Wednesday, March 5, 2014

ViewPager example, with switching page programmatically

It's my old post about ViewPager. It's modified to add buttons, such that user can click on the buttons to switch to another page programmically.



Modify the main activity, AndroidViewPagerActivity.java, to add a method switchFragment(int target) to call mViewPager.setCurrentItem(target) using Java code. Also we have to comment super.onSaveInstanceState(outState) in onSaveInstanceState(Bundle outState) method to prevent NullPointerException of ViewPager when change orientation.
package com.exercise.AndroidViewPager;

import java.util.ArrayList;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class AndroidViewPagerActivity extends FragmentActivity {
 
 ViewPager mViewPager;
 TabsAdapter mTabsAdapter;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mViewPager = new ViewPager(this);
        mViewPager.setId(R.id.pager);
        setContentView(mViewPager);
        
        final ActionBar bar = getActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
        
        mTabsAdapter = new TabsAdapter(this, mViewPager);
        mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
                MyFragmentA.class, null);
        mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
          MyFragmentB.class, null);
        mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
          MyFragmentC.class, null);

        if (savedInstanceState != null) {
            bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }

    }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  //super.onSaveInstanceState(outState);
        outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
 }
 
 public static class TabsAdapter extends FragmentPagerAdapter
  implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
  
  private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
        
        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

  public TabsAdapter(FragmentActivity activity, ViewPager pager) {
   super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

  public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

  @Override
  public void onPageScrollStateChanged(int state) {
   // TODO Auto-generated method stub
   
  }

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
   // TODO Auto-generated method stub
   
  }

  @Override
  public void onPageSelected(int position) {
   // TODO Auto-generated method stub
   mActionBar.setSelectedNavigationItem(position);
  }

  @Override
  public void onTabReselected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   
  }

  @Override
  public void onTabSelected(Tab tab, FragmentTransaction ft) {
   Object tag = tab.getTag();
            for (int i=0; i<mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
  }

  @Override
  public void onTabUnselected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   
  }

  @Override
  public Fragment getItem(int position) {
   TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
  }

  @Override
  public int getCount() {
   return mTabs.size();
  }

 }
    
    void switchFragment(int target){
     mViewPager.setCurrentItem(target);
    }
}


Modify layout of fragment_a.xml to add buttons to switch page.
<?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" >
   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It's Fragment A" />
   <Button
       android:id="@+id/swb"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Switch to Fragment B"/>
   <Button
       android:id="@+id/swc"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Switch to Fragment C"/>
   <ImageView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:src="@drawable/ic_launcher"/>
</LinearLayout>


Modify MyFragmentA.java to call switchFragment() in main activity when buttons clicked. To access main activity from separate fragment java class, we can call getActivity() method.
package com.exercise.AndroidViewPager;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MyFragmentA extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
  
  Button btnSwB = (Button)myFragmentView.findViewById(R.id.swb);
  btnSwB.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    ((AndroidViewPagerActivity)getActivity()).switchFragment(1);
   }});

  Button btnSwC = (Button)myFragmentView.findViewById(R.id.swc);
  btnSwC.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    ((AndroidViewPagerActivity)getActivity()).switchFragment(2);
   }});
  
  return myFragmentView;
 }

}


For other files, include MyFragmentB.java, fragment_b.xml, MyFragmentC.java, and fragment_c.xml, refer to the post "ViewPager".

download filesDownload the files.

Next:
- Display the title in ActionBar

5 comments:

Anonymous said...

Thank,
I have a question, why the top of title name is can't see. I want to show the title name, how can I write it?

Andr.oid Eric said...

please read ViewPager example, display with title

Anonymous said...

My Requirement is like whenever user select any number from number picker on that time that number should be printed on some text view and second time whenever user opens dialog again than previously selected number should be shown on that dialog But I don't know how to write Number Picker dialog in Fragment. Can u give me the code. Thank u.

Thomas Rykala said...

Great stuff, thank you.

DonAjmal said...

Thanks a lot :D . You saved me.