这两天公司项目需要效果是实现水平仪效果,从网上查了查,也找了一些储备,虽然达到了要求,但是有点不足,和我需求不符合,就是当小球转到边缘的时候,小球会在边缘不动,于是就改了改,完美达到了我的要求,不管你手机怎么转,小球始终在大圆里面,超过边缘的时候,也是在边缘滚动哦,特在此记录,有需要的可供参考,废话不多说,下面直接上代码了:
还是要声明下,这是本人第一篇博客,写的不好,勿怪
呃,自己要提前准备两张图片哦,一张是小球的,一张是小球的背景画布
实现的效果如下
1、首先定义传感器变量
private Sensor gyroSensor = null;
2、在onCreat里面初始化传感器
//初始化方向传感器
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
3、在onResume里面注册传感器
@Override
protected void onResume() {
super.onResume();
if (null != sensorManager || null != gyroSensor) {
sensorManager.registerListener(this, gyroSensor, SensorManager.SENSOR_DELAY_GAME); //为传感器注册监听器
}
}
4、onPause里面要暂停传感器
@Override
protected void onPause() {
// 取消方向传感器的监听
if (null != sensorManager) {
sensorManager.unregisterListener(this);
}
super.onPause();
}
5、编写PlaneView,这个就是水平仪的控件,这个是从网上摘抄的,不懂可以直接搜android 水平仪实现,一定有的
public class PlaneView extends View {
// 定义水平仪仪表盘图片
public Bitmap back;
// 定义水平仪中的气泡图标
public Bitmap bubble;
// 定义水平仪中气泡 的X、Y座标
public float bubbleX, bubbleY;
public PlaneView(Context context, AttributeSet attrs) {
super(context, attrs);
// 加载水平仪图片和气泡图片
back = BitmapFactory.decodeResource(getResources(), R.mipmap.plane);
bubble = BitmapFactory.decodeResource(getResources(), R.mipmap.bubble);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制水平仪表盘图片
canvas.drawBitmap(back, 0, 0, null);
// 根据气泡座标绘制气泡
canvas.drawBitmap(bubble, bubbleX, bubbleY, null);
}
}
6、下面就是将控件放到你的Activity布局中去,我的是MainActivity,布局android_main.xml
<!-宽高在这里设定,具体根据你个人项目需求->
<RelativeLayout
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="25dp">
<cn.leadpcom.com.underparking.common.PlaneView
android:id="@+id/pv_bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
7、下面就是具体在传感器接收到数据之后的操作了,里面的pv_bubble是我的控件名,大家应该懂得,转换成你个人设定的就行,呃,实在不懂,我也没有办法啊,就是这里面的逻辑和网上不同,希望大家注意哦,大家是不是在想MAX_ANGLE在哪里,是什么,哈哈,这个是定义的变量,就是角度,越小,小球就越灵敏
private int MAX_ANGLE = 10;//具体多大,自己尝试下就行了
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 获取触发event的传感器类型就
int sensorType = event.sensor.getType();
switch (sensorType) {
case Sensor.TYPE_ORIENTATION:
// 获取与Y轴的夹角
float yAngle = values[1];
// 获取与Z轴的夹角
float zAngle = values[2];
// 气泡位于中间时(水平仪完全水平),气泡的X、Y座标
int x = (pv_bubble.back.getWidth() - pv_bubble.bubble.getWidth()) / 2;
int y = (pv_bubble.back.getHeight() - pv_bubble.bubble.getHeight()) / 2;
// 根据与Z轴的倾斜角度计算X座标的变化值(倾斜角度越大,X座标变化越大)
int deltaX = (int) ((pv_bubble.back.getWidth() - pv_bubble.bubble.getWidth()) / 2 * zAngle / MAX_ANGLE);
x += deltaX;
// 根据与Y轴的倾斜角度计算Y座标的变化值(倾斜角度越大,Y座标变化越大)
int deltaY = (int) ((pv_bubble.back.getHeight() - pv_bubble.bubble.getHeight()) / 2 * yAngle / MAX_ANGLE);
y += deltaY;
// 如果计算出来的X、Y座标还位于水平仪的仪表盘内,更新水平仪的气泡座标
float aa = (float) Math.sqrt((x - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) * (x - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) + (y - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) * (y - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)));
if (aa < pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) {
pv_bubble.bubbleX = x;
pv_bubble.bubbleY = y;
} else {
float newx = (float) ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) * (x - (pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)))) / aa + ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)));
float newy = (float) ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) * (y - (pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)))) / aa + ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)));
pv_bubble.bubbleX = newx;
pv_bubble.bubbleY = newy;
}
// 通知系统重回MyView组件
pv_bubble.postInvalidate();
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
8、好了,只要按照上面的说的,应该就能完美实现了,小球一直在画布里面的哦!~!~!~!~!有需要的,参考下,大神还请给出点评,我会继续更新改正,上面部分是摘抄,别的部分是原创,如有雷同,纯属巧合!~!~!~!~!~!