ZOFTINO.COM android and web dev tutorials

Android AdapterViewFlipper Example

Android AdapterViewFlipper is similar to ViewFlipper but it allows you to set adapter so that each item provided by adapter becomes child view of AdapterViewFlipper. AdapterViewFlipper is useful to flip through list of items.

You can configure AdapterViewFlipper to automatically flip each item from the adapter by setting autoStart to true and specifying flip interval. Or you can make AdapterViewFlipper to flip to next or previous items in the adapter in response to a user event by calling showNext or showPrevious methods on AdapterViewFlipper object.

I’ll show how to use AdapterViewFlipper with an example by creating an adapter and components to fetch data items from the database using Room, you can read android room tutorial for more information on Room.

AdapterViewFlipper Example

Below example first fetches data from data base using Room and LiveData. Live data is used so that data fetching runs on the background thread. After list of items are available from data base, it then creates custom adapter and passes the list to the adapter which takes the list and populates each item in the item layout.

The custom adapter instance is added to AdapterViewFlipper which treats each item it gets from adapter as child view. With auto start and flip interval settings, AdapterViewFlipper switches to each item from the list. You can configure AdapterViewFlipper to switch to next or previous views by detecting touch gestures, for more information you can read ViewFlipper example.

To show animation while switching views, animators have been added to AdapterViewFlipper. Since AdapterViewFlipper takes object animator, custom object animators for in and out animation have been defined in xml and added to res/animator folder. Object animators defined in xmls can be loaded using AnimatorInflater.

AdapterViewFlipper with Data from Room Example Dependency

Since we are going to use Room and LiveData in our AdapterViewFlipper example, below libraries need to be added to project.

 dependencies {
    . . . 
implementation 'android.arch.persistence.room:runtime:1.0.0-beta2'
implementation 'android.arch.lifecycle:extensions:1.0.0-beta2'
implementation 'android.arch.lifecycle:runtime:1.0.0-beta2'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0-beta2'
 } 

AdapterViewFlipper Adapter

Adapater getView method inflates item layout and populates layout with item data.

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;

public class AlbumsAdapter extends ArrayAdapter {

    private List<Album> albumList;
    private Context context;
    private int itemLayout;

    public AlbumsAdapter(List<Album> albumListIn,int resource, Context ctx) {
        super(ctx, resource, albumListIn);
        albumList = albumListIn;
        context = ctx;
        itemLayout = resource;
    }

    @Override
    public int getCount() {
        return albumList.size();
    }
    @Override
    public Album getItem(int position) {
        return albumList.get(position);
    }
    @Override
    public long getItemId(int position) {
        return albumList.get(position).getId();
    }
        @Override
    public View getView(int position, View view, @NonNull ViewGroup parent) {

        if (view == null) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(itemLayout, parent, false);
        }

        Album album = albumList.get(position);

        TextView name = (TextView) view.findViewById(R.id.name);
        TextView singer = (TextView) view.findViewById(R.id.singer);
        TextView views = (TextView) view.findViewById(R.id.views);
        TextView downloads = (TextView) view.findViewById(R.id.downloads);

        name.setText(album.getName());
        singer.setText(album.getSinger());
        views.setText(""+album.getViews());
        downloads.setText(""+album.getDownloads());

        return view;
    }
}

AdapterViewFlipper Adapter Item Layout

Our example adapter item layout contains text views to show labels and item data.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/singer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="16dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.7"
        app:layout_constraintStart_toEndOf="@+id/name"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/views_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="Views :"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/name" />

    <TextView
        android:id="@+id/views"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/views_label"
        app:layout_constraintTop_toBottomOf="@+id/singer" />

    <TextView
        android:id="@+id/downloads_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:text="Downloads :"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/views_label" />

    <TextView
        android:id="@+id/downloads"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/downloads_label"
        app:layout_constraintTop_toBottomOf="@+id/views" />
</android.support.constraint.ConstraintLayout>

AdapterViewFlipper Example Activity

import android.animation.AnimatorInflater;
import android.animation.ObjectAnimator;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterViewFlipper;
import android.widget.Toast;

import java.util.List;

public class AdapterViewFlipperActivity extends AppCompatActivity {

    private DbRepository dbRepository = new DbRepository();
    private AdapterViewFlipper avf;

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

        avf = findViewById(R.id.adapterViewFlipper);
        avf.setAutoStart(true);
        avf.setFlipInterval(5000);

        ObjectAnimator animationIn = (ObjectAnimator) AnimatorInflater.
                loadAnimator(this, R.animator.obj_in_anim);
        animationIn.setDuration(700);
        avf.setInAnimation(animationIn);

        ObjectAnimator animationOut = (ObjectAnimator)AnimatorInflater.
                loadAnimator(this, R.animator.obj_out_anim);
        animationOut.setDuration(700);
        avf.setOutAnimation(animationOut);

        LiveData<List<Album>> albums = dbRepository.getAlbums(this);
        albums.observe(this, new Observer<List<Album>>() {
            @Override
            public void onChanged(@Nullable List<Album> albumList) {
                if(albumList == null){
                    return;
                }
                AlbumsAdapter albumsAdapter =
                        new AlbumsAdapter(albumList,R.layout.album_item_layout,
                                AdapterViewFlipperActivity.this);

                avf.setAdapter(albumsAdapter);
            }
        });
    }
}

AdapterViewFlipper Example Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
<AdapterViewFlipper
    android:id="@+id/adapterViewFlipper"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"></AdapterViewFlipper>
</android.support.constraint.ConstraintLayout>

AdapterViewFlipper Example Room Model

 import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;

@Entity
public class Album {
    @PrimaryKey(autoGenerate = true)
    private int id;

    private String name;
    private String singer;
    private int views;
    private int downloads;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSinger() {
        return singer;
    }

    public void setSinger(String singer) {
        this.singer = singer;
    }

    public int getViews() {
        return views;
    }

    public void setViews(int views) {
        this.views = views;
    }

    public int getDownloads() {
        return downloads;
    }

    public void setDownloads(int downloads) {
        this.downloads = downloads;
    }
} 

AdapterViewFlipper Example Room DAO

 import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Query;

import java.util.List;

@Dao
public interface AlbumDAO {
    @Query("SELECT * FROM Album")
    LiveData<List<Album>> getAlbums();
} 

AdapterViewFlipper Example Room Database

 import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;

@Database(entities = {Album.class}, version = 1)
public abstract class SongsDatabase  extends RoomDatabase {
public abstract AlbumDAO albumDAO();
}

AdapterViewFlipper Example Repository

 import android.arch.lifecycle.LiveData;
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.ContentValues;
import android.content.Context;

import java.util.List;

public class DbRepository {
        private static SongsDatabase songsDatabase;
        private AlbumDAO albumDAO;
        private static final Object LOCK = new Object();

        private static RoomDatabase.Callback dbCallback = new RoomDatabase.Callback(){
            public void onCreate (SupportSQLiteDatabase db){

            }
            public void onOpen (SupportSQLiteDatabase db){
                db.execSQL("Delete From Album");

                DbRepository.addData(db);
            }
        };

        public synchronized static SongsDatabase getSongsDatabase(Context context){
            if(songsDatabase == null) {
                synchronized (LOCK) {
                    if (songsDatabase == null) {
                        songsDatabase = Room.databaseBuilder(context,
                                SongsDatabase.class, "Songs db")
                                .addCallback(dbCallback).build();
                    }
                }
            }
            return songsDatabase;
        }

        public LiveData<List<Album>> getAlbums(Context context) {
            if (albumDAO == null) {
                albumDAO = DbRepository.getSongsDatabase(context).albumDAO();
            }
            return albumDAO.getAlbums();
        }

        public static void addData(SupportSQLiteDatabase db){
            ContentValues contentValues = new ContentValues();
            contentValues.put("name", "Success");
            contentValues.put("singer", "Robgindoze");
            contentValues.put("views", 30);
            contentValues.put("downloads", 50);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Dream");
            contentValues.put("singer", "Bondigo");
            contentValues.put("views", 20);
            contentValues.put("downloads", 350);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Life");
            contentValues.put("singer", "Kartizes");
            contentValues.put("views", 230);
            contentValues.put("downloads", 450);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Love");
            contentValues.put("singer", "Daoki");
            contentValues.put("views", 30);
            contentValues.put("downloads", 50);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Baseless");
            contentValues.put("singer", "Ugigno");
            contentValues.put("views", 330);
            contentValues.put("downloads", 560);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Allege");
            contentValues.put("singer", "Tykisto");
            contentValues.put("views", 130);
            contentValues.put("downloads", 540);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

            contentValues = new ContentValues();
            contentValues.put("name", "Law");
            contentValues.put("singer", "Falkinert");
            contentValues.put("views", 308);
            contentValues.put("downloads", 509);
            db.insert("Album", OnConflictStrategy.IGNORE, contentValues);

        }
}