顯示廣告
隱藏 ✕
看板 KnucklesNote
作者 Knuckles (站長 那克斯)
標題 [AndroidStudio] 使用 ViewPager 左右滑動換頁
時間 2017-01-12 Thu. 00:37:03


依照之前這一篇
[AndroidStudio] 使用 Fragment 切換頁面內容 - KnucklesNote板 - Disp BBS
將頁面改為使用 Fragment,但只能點上方的按鈕來換頁

這篇要改用 ViewPager 使用左右滑動來換頁
[圖]


 

ViewPager 還會預載左右兩頁的內容,換頁後不用再等資料載入


先檢查一下之前使用到 Fragment 的 java 檔,前面 import 的 Fragment
如果是 import android.app.Fragment;
要改成 import android.support.v4.app.Fragment;


修改主頁面的 layout 檔 activity_main.xml
刪除原本使用的 <FrameLayout … /> 改為
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.v4.view.ViewPager>


修改主頁面的 java 檔 MainActivity.java

修改成員變數
//刪掉這行
//    Fragment mHotTextFragment, mBoardListFragment, mBoardSearchFragment;

    //加上 ViewPager 與 FragmentPagerAdapter
    ViewPager mViewPager;
    FragmentPagerAdapter mAdapterViewPager;

在 MainActivity 中新增一個類別 MainPagerAdapter
    public static class MainPagerAdapter extends FragmentPagerAdapter {
        private static int NUM_ITEMS = 3;

        MainPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            switch(position){
                case 0:
                    return new HotTextFragment();
                case 1:
                    return new BoardListFragment();
                case 2:
                    return new BoardSearchFragment();
                default:
                    return null;

            }
        }

    }

修改成員函數 onCreate()
//刪掉這幾行
//        mHotTextFragment = new HotTextFragment();
//        mBoardListFragment = new BoardListFragment();
//        mBoardSearchFragment = new BoardSearchFragment();
//        mMailListFragment = new MailListFragment();
//        if (savedInstanceState == null) { //避免轉方向時重覆載入
//            getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, mHotTextFragment).commit();
//        }

        //加上
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        mAdapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mAdapterViewPager);
        mViewPager.addOnPageChangeListener(this);
對 mViewPager.addOnPageChangeListener(this); 的 this 按 alt+enter
[圖]

自動在 MainActivity 加上 implement ViewPager.OnPageChangeListener
與三個成員函數
    @Override
    public void onPageSelected(int position) {
        changeTab(position);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
只要改第一個,在滑動換頁後,執行 changeTab(position);


修改成員函式 changeTab()
    private void changeTab(int tabNew){
        Button btnSelect = mHotTextBtn;
        switch(mTabSelect){
            case TAB_BOARDLIST:
                btnSelect = mBoardListBtn;
                break;
            case TAB_BOARDSEARCH:
                btnSelect = mBoardSearchBtn;
                break;
        }
        btnSelect.setBackgroundColor(Color.BLACK);
        btnSelect.setTextColor(Color.parseColor("#99CCFF"));

        Button btnNew = mHotTextBtn;
        //Fragment fragmentNew = mHotTextFragment;
        switch(tabNew){
            case TAB_BOARDLIST:
                btnNew = mBoardListBtn;
                //fragmentNew = mBoardListFragment;
                break;
            case TAB_BOARDSEARCH:
                btnNew = mBoardSearchBtn;
                //fragmentNew = mBoardSearchFragment;
                break;
        }
        btnNew.setBackgroundColor(Color.LTGRAY);
        btnNew.setTextColor(Color.BLACK);

//        if(mTabSelect==tabNew){
//            getSupportFragmentManager().beginTransaction().detach(fragmentNew).attach(fragmentNew).commit();
//        }else {
//            getSupportFragmentManager().beginTransaction().replace(R.id.frameLayout, fragmentNew).commit();
//        }
        mTabSelect = tabNew;
    }
將原本執行換頁的程式刪掉,只保留上排按鈕選單換顏色的程式


修改成員函式 onClick()
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.button_HotText: //連到熱門文章頁
                //changeTab(TAB_HOTTEXT);
                mViewPager.setCurrentItem(TAB_HOTTEXT);
                return;
            case R.id.button_BoardList: //連到熱門看板頁
                //changeTab(TAB_BOARDLIST);
                mViewPager.setCurrentItem(TAB_BOARDLIST);
                return;
            case R.id.button_BoardSearch: //連到搜尋看板頁
                //changeTab(TAB_BOARDSEARCH);
                mViewPager.setCurrentItem(TAB_BOARDSEARCH);
                return;
            default:
        }
    }
原本上排按鈕的點擊事件是執行 changeTab() 換頁
改成使用 mViewPager.setCurrentItem() 來換頁

換頁時會觸發 onPageSelected()
就會執行到 changeTab() 來更改上排按鈕的顏色了


要重整頁面的話,可以使用
    mViewPager.setAdapter(mAdapterViewPager);
    mViewPager.setCurrentItem(mTabSelect);
重新設定 Adapter 再跳至選擇的頁面即可


□ 問題解決記錄

fragment 中的 SwipeRefreshLayout 失效
→ 每個 fragment layout 中的 SwipeRefreshLayout 要使用不同的 id 名稱
   不然的話用 mContext.findViewById() 會抓不到

有時使用 mViewPager.setCurrentItem() 後會自動捲動到頁面最下方
→ fragment 中使用 listView.addFooterView(footerView) 時造成的
   改成 listView.addFooterView(footerView, null, false);
   設定第三個參數 isSelectable = false 即可

預載下一頁的畫面時,也會出現 ProgressDialog
→ 因為 ProgressDialog 是建立在 Activity 上的,任一個 Fragment 呼叫時都會顯示出來
   可以改成在每個 Fragment 中都放一個 ProgressBar 來顯示載入中圖示
   參考這篇 [AndroidStudio] 使用 ProgressBar 顯示載入中圖示 - KnucklesNote板 - Disp BBS


參考
https://github.com/codepath/android_guides/wiki/ViewPager-with-FragmentPagerAdapter

--
※ 作者: Knuckles 時間: 2017-01-12 00:37:03
※ 編輯: Knuckles 時間: 2017-01-15 21:32:32
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 3424 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇