我是android开发的新手。我写了这段代码,在屏幕上绘制一个圆圈,通过移动设备,圆圈将在屏幕上移动。但是我的Nexus 7设备速度非常慢。你能帮助我提高表现吗?
public class MainActivity extends Activity implements SensorEventListener {
public static SensorManager mSensorManager;
public static Sensor accelerometer;
public static Sensor magnetometer;
public static float[] mAccelerometer = null;
public static float[] mGeomagnetic = null;
private SampleCircle sampleCircle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.mainForm);
sampleCircle = new SampleCircle(this);
layout.addView(sampleCircle);
layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
sampleCircle.setPoint(motionEvent.getX(), motionEvent.getY());
return false;
}
});
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this, accelerometer);
mSensorManager.unregisterListener(this, magnetometer);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mAccelerometer = event.values;
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic = event.values;
}
if (mAccelerometer != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mAccelerometer, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
// at this point, orientation contains the azimuth(direction), pitch and roll values.
double azimuth = 180 * orientation[0] / Math.PI;
double pitch = 180 * orientation[1] / Math.PI;
double roll = 180 * orientation[2] / Math.PI;
sampleCircle.move((float) Math.floor(pitch), (float) Math.floor(roll));
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
System.out.println("Acc");
}
private class SampleCircle extends View {
private Paint p = new Paint();
{
p.setColor(Color.RED);
p.setStyle(Paint.Style.FILL);
}
private float y;
private float x;
public SampleCircle(Context context, float x, float y) {
super(context);
this.y = y;
this.x = x;
}
public SampleCircle(Context context) {
super(context);
}
public void setPoint(float x, float y) {
this.x = x;
this.y = y;
}
public void move(float x, float y) {
this.x -= x;
this.y -= y;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, 50, p);
invalidate();
}
}
}
答案 0 :(得分:2)
不要调用invalidate();在onDraw方法中,只有在想要在新位置绘制圆时才调用它:在setPoint()和move()方法中
答案 1 :(得分:2)
调用View.invalidate()
会通过调用View.onDraw(Canvas)
告诉操作系统重绘视图,因此调用invalidate()
中的onDraw(...)
表示设备将永久忙于重新绘制视图。因此,正如@pskink所建议的那样,View.invalidate()
应该从SampleCircle.setPoint(...)
和SampleCircle.move(...)
方法调用。但是,为了获得最大效率,您需要添加一个容差,这样如果移动很小,就不会重新绘制。
答案 2 :(得分:0)
应在onSensorChanged(SensorEvent事件)中调用invalidate();并且只有在发生明显变化时。这肯定会提高性能