Empezamos!!
Vamos a crearnos 2 clases una llamada Compass y otra rose.
En la clase compass escribiremos el siguiente código:
package msm.compass;
import android.app.Activity;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
// implement SensorListener
public class Compass extends Activity implements SensorListener {
SensorManager sensorManager;
static final int sensor = SensorManager.SENSOR_ORIENTATION;
Rose rose;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
rose = new Rose(this);
setContentView(rose);
// get sensor manager
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
// register to listen to sensors
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, sensor);
}
// unregister
@Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
// Ignore for now
public void onAccuracyChanged(int sensor, int accuracy) {
}
// Listen to sensor and provide output
public void onSensorChanged(int sensor, float[] values) {
if (sensor != Compass.sensor)
return;
int orientation = (int) values[0];
rose.setDirection(orientation);
}
}
Como podeis ver implementamos el SensorListener y el SensorManager que controlará el movimiento del teléfono para que controle donde esta el norte.
Ahora la clase rose:
package msm.compass;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.widget.ImageView;
public class Rose extends ImageView {
Paint paint;
int direction = 0;
public Rose(Context context) {
super(context);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
paint.setStyle(Style.STROKE);
this.setImageResource(R.drawable.compassrose);
}
@Override
public void onDraw(Canvas canvas) {
int height = this.getHeight();
int width = this.getWidth();
canvas.rotate(direction, width / 2, height / 2);
super.onDraw(canvas);
}
public void setDirection(int direction) {
this.direction = direction;
this.invalidate();
}
}
Esta clase únicamente controla la dirección que tendrá nuestro fondo (es una brujula) y lo irá girando a medida que desde la otra clase se le vaya pidiendo en función de la información que obtengamos del Sensor Manager.
Por último y de regalo os muestro mi main.xml por si teneis problemas al implementar la brujula.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="25dp" android:gravity="center" android:text="@string/app_name" android:textSize="35sp"/>
<TextView
android:id="@+id/textDirection"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="NW"
android:textSize="150sp" />
</LinearLayout>
Si quereis ver el ejemplo en funcionamiento aqui os dejo uno de ellos:
Las casualidades de la vida, ahora mismo estaba liado con la actividad de la brujula que nos habian mandado en el ciclo y estaba medio pillado por como comenzarla.
ResponderEliminarPor cierto, me gusta la idea que has tenido de rotar una única imagen, yo tenía planeado cargar 8 imagenes independientes para cada orientacion pero fijo que ralentiza bastante. Me quedo mejor con tu forma.
Pd: Ojalá continuases publicando en tu blog. Acabo de descubrirlo y tienes publicaciones muy interesantes.
Saludos compañero ^^