Showing posts with label ObjectAnimator. Show all posts
Showing posts with label ObjectAnimator. Show all posts

Tuesday, January 1, 2019

Mix using of ImageDecoder and ObjectAnimator

Last posts show how to "Display animated GIF using ImageDecoder" and "Apply PostProcess for ImageDecoder". This example I try to mix using of ImageDecoder and ObjectAnimator, to apply animation on animated GIF.



Modify MainActivity.java
package com.blogspot.android_er.androidimagedecoder;

import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageDecoder;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.PostProcessor;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.IOException;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView1 = findViewById(R.id.gifimage1);
        ImageView imageView2 = findViewById(R.id.gifimage2);

        loadGif(imageView1);
        loadRoundGif(imageView2);

        imageView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimatorRotate((ImageView)v);
            }
        });

        imageView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimatorAlpha((ImageView)v);
            }
        });
    }

    PostProcessor myPostProcessor =
            new PostProcessor(){
                @Override
                public int onPostProcess(
                        Canvas canvas) {
                    // This will create rounded corners.
                    Path path = new Path();
                    path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
                    int width = canvas.getWidth();
                    int height = canvas.getHeight();
                    path.addRoundRect(0, 0,
                            width, height, 150, 150,
                            Path.Direction.CW);
                    Paint paint = new Paint();
                    paint.setAntiAlias(true);
                    paint.setColor(Color.TRANSPARENT);
                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
                    canvas.drawPath(path, paint);
                    return PixelFormat.TRANSLUCENT;
                }
            };


    ImageDecoder.OnHeaderDecodedListener myOnHeaderDecodedListener =
            new ImageDecoder.OnHeaderDecodedListener(){
                @Override
                public void onHeaderDecoded
                        (ImageDecoder decoder,
                         ImageDecoder.ImageInfo info,
                         ImageDecoder.Source source) {
                    decoder.setPostProcessor(myPostProcessor);
                }
            };

    private void loadGif(ImageView iv){

        try {
            ImageDecoder.Source source =
                    ImageDecoder.createSource(getResources(), R.drawable.android_er);

            Drawable drawable = ImageDecoder.decodeDrawable(source);

            iv.setImageDrawable(drawable);

            if (drawable instanceof AnimatedImageDrawable) {
                ((AnimatedImageDrawable) drawable).start();
                Toast.makeText(getApplicationContext(),
                        "loadGif: Animation started",
                        Toast.LENGTH_LONG).show();
            }

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "loadGif: IOException: \n" + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

    }

    private void loadRoundGif(ImageView iv){

        try {
            ImageDecoder.Source source =
                    ImageDecoder.createSource(getResources(), R.drawable.android_er);

            //Drawable drawable = ImageDecoder.decodeDrawable(source);
            Drawable drawable = ImageDecoder.decodeDrawable(source,
                    myOnHeaderDecodedListener);

            iv.setImageDrawable(drawable);

            if (drawable instanceof AnimatedImageDrawable) {
                ((AnimatedImageDrawable) drawable).start();
                Toast.makeText(getApplicationContext(),
                        "loadRoundGif: Animation started",
                        Toast.LENGTH_LONG).show();
            }

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),
                    "loadRoundGif: IOException: \n" + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

    }

    private void prepareObjectAnimatorRotate(ImageView image){
        TimeInterpolator timeInterpolator =
                new AccelerateDecelerateInterpolator();
        float propertyStart = 0f;
        float propertyEnd = 360f;
        String propertyName = "rotation";
        ObjectAnimator objectAnimator
                = ObjectAnimator.ofFloat(
                        image, propertyName, propertyStart, propertyEnd);
        objectAnimator.setDuration(5000);
        objectAnimator.setRepeatCount(1);
        objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        objectAnimator.setInterpolator(timeInterpolator);
        objectAnimator.start();
    }

    private void prepareObjectAnimatorAlpha(ImageView image){
        TimeInterpolator timeInterpolator =
                new AccelerateDecelerateInterpolator();
        float propertyStart = 1f;
        float propertyEnd = 0f;
        String propertyName = "alpha";
        ObjectAnimator objectAnimator
                = ObjectAnimator.ofFloat(
                        image, propertyName, propertyStart, propertyEnd);
        objectAnimator.setDuration(5000);
        objectAnimator.setRepeatCount(1);
        objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        objectAnimator.setInterpolator(timeInterpolator);
        objectAnimator.start();
    }
}


Keep using the layout in last post "Apply PostProcess for ImageDecoder".

If you target to animated GIF and it cannot shown, try to disable hardwareAccelerated, refer to "Display animated GIF using ImageDecoder".


Related old post:
Interpolator effect on ObjectAnimator


Monday, October 19, 2015

Simulate 3D Hologram effect


Last post show a DIY 3D Hologram Projector for smartphone to view 3D Hologram Video in YouTube. Here I try to simulate the effect in Android App.






MainActivity.java
package com.blogspot.android_er.androidmirror;

import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    ImageView image2, image4, image6, image8;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image2 = (ImageView)findViewById(R.id.image2);
        image4 = (ImageView)findViewById(R.id.image4);
        image6 = (ImageView)findViewById(R.id.image6);
        image8 = (ImageView)findViewById(R.id.image8);

        image2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                flipX();
            }
        });

        image4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                flipY();
            }
        });

        image6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                flipY();
            }
        });

        image8.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                flipX();
            }
        });
    }

    private void flipX(){
        ObjectAnimator flip2 = ObjectAnimator.ofFloat(image2, "rotationX", 0f, 360f);
        ObjectAnimator flip4 = ObjectAnimator.ofFloat(image6, "rotationY", 0f, 360f);
        ObjectAnimator flip6 = ObjectAnimator.ofFloat(image4, "rotationY", 0f, -360f);
        ObjectAnimator flip8 = ObjectAnimator.ofFloat(image8, "rotationX", 0f, -360f);
        flip2.setDuration(3000);
        flip4.setDuration(3000);
        flip6.setDuration(3000);
        flip8.setDuration(3000);
        flip2.start();
        flip4.start();
        flip6.start();
        flip8.start();
    }


    private void flipY(){
        ObjectAnimator flip2 = ObjectAnimator.ofFloat(image2, "rotationY", 0f, 360f);
        ObjectAnimator flip4 = ObjectAnimator.ofFloat(image6, "rotationX", 0f, 360f);
        ObjectAnimator flip6 = ObjectAnimator.ofFloat(image4, "rotationX", 0f, -360f);
        ObjectAnimator flip8 = ObjectAnimator.ofFloat(image8, "rotationY", 0f, -360f);
        flip2.setDuration(3000);
        flip4.setDuration(3000);
        flip6.setDuration(3000);
        flip8.setDuration(3000);
        flip2.start();
        flip4.start();
        flip6.start();
        flip8.start();
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:background="@android:color/black"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold"
        android:layout_alignParentTop="true"/>

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:columnCount="3"
        android:layout_centerInParent="true">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/image2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/androider"
            android:layout_gravity="center"/>
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/image4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/androider"
            android:layout_gravity="center"
            android:rotation="270"/>
        <ImageView
            android:layout_width="20mm"
            android:layout_height="20mm"/>
        <ImageView
            android:id="@+id/image6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/androider"
            android:layout_gravity="center"
            android:rotation="90"/>
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/image8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/androider"
            android:layout_gravity="center"
            android:rotation="180"/>
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </GridLayout>
</RelativeLayout>


Where "@drawable/androider" is a 100x100 PNG with alpha channel.

Next:
Animated GIF (Androidify) for 3D Hologram viewer

Interpolator effect on ObjectAnimator


This post demo various Interpolator effect on ObjectAnimator. You can also download the demo APK, from the link on the bottom.


MainActivity.java
package com.blogspot.android_er.androidobjectanimator;

import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.os.Bundle;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    LinearLayout playGround;
    ImageView image;

    AccelerateDecelerateInterpolator accelerateDecelerateInterpolator;
    AccelerateInterpolator accelerateInterpolator;
    AnticipateInterpolator anticipateInterpolator;
    AnticipateOvershootInterpolator anticipateOvershootInterpolator;
    BounceInterpolator bounceInterpolator;
    CycleInterpolator cycleInterpolator;
    DecelerateInterpolator decelerateInterpolator;
    FastOutLinearInInterpolator fastOutLinearInInterpolator;
    FastOutSlowInInterpolator fastOutSlowInInterpolator;
    LinearInterpolator linearInterpolator;
    LinearOutSlowInInterpolator linearOutSlowInInterpolator;
    OvershootInterpolator overshootInterpolator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        playGround = (LinearLayout)findViewById(R.id.playground);
        image = (ImageView)findViewById(R.id.image);
        image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Clicked!", Toast.LENGTH_SHORT).show();
            }
        });

        Button btnNull = (Button)findViewById(R.id.bNull);
        btnNull.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(null);
            }
        });

        Button btnAccelerateDecelerateInterpolator
                = (Button)findViewById(R.id.bAccelerateDecelerateInterpolator);
        btnAccelerateDecelerateInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(accelerateDecelerateInterpolator);
            }
        });

        Button btnAccelerateInterpolator = (Button)findViewById(R.id.bAccelerateInterpolator);
        btnAccelerateInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(accelerateInterpolator);
            }
        });

        Button btnAnticipateInterpolator = (Button)findViewById(R.id.bAnticipateInterpolator);
        btnAnticipateInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(anticipateInterpolator);
            }
        });

        Button btnAnticipateOvershootInterpolator
                = (Button)findViewById(R.id.bAnticipateOvershootInterpolator);
        btnAnticipateOvershootInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(anticipateOvershootInterpolator);
            }
        });

        Button btnBounceInterpolator = (Button)findViewById(R.id.bBounceInterpolator);
        btnBounceInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(bounceInterpolator);
            }
        });

        Button btnCycleInterpolator = (Button)findViewById(R.id.bCycleInterpolator);
        btnCycleInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(cycleInterpolator);
            }
        });

        Button btnDecelerateInterpolator = (Button)findViewById(R.id.bDecelerateInterpolator);
        btnDecelerateInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(decelerateInterpolator);
            }
        });

        Button btnFastOutLinearInInterpolator
                = (Button)findViewById(R.id.bFastOutLinearInInterpolator);
        btnFastOutLinearInInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(fastOutLinearInInterpolator);
            }
        });

        Button btnFastOutSlowInInterpolator
                = (Button)findViewById(R.id.bFastOutSlowInInterpolator);
        btnFastOutSlowInInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(fastOutSlowInInterpolator);
            }
        });

        Button btnLinearInterpolator = (Button)findViewById(R.id.bLinearInterpolator);
        btnLinearInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(linearInterpolator);
            }
        });

        Button btnOvershootInterpolator = (Button)findViewById(R.id.bOvershootInterpolator);
        btnOvershootInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(overshootInterpolator);
            }
        });

        Button btnLinearOutSlowInInterpolator
                = (Button)findViewById(R.id.bLinearOutSlowInInterpolator);
        btnLinearOutSlowInInterpolator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                prepareObjectAnimator(linearOutSlowInInterpolator);
            }
        });

        prepareInterpolator();
    }

    private void prepareInterpolator(){
        accelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
        accelerateInterpolator = new AccelerateInterpolator();
        anticipateInterpolator = new AnticipateInterpolator();
        anticipateOvershootInterpolator = new AnticipateOvershootInterpolator();
        bounceInterpolator = new BounceInterpolator();
        cycleInterpolator = new CycleInterpolator(2);
        decelerateInterpolator = new DecelerateInterpolator();
        fastOutLinearInInterpolator = new FastOutLinearInInterpolator();
        fastOutSlowInInterpolator = new FastOutSlowInInterpolator();
        linearInterpolator = new LinearInterpolator();
        linearOutSlowInInterpolator = new LinearOutSlowInInterpolator();
        overshootInterpolator = new OvershootInterpolator();
    }

    private void prepareObjectAnimator(TimeInterpolator timeInterpolator){
        //float w = (float)playGround.getWidth();
        float h = (float)playGround.getHeight();
        float propertyStart = 0f;
        float propertyEnd = -(h/2 - (float)image.getHeight()/2);
        String propertyName = "translationY";
        ObjectAnimator objectAnimator
                = ObjectAnimator.ofFloat(image, propertyName, propertyStart, propertyEnd);
        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(1);
        objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        objectAnimator.setInterpolator(timeInterpolator);
        objectAnimator.start();
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="16dp"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:autoLink="web"
            android:text="http://android-er.blogspot.com/"
            android:textStyle="bold" />

        <LinearLayout
            android:id="@+id/playground"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:background="#E0E0E0"
            android:gravity="center"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="@mipmap/ic_launcher" />
        </LinearLayout>
    </LinearLayout>

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:id="@+id/bNull"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Interpolator = null (LinearInterpolator)"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bAccelerateDecelerateInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="AccelerateDecelerateInterpolator (default)"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bAccelerateInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="AccelerateInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bAnticipateInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="AnticipateInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bAnticipateOvershootInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="AnticipateOvershootInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bBounceInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="BounceInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bCycleInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="CycleInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bDecelerateInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="DecelerateInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bFastOutLinearInInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="FastOutLinearInInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bFastOutSlowInInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="FastOutSlowInInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bLinearInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="LinearInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bLinearOutSlowInInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="LinearOutSlowInInterpolator"
                android:textAllCaps="false" />

            <Button
                android:id="@+id/bOvershootInterpolator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="OvershootInterpolator"
                android:textAllCaps="false" />

        </LinearLayout>

    </ScrollView>

</LinearLayout>



download filesDownload the files (Android Studio Format) .

download filesDownload the demo APK.


~ Old example of Various effect of interpolator in Android Animation