Animated GIF (Androidify) for 3D Hologram viewer


Last post I tried to generate interactive animation using ObjectAnimator, to simulate 3D Hologram effect. This post I create Custom View to display animated GIF of Androidify, to simulate the effect.


The animated GIFs of Androidify are create using Google's Androidify App.  Then I have to edit the animated GIFs to resize it to 200x200, and change the background to black using GIMP. Then copy the files to drawable folder in Android Studio project.

Create a custom view, GifView, to handle the animated GIF. If you are looking for display animated GIF, refer "Play animated GIF using android.graphics.Movie, with Movie.decodeStream(InputStream)". In this version, I have to handle src attribute from xml, such that I can display four GifView of different source.

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

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;

import java.io.InputStream;

public class GifView extends View {

private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;

public GifView(Context context) {
super(context);
init(context, null);
}

public GifView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}

public GifView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}

private void init(Context context, AttributeSet attrs){
setFocusable(true);

//Handle src attribute from xml
if(attrs == null){
gifInputStream = context.getResources().openRawResource(R.drawable.androidify1b);
}else{
int src_id = attrs.getAttributeResourceValue(
"http://schemas.android.com/apk/res/android",
"src",
R.drawable.androidify1b);
gifInputStream = context.getResources().openRawResource(src_id);
}

gifMovie = Movie.decodeStream(gifInputStream);
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
}

@Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}

public int getMovieWidth(){
return movieWidth;
}

public int getMovieHeight(){
return movieHeight;
}

public long getMovieDuration(){
return movieDuration;
}

@Override
protected void onDraw(Canvas canvas) {

long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}

if (gifMovie != null) {

int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}

int relTime = (int)((now - mMovieStart) % dur);

gifMovie.setTime(relTime);

gifMovie.draw(canvas, 0, 0);
invalidate();

}

}
}


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"/>
<com.blogspot.android_er.androidmirror.GifView
android:id="@+id/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/androidify1b"
android:layout_gravity="center"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.blogspot.android_er.androidmirror.GifView
android:id="@+id/image4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/androidify2b"
android:layout_gravity="center"
android:rotation="270"/>
<ImageView
android:layout_width="20mm"
android:layout_height="20mm"/>
<com.blogspot.android_er.androidmirror.GifView
android:id="@+id/image6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/androidify3b"
android:layout_gravity="center"
android:rotation="90"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.blogspot.android_er.androidmirror.GifView
android:id="@+id/image8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/androidify4b"
android:layout_gravity="center"
android:rotation="180"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</GridLayout>
</RelativeLayout>


Edit AndroidManifest.xml to disable hardwareAccelerated by setting it false.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blogspot.android_er.androidmirror" >

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity"
android:hardwareAccelerated="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


Nothing do on MainActivity.java
package com.blogspot.android_er.androidmirror;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

}



download filesDownload the files (Android Studio Format) .

download filesDownload APK .


If you have a DIY 3D Hologram Projector, you can view the test view at YouTube.