简单方法实现重力感应背景图(GravityImageView)
来源:互联网 发布:上海大学乐乎论坛 编辑:程序博客网 时间:2024/06/06 12:35
在一些比较文艺范的APP中我们常常见到背景图可以重力感应左右移动,看起来又文艺又好看,今天我们就来实现这个效果
首先在布局中放一个ImageView
<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/iv_bg" android:layout_width="wrap_content" android:layout_height="match_parent" android:scaleType="matrix" /></LinearLayout>
然后,按照我写的上一篇博客,读取assets目录中的高清图片,并将其设置到ImageView上
ivBg = (ImageView) findViewById(R.id.iv_bg); //导入assets文件夹中的文件并将其设置到背景图片控件上 try { InputStream open = getResources().getAssets().open("school.jpg"); Bitmap bitmap = BitmapFactory.decodeStream(open); ivBg.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); }
//设置图片的缩放模式和显示位置并设置 mMatrix = new Matrix(); mMatrix.postScale(1.5f, 1.5f, 0.5f, 0.5f); mMatrix.postTranslate(-540, 0); ivBg.setImageMatrix(mMatrix); ivBg.invalidate();
初始化重力感应Sensor
//获取系统传感器服务 sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //设置监听器监听加速度传感器(重力感应器)的状态,精度为普通(SENSOR_DELAY_NORMAL) sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
传感器监听
/** * 传感器监听 * * @param event */ @Override public void onSensorChanged(SensorEvent event) { //若传感器类型为加速度传感器(重力感应器) if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { //获取X坐标 int x = (int) event.values[SensorManager.DATA_X]; if (x == 0) orientation = RIGHT_1;//默认向左移动 if (x < 2 && x > 0) orientation = RIGHT_1; if (x > 2) orientation = RIGHT_2; if (x < 0 && x > -2) orientation = LEFT_1; if (x < -2) orientation = LEFT_2; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }
自定义一个动画类
/** * 自定义动画 */ public class MAnimation extends Animation { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if (orientation == LEFT_1) { mMatrix.postTranslate(interpolatedTime * 2, 0); } if (orientation == RIGHT_1) { mMatrix.postTranslate(-interpolatedTime * 2, 0); } if (orientation == LEFT_2) { mMatrix.postTranslate(interpolatedTime * 5, 0); } if (orientation == RIGHT_2) { mMatrix.postTranslate(-interpolatedTime * 5, 0); } ivBg.setImageMatrix(mMatrix); ivBg.invalidate(); } }
设置动画的各种属性
/** * 设置动画属性 * 将时间设置稍长以避免动画执行完成后重复执行的时候的停顿现象 * * @return */ private Animation getAnimation() { MAnimation animation = new MAnimation(); animation.setDuration(600000); animation.setRepeatMode(Animation.REVERSE); animation.setRepeatCount(Animation.INFINITE); return animation; }
将动画设置给ImageView
//为图片控件设置动画 ivBg.startAnimation(getAnimation());
最后,如果只写到这的话,图片移动到边界的时候还会继续移动,所以我们必须进行边界判断
/** * 获取左上坐标,用于边界条件的判断 * * @return */ private PointF getLeftPointF() { float[] values = new float[9]; float[] rightValues = {1.5f, 0, -1080f, 0, 1.5f, -0.25f, 0, 0, 1.0f}; float[] leftValues = {1.5f, 0, 0, 0, 1.5f, -0.25f, 0, 0, 1.0f}; mMatrix.getValues(values); //若超出边界,为其设置自定义的位置 if (values[2] < -1080) { mMatrix.setValues(rightValues); } if (values[2] > 0) { mMatrix.setValues(leftValues); } float leftX = values[2]; float leftY = values[5]; return new PointF(leftX, leftY); }
当然,我这个代码还是很幼稚的,适配性也很差很差,但是确实可以实现想要的效果,而且貌似也没有BUG....反正能用!
以下是完整代码
package androidstudio.myapplication;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PointF;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.animation.Animation;import android.view.animation.Transformation;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;public class MainActivity extends AppCompatActivity implements SensorEventListener { private ImageView ivBg; private Matrix mMatrix; private SensorManager sensorManager; //以速度1向左移动 private static final int LEFT_1 = 1; //以速度2向左移动 private static final int LEFT_2 = 2; //以速度1向右移动 private static final int RIGHT_1 = 3; //以速度2向右移动 private static final int RIGHT_2 = 4; private int orientation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivBg = (ImageView) findViewById(R.id.iv_bg); //导入assets文件夹中的文件并将其设置到背景图片控件上 try { InputStream open = getResources().getAssets().open("school.jpg"); Bitmap bitmap = BitmapFactory.decodeStream(open); ivBg.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } //设置图片的缩放模式和显示位置并设置 mMatrix = new Matrix(); mMatrix.postScale(1.5f, 1.5f, 0.5f, 0.5f); mMatrix.postTranslate(-540, 0); ivBg.setImageMatrix(mMatrix); ivBg.invalidate(); //为图片控件设置动画 ivBg.startAnimation(getAnimation()); //获取系统传感器服务 sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //设置监听器监听加速度传感器(重力感应器)的状态,精度为普通(SENSOR_DELAY_NORMAL) sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } /** * 设置动画属性 * 将时间设置稍长以避免动画执行完成后重复执行的时候的停顿现象 * * @return */ private Animation getAnimation() { MAnimation animation = new MAnimation(); animation.setDuration(600000); animation.setRepeatMode(Animation.REVERSE); animation.setRepeatCount(Animation.INFINITE); return animation; } /** * 自定义动画 */ public class MAnimation extends Animation { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { //运行方法,获取左上点的坐标,用于设置边界 getLeftPointF(); if (orientation == LEFT_1) { mMatrix.postTranslate(interpolatedTime * 2, 0); } if (orientation == RIGHT_1) { mMatrix.postTranslate(-interpolatedTime * 2, 0); } if (orientation == LEFT_2) { mMatrix.postTranslate(interpolatedTime * 5, 0); } if (orientation == RIGHT_2) { mMatrix.postTranslate(-interpolatedTime * 5, 0); } ivBg.setImageMatrix(mMatrix); ivBg.invalidate(); } } /** * 传感器监听 * * @param event */ @Override public void onSensorChanged(SensorEvent event) { //若传感器类型为加速度传感器(重力感应器) if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { //获取X坐标 int x = (int) event.values[SensorManager.DATA_X]; if (x == 0) orientation = RIGHT_1;//默认向左移动 if (x < 2 && x > 0) orientation = RIGHT_1; if (x > 2) orientation = RIGHT_2; if (x < 0 && x > -2) orientation = LEFT_1; if (x < -2) orientation = LEFT_2; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } /** * 获取左上坐标,用于边界条件的判断 * * @return */ private PointF getLeftPointF() { float[] values = new float[9]; float[] rightValues = {1.5f, 0, -1080f, 0, 1.5f, -0.25f, 0, 0, 1.0f}; float[] leftValues = {1.5f, 0, 0, 0, 1.5f, -0.25f, 0, 0, 1.0f}; mMatrix.getValues(values); //若超出边界,为其设置自定义的位置 if (values[2] < -1080) { mMatrix.setValues(rightValues); } if (values[2] > 0) { mMatrix.setValues(leftValues); } float leftX = values[2]; float leftY = values[5]; return new PointF(leftX, leftY); }}
1 0
- 简单方法实现重力感应背景图(GravityImageView)
- Android 手机重力感应实现简单介绍
- cocos2d-x 3.2 |重力感应实现方法
- Android 小球重力感应实现
- IOS 重力感应的实现
- Android重力感应实现方式
- Android 小球重力感应实现
- Android重力感应实现方式
- Android重力感应实现方式
- Android重力感应(转)
- mma7660(重力感应传感器)
- 重力感应G-Sensor 简单介绍
- 简单重力感应跑步测速应用
- 重力感应
- 重力感应
- 重力感应
- 重力感应
- 重力感应
- 论__大量文本内容去重的方式
- 快速排序---C语言实现
- C语言可变参函数的实现原理浅析
- 根据遍历结果构造二叉树
- Cocos2d-x常用动作 Action API
- 简单方法实现重力感应背景图(GravityImageView)
- js事件
- C语言实现循环队列
- linux开机自启动的几种方法
- 程序员技术练级攻略
- JavaScript中的prototype.bind()方法介绍
- 关于对象实例的一些新手问题
- 中文编码杂谈
- SDL起步——SDL2的配置