Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android UI學習筆記 之 使用ViewPager實現導航

Android UI學習筆記 之 使用ViewPager實現導航

編輯:關於Android編程

ViewPager的用處就如上圖所示(圖源網絡),當我們左右滑動屏幕時,會從一個頁卡轉到下一個頁卡。

ViewPager中默認三個為一組的加載,例如,view1 view2 view3,當我們向左滑動時,view1會被銷毀,

而view4(如果有的話)就會實例化加載進來,變成view2 view3 view4的樣子。

使用ViewPager大致分為以下步驟:

建立數據源List或者List

將數據源綁定到適配器,不同的數據源有不同的適配器。

再將適配器綁定到當前的ViewPager中,完成。

當填充的內容不同時,使用的適配器也不同。

PagerAdapter適配器對應的數據源是List,能動態加載頁卡,銷毀頁卡。

FragmentPagerAdapter適配器對應的數據源是List,不能動態加載頁卡,銷毀頁卡,一次性全部導入。

FragmentStatePagerAdapter適配器對應的數據源是List,能動態加載頁卡,銷毀頁卡。

建立數據源List或者List

ViewPager中可以填充View和Fragment作為頁卡。

我們這裡以View為例,先新建一個簡單的layout,裡面只有一個TextView,用來顯示第幾個頁卡。



    
然後在Activity中將這個layout轉換為View對象,有兩種方法,這裡大致提一下。
//第一種方法
LayoutInflater lf = getLayoutInflater().from(this);//先獲取LayoutInflater 對象
lf.inflate(resource, root);//再inflate獲取view,resource表示layout的布局文件,root表示需要附加到resource資源文件的根控件

//第二種方法
View.inflate(context, resource, root);//context表示當前的上下文,resouce和root參照上面解釋
//這裡的root就是說要把layout轉換得到的view加載到哪一個ViewGroup裡面,我們這裡不需要.所以設置為null
得到的view在添加到List集合裡面,這樣第一步建立數據源就完成了。
    viewList = new ArrayList();
    for (int i = 0; i < 4; i++) {
        View view = View.inflate(MainActivity.this, R.layout.view, null);
        ((TextView) view.findViewById(R.id.pageText)).setText("這是第" + i + "個View");
        viewList.add(view);
    }

將數據源綁定到適配器,不同的數據源有不同的適配器。
我們需要自己來寫一個適配器,因為之前用的是View來填充的,所以這裡使用PagerAdapter。

public class MyViewPagerAdapter extends PagerAdapter {
    List viewList;//頁卡的View集合
    List titleList;//頁卡的標題集合

    public MyViewPagerAdapter(List viewList, List titleList) {//自定義的構造方法
        this.viewList = viewList;
        this.titleList = titleList;
    }
    @Override
    public int getCount() {
        return viewList.size();//返回頁卡數量
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;//這個view是否來自object的類型
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(viewList.get(position));//實例化一個頁卡,左右滑動時調用
        return viewList.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(viewList.get(position));//銷毀一個頁卡,左右滑動時調用
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);//設置頁卡的標題,如上圖中的FragmentA,FragmentB,FragmentC
    }
}

裡面有一些常用的方法要重寫。

getCount()返回的是頁卡的數量,也就是你填充進去的View的數量,我們用集合的size()方法返回一個int。isViewFromObject()判斷的是view的類型,有時候我們要判斷這個view是否為TextView或者Button之類的。instantiateItem()這個方法的用法,就是當頁面是view1 view2 view3時,向左滑動,出現view4的時候調用的,用來加載view4,形成view2 view3 view4。destroyItem()和上一個方法同時調用,銷毀view1,本質上就是從ViewGroup中刪掉view1,加入view4。getPageTitle()顯示的是標題,如最上面圖中的fragmengA,fragmengB,fragmengC。

我們寫了個適配器之後,之後當然就是加載數據源了。

第二步的主要工作就是寫適配器了。

myViewPagerAdapter = new MyViewPagerAdapter(viewList, titleList);//將List傳入,適配器中要寫構造方法

③再將適配器綁定到當前的ViewPager中,完成。

先在Activity的XML布局文件中,加入ViewPager。

實現上圖中的FragmentA,FragmentB,FragmentC的標題其實有兩種方法,

使用PagerTabStrip或者PagerTitleStrip兩種,注意只能取其中一種方法。

然後通過layout_gravity來布置,我們把tab放在頂部,title放在底部。

<android.support.v4.view.viewpager android:id="@+id/viewPager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center">
    <android.support.v4.view.pagertabstrip android:id="@+id/tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:background="@color/yellow">
    </android.support.v4.view.pagertabstrip>
    <android.support.v4.view.pagertitlestrip android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="@color/blue">
  </android.support.v4.view.pagertitlestrip>
</android.support.v4.view.viewpager>
會造成tab的失效(PagerTabStrip是PagerTitleStrip的子類,有興趣的可以看下API)
然後綁定適配器,完成。
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(myViewPagerAdapter);

 

附加:

如果覺得樣式很丑的話,我們可以自定義樣式

建議還是實際寫一下代碼,增加印象。
//在pagerTabStrip中有以下方法
pagerTabStrip.setBackgroundColor(int color);//導航欄的背景色
pagerTabStrip.setTextColor(int color);//導航欄的文字色
pagerTabStrip.setDrawFullUnderline(boolean drawFull);//導航欄底線是否顯示
pagerTabStrip.setTabIndicatorColor(int color);//當前頁卡的選中的線的顏色

如果不是用View,而是用Fragment填充呢

 

通過查閱API,我們可以知道FragmentPagerAdapter和FragmentStatePagerAdapter是兄弟關系,都是直接繼承自PagerAdapter。

兩者的區別在於FragmentPagerAdapter不能動態加載頁卡,是一次性導入所有頁卡,而FragmentStatePagerAdapter是和PagerAdapter一樣動態加載頁卡的。

和View一樣,我們為FragmentPagerAdapter適配器添加數據源List,然後重寫FragmentPagerAdapter中的方法(繼承自PagerAdapter)。

注意FragmentPagerAdapter是一次性加載所有頁卡,所以不用重寫instantiateItem()和destroyItem()(這兩個方法在FragmentStatePagerAdapter要重寫)。

值得注意的是我們需要import android.support.v4.app.Fragment;而不是import android.app.Fragment。

並且,我們的Activity要繼承自FragmentActivity,

並且在new對象的時候,要在Activity中用getSupportFragmentManager()獲取FragmentManager對象。

public MyFragmentPagerAdapter(FragmentManager fm,List fragmentList, List titleList) {
        super(fm);
        this.fragmentList = fragmentList;
        this.titleList = titleList;
    }

 

最後,我們再添加一個監聽器

 

public class MainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener{
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        System.out.println("當前是第"+position+"個頁卡" +
                ",當前頁面偏移的百分比:"+positionOffset+
                ",當前頁面偏移的像素位置:"+positionOffsetPixels);
        //當頁卡滾動時調用該方法
    }

    @Override
    public void onPageSelected(int position) {
        Toast.makeText(MainActivity.this, "當前是第"+position+"個頁卡", Toast.LENGTH_SHORT).show();
        //當頁卡改變時調用該方法
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        switch (state) {
            case 0: Toast.makeText(MainActivity.this, "滑動完畢", Toast.LENGTH_SHORT).show();break;
            case 1: Toast.makeText(MainActivity.this, "手指按下", Toast.LENGTH_SHORT).show();break;
            case 2: Toast.makeText(MainActivity.this, "手指抬起", Toast.LENGTH_SHORT).show();break;
        }
        //當滑動狀態改變時調用該方法
    }


 

 

以下附上以View填充的ViewPager的Demo源碼。

public class MainActivity extends Activity implements ViewPager.OnPageChangeListener{
    List viewList;//填充View數據源
    List titleList;//View的標題集合
    MyViewPagerAdapter myViewPagerAdapter;//自定義的以View為數據源的適配器
    PagerTabStrip pagerTabStrip;//導航欄
    ViewPager viewPager;//被填充的組件
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewList = new ArrayList();
        titleList = new ArrayList();
        View[] views = new View[4];
        for (int i = 0; i < 4; i++) {
            views[i] = View.inflate(MainActivity.this, R.layout.view, null);//將view.xml轉化為View對象
            ((TextView) views[i].findViewById(R.id.pageText)).setText("這是第" + i + "個View");
            titleList.add("第" + i + "頁");//添加標題到集合
            viewList.add(views[i]);//添加view到集合
        }

        pagerTabStrip = (PagerTabStrip) findViewById(R.id.tab);//自定義導航欄樣式
        pagerTabStrip.setBackgroundColor(Color.YELLOW);//導航欄背景色
        pagerTabStrip.setTextColor(Color.BLUE);//導航欄文字色
        pagerTabStrip.setDrawFullUnderline(false);//導航欄底線是否顯示
        pagerTabStrip.setTabIndicatorColor(Color.RED);//導航欄選中的當前頁卡的底線顏色

        myViewPagerAdapter = new MyViewPagerAdapter(viewList, titleList);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPager.setAdapter(myViewPagerAdapter);//添加適配器到ViewPager
        viewPager.setOnPageChangeListener(this);//設置監聽器
    }
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        System.out.println("當前是第"+position+"個頁卡" +
                ",當前頁面偏移的百分比:"+positionOffset+
                ",當前頁面偏移的像素位置:"+positionOffsetPixels);
        //當頁卡滾動時調用該方法
    }
    @Override
    public void onPageSelected(int position) {
        Toast.makeText(MainActivity.this, "當前是第"+position+"個頁卡", Toast.LENGTH_SHORT).show();
        //當頁卡改變時調用該方法
    }
    @Override
    public void onPageScrollStateChanged(int state) {
        switch (state) {
            case 0: Toast.makeText(MainActivity.this, "滑動完畢", Toast.LENGTH_SHORT).show();break;
            case 1: Toast.makeText(MainActivity.this, "手指按下", Toast.LENGTH_SHORT).show();break;
            case 2: Toast.makeText(MainActivity.this, "手指抬起", Toast.LENGTH_SHORT).show();break;
        }
        //當滑動狀態改變時調用該方法
    }
}
public class MyViewPagerAdapter extends PagerAdapter {
    List viewList;
    List titleList;
    public MyViewPagerAdapter(List viewList, List titleList) {
        this.viewList = viewList;
        this.titleList = titleList;
    }

    @Override
    public int getCount() {
        return viewList.size();//返回頁卡數量
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;//這個view是否來自object的類型
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(viewList.get(position));//實例化一個頁卡
        return viewList.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(viewList.get(position));//銷毀一個頁卡
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);//設置頁卡的標題
    }
}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved