android 实现仿IOS桌面背景动效果

注:https://stackoverflow.com/questions/56141981/how-to-implement-background-motion-effect-parallax-effect

gifhome_616x1280_2s.gif

如图,苹果手机桌面背景动图。
自定义ImageView,实现SensorEventListener,在onSensorChanged方法中通过 SensorManager做处理。动态改变x、y值。上代码~

============================================================
public class ParallaxImageView extends AppCompatImageView implements SensorEventListener {
float[] rotMat = new float[16];
float[] vals = new float[3];

private SensorManager senSensorManager;
private Sensor senAccelerometer;
private int sideVerticalMargin, sideHorizontalMargin;
private float verticalMultiplier=1, horizontalMultiplier=1;

public ParallaxImageView(Context context, AttributeSet attrs) {
    super(context, attrs);

    senSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
    senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
    senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_FASTEST);

}

public ParallaxImageView(Context context) {
    super(context);
}

public void setMargins(int VM, int HM){
    this.sideVerticalMargin = -VM;
    this.sideHorizontalMargin = -HM;
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)this.getLayoutParams();
    params.setMargins(-HM, -VM, -HM, -VM);
    this.setLayoutParams(params);
}

public void setMultipliers(float Vertical, float Horizontal){
    this.verticalMultiplier = Vertical;
    this.horizontalMultiplier = Horizontal;
}

@Override
public void onSensorChanged(SensorEvent event) {
    Sensor mySensor = event.sensor;

    if (mySensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {

        // Convert the rotation-vector to a 4x4 matrix.
        try {
            SensorManager.getRotationMatrixFromVector(rotMat, event.values);
        } catch (IllegalArgumentException e) {
            if (event.values.length > 3) {
                // Note 3 bug
                float[] newVector = new float[] {
                        event.values[0],
                        event.values[1],
                        event.values[2]
                };
                SensorManager.getRotationMatrixFromVector(rotMat, newVector);
            }
        }
        SensorManager.remapCoordinateSystem(rotMat,
                SensorManager.AXIS_Y, SensorManager.AXIS_X,
                rotMat);

        SensorManager.getOrientation(rotMat, vals);

        vals[0] = (float) Math.toDegrees(vals[0]);
        vals[1] = (float) Math.toDegrees(vals[1]);
        vals[2] = (float) Math.toDegrees(vals[2]);

        int leftfloat = (int) (this.sideHorizontalMargin-(vals[1]*this.horizontalMultiplier));

        int topfloat;

        if(vals[2]>0){
            topfloat=(int) (this.sideVerticalMargin+(vals[2]*this.verticalMultiplier));
        }else{
            topfloat=(int) (this.sideVerticalMargin-(vals[2]*this.verticalMultiplier));
        }

        this.setX(leftfloat);
        this.setY(topfloat);
    }

}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub

}

/**
 * 在生命周期调用onPause时调用
 */
public void onPause() {
    senSensorManager.unregisterListener(this);
}
/**
 * 在生命周期调用onResume时调用
 */
public void onResume() {
    senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
}

}


============================================================
ParallaxImageView ivBackground = findViewById(R.id.iv_background);
ivBackground.setMargins(300, 200);
ivBackground.setMultipliers(1.6f, 1.8f);//动的幅度
============================================================
我是放在LinearLayout中,如果是在RelativeLayout 中需要将LinearLayout.LayoutParams改为RelativeLayout .LayoutParams。

另外还有一个库可以使用
https://github.com/gjiazhe/PanoramaImageView

以后如果做这个需求可以借鉴参考了。

你可能感兴趣的:(android 实现仿IOS桌面背景动效果)