android之ViewPager介紹

分類:IT技術 時間:2016-10-09
一:ViewPager的含義:
ViewPager的功能就是可以使視圖滑動,就像Lanucher左右滑動那樣。
ViewPager用於實現多頁面的切換效果,該類存在於Google的兼容包android-support-v4.jar裏面.
ViewPager:
   1)ViewPager類直接繼承了ViewGroup類,所有它是一個容器類,可以在其中添加其他的view類。
   2)ViewPager類需要一個PagerAdapter適配器類給它提供數據。
   3)ViewPager經常和Fragment一起使用,並且提供了專門的FragmentPagerAdapter和FragmentStatePagerAdapter類供Fragment中    的ViewPager使用。
  4)在編寫ViewPager的應用的使用,還需要使用兩個組件類分別是PagerTitleStrip類和PagerTabStrip類,PagerTitleStrip類直接繼承  自ViewGroup類,而PagerTabStrip類繼承PagerTitleStrip類,所以這兩個類也是容器類。但是有一點需要註意,在定義XML的layout  的時候,這兩個類必須是ViewPager標簽的子標簽,不然會出錯。

如下:

<android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/viewPager"
        android:layout_gravity="center">
    	<android.support.v4.view.PagerTitleStrip
    	    android:id="@+id/pagertitle"
    	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
            android:layout_gravity="top"/>
</android.support.v4.view.ViewPager>
其中ViewPager為多頁顯示控件, pagerTitleStrip用於顯示當前頁面的標題,並且其android:layout_width必須設置成match_parent

二:完成一個簡單的ViewPager例子
 a)在布局文件中配置ViewPager
 <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/> 
 b)在Activity中獲取這這個ViewPager組件.
   並且可以設置全屏效果:
   requestWindowFeature(Window.FEATURE_NO_TITLE);
   getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
 c)加載要顯示的頁卡:初始化數據,即每一個頁面顯示的View.
   將其View添加到List集合中。
   LayoutInflater lf=getLayoutInflater();
   list=new ArrayList<View>();
   list.add(lf.inflate(R.layout.activity_layout1,null));
   list.add(lf.inflate(R.layout.activity_layout2,null));
   list.add(lf.inflate(R.layout.activity_layout3,null));
 d)給ViewPager設置數據適配器PagerAdapter
   viewPager.setAdapter(PagerAdatpser);
  實現PagerAdapter至少要實現四個方法:
    1)instantiateItem(ViewGroup, int)
        對顯示的資源進行初始化。將顯示的View
加入到ViewGroup中,然後作為返回值返回。
//container.addView(list.get(position));
//return list.get(position);
    2)destroyItem(ViewGroup, int, Object)
        PagerAdapter有一個緩存範圍,如果在滑動過程
中超過了緩存範圍,就會調用這個方法,銷毀資源。
//////container.removeView(list.get(position));
    3)getCount()獲取要滑動的控件的數量
    4)isViewFromObject(View, Object)
       來判斷顯示的是否是同一個視圖,一般將兩個參數進行比較返回即可。

代碼如下:

public class MainActivity extends Activity {

	private ViewPager pager;
	//每一個界面
	private List<View> views;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, 
				LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
		setContentView(R.layout.activity_main);
		pager=(ViewPager) findViewById(R.id.pager);
		views=new ArrayList<View>();
		LayoutInflater li=getLayoutInflater();
		views.add(li.inflate(R.layout.f1, null));
		views.add(li.inflate(R.layout.f2, null));
		views.add(li.inflate(R.layout.f3, null));
		//需要給ViewPager設置適配器
		PagerAdapter adapter=new PagerAdapter() {
			
			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				// TODO Auto-generated method stub
				return arg0==arg1;
			}
			//有多少個切換頁
			@Override
			public int getCount() {
				// TODO Auto-generated method stub
				return views.size();
			}

			//對超出範圍的資源進行銷毀
			@Override
			public void destroyItem(ViewGroup container, int position,
					Object object) {
				// TODO Auto-generated method stub
				//super.destroyItem(container, position, object);
				container.removeView(views.get(position));
			}
			//對顯示的資源進行初始化
			@Override
			public Object instantiateItem(ViewGroup container, int position) {
				// TODO Auto-generated method stub
				//return super.instantiateItem(container, position);
				container.addView(views.get(position));
				return views.get(position);
			}
			
		};
		pager.setAdapter(adapter);
		
		//給ViewPager添加事件監聽
		pager.setOnPageChangeListener(new OnPageChangeListener() {
			
			@Override
			public void onPageSelected(int arg0) {
				// TODO Auto-generated method stub
				Toast.makeText(MainActivity.this, "您選擇了:"+arg0+"頁面", 0).show();
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub
				
			}
		});
	}
}
布局文件就一個ViewPager,就不貼代碼了,

效果如圖:


三:實現了滑動頁面的的簡單實現方法,但有時,僅僅實現頁面滑動是不夠的,還要有標題欄才會顯得更友好。
所以需要使用android.support.v4包中的兩個控件PagerTabStrip與PagerTitleStrip,他們都是用來實現標題欄的,但各自有些不同。
  a)PagerTitleStrip是ViewPager的一個關於當前頁面、上一個頁面和下一個頁面的一個非交互的指示器。
它經常作為ViewPager控件的一個子控件被被添加
在XML布局文件中。在布局文件中,它必須作為子
控件添加在ViewPager中。而且要使用它的
android:layout_gravity性設置為TOP或BOTTOM來
將標題顯示在ViewPager的頂部或底部。每個頁面的標
題是通過適配器的getPageTitle(int)函數提供給ViewPager
的標題內容。
  b)PagerTabStrip是ViewPager的一個關於當前頁面、上一個頁面和下一個頁面的一個可交互的指示器。
它經常作為ViewPager控件的一個子控件被被添加
在XML布局文件中。在你的布局文件中,將它作為
子控件添加在ViewPager中。而且要將它的 
android:layout_gravity 屬性設置為TOP或BOTTOM
來將它顯示在ViewPager的頂部或底部。每個頁面
的標題是通過適配器的getPageTitle(int)函數提
供給ViewPager的標題內容。
  註意:其實這兩個實現的效果基本差不多,但有兩點不同:
          1)PagerTabStrip在當前頁面下,會有一個下劃線條來提示當前頁面的Tab是哪個。
          2)PagerTabStrip的Tab是可以點擊的,當用戶點擊某一個Tab時,當前頁面就
 會跳轉到這個頁面,而PagerTitleStrip
 則沒這個功能。
         3)做標題欄需要重寫適配器中的
getPageTitle(int position)返回標題內容。
所有標題可以放在List集合中,每次在
該方法中返回指定位置的標題。
        4)可以自定義PagerTabStrip的樣式
tabStrip = (PagerTabStrip)findViewById(R.id.pagertab);
//取消tab下面的長橫線
tabStrip.setDrawFullUnderline(true);
//設置tab的背景色
tabStrip.setBackgroundColor(Color.BLUE);
//設置當前tab頁簽的下劃線顏色
tabStrip.setTabIndicatorColor(Color.RED);
tabStrip.setTextColor(Color.CYAN);
實例代碼:

布局:

<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.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/pager" >
        <android.support.v4.view.PagerTabStrip
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:id="@+id/title"
            />
          
     </android.support.v4.view.ViewPager>

</RelativeLayout>

activity:

public class TestActivity extends Activity {

	private ViewPager pager;
	//每一個界面
	private List<View> views;
	//標題
	private String[] titles={"新聞","娛樂","軍事"};
	
	private PagerTabStrip t;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, 
				LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
		setContentView(R.layout.activity_test);
		
		t=(PagerTabStrip) findViewById(R.id.title);
		//自定義table的樣式
		t.setBackgroundColor(Color.MAGENTA);
		t.setTextColor(Color.BLUE);
		t.setTextSize(0, 25f);
		t.setTabIndicatorColor(Color.GREEN);
		
		pager=(ViewPager) findViewById(R.id.pager);
		views=new ArrayList<View>();
		LayoutInflater li=getLayoutInflater();
		views.add(li.inflate(R.layout.f1, null));
		views.add(li.inflate(R.layout.f2, null));
		views.add(li.inflate(R.layout.f3, null));
		//需要給ViewPager設置適配器
		PagerAdapter adapter=new PagerAdapter() {
			
			//提供標題的內容
			@Override
			public CharSequence getPageTitle(int position) {
				// TODO Auto-generated method stub
				return titles[position];
			}
			
			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				// TODO Auto-generated method stub
				return arg0==arg1;
			}
			//有多少個切換頁
			@Override
			public int getCount() {
				// TODO Auto-generated method stub
				return views.size();
			}

			//對超出範圍的資源進行銷毀
			@Override
			public void destroyItem(ViewGroup container, int position,
					Object object) {
				// TODO Auto-generated method stub
				//super.destroyItem(container, position, object);
				container.removeView(views.get(position));
			}
			//對顯示的資源進行初始化
			@Override
			public Object instantiateItem(ViewGroup container, int position) {
				// TODO Auto-generated method stub
				//return super.instantiateItem(container, position);
				container.addView(views.get(position));
				return views.get(position);
			}
			
		};
		pager.setAdapter(adapter);
	}
}

效果圖:


四:PagerTabStrip和PagerTitleStrip都不適合用在實際用途中,

當要在實際運用中,我們就要自己去實現相關的功能。一般使用交互Tab的實現。
   步驟:a)布局文件使用TextView完成tab的切換卡。
           使用ImageView進行分割
           使用ViewPager進行翻頁
         b)在Activity中獲取TextView對象,
  並分別設置點擊事件。點擊TextView
  可以切換當前選中的卡片:
   mPager.setCurrentItem(index);
c)在Activity中獲取ViewPager對象。
  添加卡片內容,設置PagerAdapter適配器。
d)給ViewPager對象設置setOnPageChangeListener();
  可以監聽某個卡片被選中的事件監聽器。
  修改TextView的字體大小和字體顏色。
實例:

布局:

<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="vertical">
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal"
        android:background="#D5D4C3"
        android:gravity="center">
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:layout_weight="1"
            android:text="聊天"
            android:id="@+id/tv1"
            android:gravity="center"/>
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:layout_weight="1"
            android:text="發現"
            android:id="@+id/tv2"
            android:gravity="center"/>
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:layout_weight="1"
            android:text="通訊錄"
            android:id="@+id/tv3"
            android:gravity="center"/>
    </LinearLayout>
    <View 
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#68AE94"/>
    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/pager" />
</LinearLayout>
activity:

public class MyTabActivity extends Activity {

	private ViewPager pager;
	private List<View> views;
	//放標簽頁
	private List<TextView>tvs=new ArrayList<TextView>();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_tab);
		initTextView();
		//初始化ViewPager組件
		initView();
		initViewPager();
	}
	
	public void initTextView() {
		// TODO Auto-generated method stub
		TextView tv1=(TextView) findViewById(R.id.tv1);
		tv1.setTextColor(Color.BLUE);
		TextView tv2=(TextView) findViewById(R.id.tv2);
		TextView tv3=(TextView) findViewById(R.id.tv3);
		//添加點擊事件
		//OnClickListener click=new MyClickListener();
		tv1.setOnClickListener(new MyClickListener(0));
		tv2.setOnClickListener(new MyClickListener(1));
		tv3.setOnClickListener(new MyClickListener(2));
		tvs.add(tv1);
		tvs.add(tv2);
		tvs.add(tv3);
	}	
	private class MyClickListener implements OnClickListener{

		private int index;
		public MyClickListener(int index) {
			// TODO Auto-generated constructor stub
			this.index=index;
		}
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			//改變ViewPager當前顯示頁面
			pager.setCurrentItem(index);
		}
	}

	//初始化ViewPager中顯示的數據
	public void initView() {
		// TODO Auto-generated method stub
		views=new ArrayList<View>();
		LayoutInflater li=getLayoutInflater();
		views.add(li.inflate(R.layout.f1, null));
		views.add(li.inflate(R.layout.f2, null));
		views.add(li.inflate(R.layout.f3, null));
	}
	
	
	public void initViewPager() {
		// TODO Auto-generated method stub
		pager=(ViewPager) findViewById(R.id.pager);
		PagerAdapter adapter=new MyPagerAdapter();
		pager.setAdapter(adapter);
		pager.setOnPageChangeListener(new OnPageChangeListener() {
			
			@Override
			public void onPageSelected(int index) {
				// TODO Auto-generated method stub
				for(int i=0;i<tvs.size();i++){
					if(i==index){
						tvs.get(i).setTextColor(Color.BLUE);
					}else{
						tvs.get(i).setTextColor(Color.rgb(55,55,55));
					}
				}
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub
				
			}
		});
	}	
	private class MyPagerAdapter extends PagerAdapter{

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			// TODO Auto-generated method stub
			return arg0==arg1;
		}
		//有多少個切換頁
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return views.size();
		}
		//對超出範圍的資源進行銷毀
		@Override
		public void destroyItem(ViewGroup container, int position,
				Object object) {
			// TODO Auto-generated method stub
			//super.destroyItem(container, position, object);
			container.removeView(views.get(position));
		}
		//對顯示的資源進行初始化
		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			// TODO Auto-generated method stub
			//return super.instantiateItem(container, position);
			container.addView(views.get(position));
			return views.get(position);
		}
	}
}

效果圖:


五:前面介紹ViewPager的普通實現方法,但android官方最推薦的一種實現方法卻是使用fragment。
使用Fragment的時候需要使用的適配器為FragmentPagerAdapter。
FragmentPagerAdapter是PagerAdapter的子類,專門用於處理Fragment翻頁的適配器。
這個適配器最好用於有限個靜態fragment頁面的管理。盡管不可見的視圖有時會被銷毀,但用戶所有訪問過的fragment都會被保存在內存中。因此fragment實例會保存大量的各種狀態,這就造成了很大的內存開銷。
所以如果要處理大量的頁面切換,建議使用FragmentStatePagerAdapter.對於FragmentPagerAdapter的派生類,只需要重寫getItem(int)和getCount()就可以了。

步驟:a)寫一個Activity繼承FragmentActivity,
        專門處理Frament的Activity,重寫onCreate方法
List<Fragment> fragments=new ArrayList<Fragment>();
fragments.add(new Fragment1());
fragments.add(new Fragment2());
fragments.add(new Fragment3()); 
FragAdapter adapter = new FragAdapter(
getSupportFragmentManager(), fragments);      
        //設定適配器
        ViewPager vp = (ViewPager)findViewById(R.id.viewpager);
        vp.setAdapter(adapter);


      b)FragAdapter是extends FragmentPagerAdapter。
        //提供構造器
private List<Fragment> mFragments;
public FragAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
mFragments=fragments;
}
        //重寫方法
@Override
public Fragment getItem(int arg0) {
return mFragments.get(arg0);
}
@Override
public int getCount() {
return mFragments.size();
}

實例:

布局:和上一個一樣

activity:

public class MyFragmentActivity extends FragmentActivity {

	private ViewPager pager;
	private List<Fragment>list;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_tab);
		list=new ArrayList<Fragment>();
		list.add(new ChatFragment());
		list.add(new FindFragment());
		list.add(new ContactFragment());
		pager=(ViewPager) findViewById(R.id.pager);
		MyAdapter adapter=new MyAdapter(getSupportFragmentManager());
		pager.setAdapter(adapter);
	}
	
	//處理Fragment和ViewPager的適配器
	private class MyAdapter extends FragmentPagerAdapter{

		public MyAdapter(FragmentManager fm) {
			super(fm);
			// TODO Auto-generated constructor stub
		}

		@Override
		public Fragment getItem(int arg0) {
			// TODO Auto-generated method stub
			return list.get(arg0);
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return list.size();
		}
		
	}
}
效果圖:


有想要代碼的可以:下載鏈接





Tags:

文章來源:


ads
ads

相關文章
ads

相關文章

ad