ViewPager+Fragment實現界面滑動

VIewPager本身就可以實現界面的滑動效果,爲什麼還要結合Fragment一起使用呢?(或許是因爲結合Fragment一起使用可以更方便的管理每一個界面,對每個界面可以單獨處理,而不必要把所有代碼都寫到一個文件裏吧。)究其原因,我也說不明白,但是怎麼實現還是要學會的。

ViewPager加Fragment的實現無非就是把原先加載的Views換成了Fragments。其流程和單獨使用ViewPager差不多(數據源,適配器,綁定)。其中的差別可能就是在使用Fragment作爲頁面顯示時,適配器類要使用FragmentPagerAdapter。那麼,就有必要先學習一下FragmentPagerAdapter的相關API。

FragmentPagerAdapter類的主要介紹如下所示:


FragmentPagerAdapter extends PagerAdapter
它是一個公有抽象類,繼承自PagerAdapter。
java.lang.Object
   ↳ android.support.v4.view.PagerAdapter
   ↳ android.support.v13.app.FragmentPagerAdapter


Class Overview

類的概述:
          Implementation of PagerAdapter that represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.
         This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.

大意爲:

         FragmentPagerAdapter是PagerAdapter類的一種實現,它表示ViewPager的每一頁都是一個Fragment,並且只要用戶可以返回到頁面中,Fragment就會一直保存在碎片管理器(fragment manager)中。
        這種類型的頁面最好用於少量靜態Fragment的顯示,比如一系列選項卡(tabs)。此外,雖然當頁面不可見時,fragment的試圖層次結構( view hierarchy)就可能被銷燬,但是用戶訪問的每一個頁面對應的Fragment都將被保存在內存中。這可能導致大量內存的佔用,因爲fragment實例可能保持任意數量的狀態。所以,對於大量頁面的顯示,推薦使用FragmentStatePagerAdapter。

       When using FragmentPagerAdapter the host ViewPager must have a valid ID set.
        Subclasses only need to implement getItem(int) and getCount() to have a working adapter.
        FragmentPagerAdapter的子類只要實現 getItem(int) 和 getCount()方法,就可起作用。

       getItem(int) 決定了顯示什麼,getCount()方法決定了有多少項可顯示。



通過案例進行實現,效果如下:

                    

                  圖1.  初始時                                                                                     圖2. 滑動時                               

其主佈局文件爲activity_main.xml。其中佈局中的PagerTabStrip對應着視圖中頂部的選項卡效果。當不需要時,可以不添加。佈局下面的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"
    tools:context="${relativePackage}.${activityClass}" >

    
    <android.support.v4.view.ViewPager
        android:id="@+id/mViewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        
        <android.support.v4.view.PagerTabStrip
            android:id="@+id/mTab"
            android:background="#556677"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="top"
            
            />                  
        
    </android.support.v4.view.ViewPager>
        
       <TextView 
            android:id="@+id/mTV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>    
                  
       

</LinearLayout>
此外自定義了3個Fragment類,代碼相同,其一如下:
</pre><pre name="code" class="html">
package com.jtest.fragments;

import com.jtest.viewpagertest.R;

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

public class Fragment1 extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View view=inflater.inflate(R.layout.pager1, container, false);
		return view;
	}

}
Fragment的佈局文件如下:
<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff0000"
    android:orientation="vertical" >
    
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="pager1"      
        
        />

</LinearLayout>

主程序代碼MainActivity.java如下:

<pre name="code" class="html">package com.jtest.viewpagertest;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.jtest.fragments.Fragment1;
import com.jtest.fragments.Fragment2;
import com.jtest.fragments.Fragment3;
import com.jtest.pageradpter.MyFragmentAdapter;

public class MainActivity extends FragmentActivity implements OnPageChangeListener{

	
	private ViewPager viewPager;
	private PagerTabStrip mTab;
	private TextView mTextView;	
	private MyFragmentAdapter fragAdapter;
	
	List<String>titles;
	
	List<Fragment>frags;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		 initFragment();
     	fragAdapter=new MyFragmentAdapter(getSupportFragmentManager(),frags,titles);
		viewPager.setAdapter(fragAdapter);
		
		viewPager.setOnPageChangeListener(this);
		viewPager.setCurrentItem(1);
	}
	
	private void initView(){
		mTextView=(TextView) findViewById(R.id.mTV);
	        viewPager=(ViewPager) findViewById(R.id.mViewPager);
		mTab=(PagerTabStrip) findViewById(R.id.mTab);	  
		titles=new ArrayList<String>();	
		
		
		
		String t1="pager1";
		String t2="pager2";
		String t3="pager3";		
		titles.add(t1);
		titles.add(t2);
		titles.add(t3);
		
	
		
	}
	 void initFragment(){
		        frags=new ArrayList<Fragment>();
			Fragment f1=new Fragment1();
			Fragment f2=new Fragment2();
			Fragment f3=new Fragment3();
			frags.add(f1);
			frags.add(f2);
			frags.add(f3);
	 }
	
	@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub
		Log.e("onPageScrollStateChanged", "state change");
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		// TODO Auto-generated method stub
		Log.e("onPageScrolled", "You are scroll the view");
	}
/**
 * argo返回的是當前頁面(剛進入的頁面的)的頁碼從0開始
 */
	@Override
	public void onPageSelected(int arg0) {
		// TODO Auto-generated method stub
		Toast.makeText(this, "當前頁碼"+arg0, Toast.LENGTH_LONG).show();
		mTextView.setText("pager"+arg0);
	}
	
}



適配器MyFragmentAdapter.java:

package com.jtest.pageradpter;

import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;


public class MyFragmentAdapter extends FragmentPagerAdapter {

     List<Fragment>frags;
     List<String>titles;
	public MyFragmentAdapter(FragmentManager fm, List<Fragment> frags,  List<String>titles) {
		super(fm);
		this.frags = frags;
		this.titles = titles;
	}

	@Override
	public CharSequence getPageTitle(int position) {
		// TODO Auto-generated method stub
		return titles.get(position);
	}

	@Override
	public Fragment getItem(int position) {
		// TODO Auto-generated method stub
		return frags.get(position);
	}
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return frags.size();
	}

}
注意事項:

1.構造函數一定要實現super(fm)方法;

2.剛開始時,調用構造函數創建適配器時總報錯,提示構造函數不存在,經分析所傳給的參數類型並沒有錯誤,不知錯在哪裏,後發現錯誤可能是獲取的FragmentManage對象r的版本支持問題。一個位於android.support.v4.app.FragmentManager,一個位於android.app.FragmentManager;雖然都是FragmentManager但卻不兼容。後來改用getSupportFragmentManager()來獲取碎片管理器得以解決。










發佈了35 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章