logo

ViewFlinger this an android widget (extends ViewGroup) that allows to group a set of views that can be swiped horizontally. It offers a smoother transition that cannot be accomplished using ViewFlipper. This is based on the Workspace class on the iosched project, which is based in the class with the same name of the Launcher app.

You can see in the video, how ViewFlinger actually works:

1) You can download requisite package here

2) Unpack zip file and copy the above downloaded package com.egoclean.android.widget.flinger into your project i.e in src directory.

Directory structure is given below:

In main.xml , define custom view ViewFlinger

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    
	 <com.egoclean.android.widget.flinger.ViewFlinger 
	 	android:layout_height="fill_parent" 
    	android:layout_width="fill_parent" 
    	android:id="@+id/viewFlipper1">
     </com.egoclean.android.widget.flinger.ViewFlinger> 	
</LinearLayout>

Adding Limited number of views

Create view.xml in layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical">
  		<ImageView android:id="@+id/image"
    		android:layout_height="wrap_content"
    		android:layout_width="wrap_content"
    		android:background="@drawable/icon"/>
    	<TextView android:id="@+id/text"
    	   android:layout_width="wrap_content"
    	   android:layout_height="wrap_content"
    	   android:text="hello view flinger"/>
</LinearLayout>

Create two more xml’s as view1.xml and view2.xml. Add the above code in it and add different image names in ImageView

MainActivity
will look like:

package com.mobisys.android.viewflinger;

import com.egoclean.android.widget.flinger.ViewFlinger;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class MainActivity extends Activity{

	ViewFlinger viewFlinger;
	View cur_view,next_view,prev_view;
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        viewFlinger=(ViewFlinger)findViewById(R.id.viewFlinger1);
        
        LayoutInflater inflate=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        cur_view=inflate.inflate(R.layout.view, null);
        prev_view=inflate.inflate(R.layout.view1, null);
        next_view=inflate.inflate(R.layout.view2, null);
        
        viewFlinger.addView(cur_view);
        viewFlinger.addView(prev_view);
   <div style="display:none"></div>      viewFlinger.addView(next_view);
        }
	
}

Run the project and swipe the screen.

Adding unlimited number of views

Suppose there are 100 views, so it will not be efficient to add 100 views. So here we will play with only 3 views not the 100 and we will reposition the views as explained below.

Whenever we swipe forward, we will remove prev_view from ViewFlinger, then we will assign curr_view to prev_view and next_view to cur_view.

i.e

               View temp_view=prev_view;
               prev_view=cur_view;
	       cur_view=next_view;
	       next_view=temp_view;

             if(viewFlinger.indexOfChild(next_view)!=-1)
						viewFlinger.removeViewFromFront();    

Also for backward swipe, we remove next_view from ViewFlinger, then we will assign cur_view to next_view and prev_view to cur_view.

i.e

 temp_View=next_view;
					next_view=cur_view;
					cur_view=prev_view;
					prev_view=temp_View;

                         if(viewFlinger.indexOfChild(prev_view)!=-1)
						viewFlinger.removeViewFromBack();

i.e.
view.xml contains:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical">
  		<ImageView android:id="@+id/image"
    		android:layout_height="wrap_content"
    		android:layout_width="wrap_content"
    		android:background="@drawable/icon"/>
    	<TextView android:id="@+id/text"
    	   android:layout_width="wrap_content"
    	   android:layout_height="wrap_content"
    	   android:text="hello view flinger"/>
    	 <TextView android:id="@+id/flashCardNo"
	          android:layout_height="wrap_content"
	          android:layout_width="wrap_content"
	          android:layout_marginTop="200dp"
	         
	          />  
</LinearLayout>

and MainActivity contains:

package com.mobisys.android.viewflinger;

import com.egoclean.android.widget.flinger.ViewFlinger;
import com.egoclean.android.widget.flinger.ViewFlinger.OnScreenChangeListener;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity implements OnScreenChangeListener{

ViewFlinger viewFlinger;
View cur_view,next_view,prev_view;
int currentIndex;
int currentScreenIndex = 0;
int total_count=5;
private boolean from_start=true;
TextView txt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

viewFlinger=(ViewFlinger)findViewById(R.id.viewFlinger1);
currentIndex=0;

LayoutInflater inflate=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

cur_view=inflate.inflate(R.layout.view, null);
prev_view=inflate.inflate(R.layout.view, null);
next_view=inflate.inflate(R.layout.view, null);

if(currentIndex>total_count) currentIndex=0;

int start_index=currentIndex;
from_start=start_index==0;

if(currentIndex > 0) loadView(prev_view,currentIndex-1,currentScreenIndex++,true);
if(currentIndex <= total_count-1) loadView(cur_view,currentIndex++,currentScreenIndex++,true); if(currentIndex <= total_count-1) loadView(next_view,currentIndex++,currentScreenIndex,true); if(start_index>0) currentScreenIndex=1;
else currentScreenIndex=0;

viewFlinger.setCurrentScreenNow(currentScreenIndex, false);
viewFlinger.setOnScreenChangeListener(this,false);
}
private void loadView(View v, int cur_index, int screen_index,boolean init) {

if(cur_index%2==0)
v.findViewById(R.id.image).setBackgroundResource(R.drawable.icon);
else if(cur_index%2==1)
v.findViewById(R.id.image).setBackgroundResource(R.drawable.icon1);

txt=(TextView)v.findViewById(R.id.flashCardNo);
txt.setText(“Card number: “+(cur_index+1)+” of “+total_count);

if(init)
viewFlinger.addView(v,screen_index);

else{

if(screen_index!=0)
viewFlinger.addView(v,screen_index);
else
viewFlinger.addViewToFront(v);

}
}
@Override
public void onScreenChanged(View newScreen, int newScreenIndex) {
if(currentScreenIndex!=newScreenIndex){

if(newScreenIndex>currentScreenIndex){
if(from_start||currentScreenIndex==1){
from_start=false;
//if(currentIndex=0)
loadView(prev_view,currentIndex-4,0,false);
else{
if(total_count>4)
loadView(prev_view, total_count+(currentIndex-4),0,false);
else
loadView(prev_view,total_count+(currentIndex – total_count),0,false);
}

viewFlinger.setCurrentScreenNow(1,false);
currentScreenIndex=1;
currentIndex–;
if(currentIndex<0) currentIndex=total_count-1; } else currentScreenIndex=1; } } } @Override public void onScreenChanging(View newScreen, int newScreenIndex) { // TODO Auto-generated method stub } } [/sourcecode]

AUTHOR: Vikas Hiran
3 Comments
  • kuki

    Great article! But I can’t understand in which way you can add infinite views.
    If I have an array filled with views, how can I display all of them?
    Thanks!

    May 10, 2012
  • lockzackary

    Hey, thanks so much for this… really saved me a lot of time 🙂

    July 10, 2012
  • Mehdi

    Awesome work. Just found out this lib, integrated it into a my calendar to make infinite browsing by adapting your sample, built and ran the project, worked p.e.r.f.e.c.t.l.y the first time. Thanks !

    March 26, 2013

Leave a Comment

Your email address will not be published.