Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Background Motion Effect (Parallax Effect)

Tags:

android

On most devices, it is possible to enable Motion Effect for Wallpapers, so my question is that is it possible to set this effect on an ImageView or not? And if yes, how can I do it?

Motion Effect: On a Smartphone, it simply is an effect that moves in accord to the motion that is being done on your phone. If you tilt the phone right, you’ll notice that the wallpaper will have an effect that makes it look like it’s tilting right as well.

MotionGif

like image 606
Alireza Noorali Avatar asked Sep 12 '25 12:09

Alireza Noorali


2 Answers

According to the Parallax ImageView Android library create a custom ImageView:

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

public class ParallaxImageView extends AppCompatImageView implements SensorEventListener {
    float[] rotMat = new float[16];
    float[] vals = new float[3];
    //sensor parallax effect
    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;
        RelativeLayout.LayoutParams params = (RelativeLayout.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

    }

    public void onPause() {
        senSensorManager.unregisterListener(this);
    }
    public void onResume() {
        senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
    }
}

Use it as below:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="0dip"
    tools:context="com.example.sensortest.MainActivity" >

    <ir.tcharter.testapp.ParallaxImageView
        android:id="@+id/iv_background"
        android:src="@drawable/background"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:scaleType="centerCrop"
        android:adjustViewBounds="true"/>

</RelativeLayout>

And in the Activity:

ParallaxImageView ivBackground = findViewById(R.id.iv_background);
ivBackground.setMargins(300, 200);
ivBackground.setMultipliers(1.5f, 1.7f);

Don't forget to add an image to drawable. here background.png is added.

like image 86
Alireza Noorali Avatar answered Sep 15 '25 02:09

Alireza Noorali


You can do this by using below the given library.

Add This Library into your gradle file.

implementation 'com.gjiazhe:PanoramaImageView:1.0'

By using below PanoramaImageView instead of ImageView you'll get your solution.

<com.gjiazhe.panoramaimageview.PanoramaImageView
     android:id="@+id/panorama_image_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:src="@drawable/img"
     app:piv_enablePanoramaMode="true"
     app:piv_show_scrollbar="true"
     app:piv_invertScrollDirection="false" />

For more understanding visit my site.

For Example :

enter image description here enter image description here

like image 45
Prince Dholakiya Avatar answered Sep 15 '25 02:09

Prince Dholakiya