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

來源:互聯網
上載者:User

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

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);//設定頁卡的標題    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.