Fragment的應用之底部導航欄的實現(二)之應用ViewPager

效果圖

底部導航欄(二).gif

什么是ViewPager

該文要講到的實際是在Fragment的應用之底部導航欄的實現(一)的基礎上應用了ViewPager。使得底部導航欄的切換有了滑動的效果,同時支持了頁面的手勢滑動切換。

ViewPager

ViewPager在很多App中都會有應用,那它到底干什么的?我以前也沒用過,不過專門學習了之后,覺得這個控件還是很好理解的,在我看來它其實和Listview這一類ViewGroup差不多,只不過它是橫向滑動的,而且通常情況下每一個item的寬度是屏幕的寬度,再通俗點說就是可以左右滑動切換顯示的View,且屏幕上同時只能看到一個item。具體能實現的效果就是上面效果圖所展示的那樣。

ViewPager的使用

既然ViewPager類似于ListView,那他的使用就應該也類似于它。所以ViewPager也有一個適配器,而且ViewPager通常會和Fragment搭配使用,官方也提供了FragmentPagerAdapter和FragmentStatePagerAdapter兩個適配器類供我們使用。關于ViewPager的使用可以有很多東西要寫,不過該文中只討論了它最基本的使用

布局

整體的布局基本上沿用上一篇文章demo的布局。不過在主界面布局上做了一定的修改。
之前是用一個FrameLayout來放置Fragment,而這里自然就要使用ViewPager來代替之前的FrameLayout。注意ViewPager是在V4擴展包當中的

<android.support.v4.view.ViewPager
        android:id="@+id/my_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/tab_linear">
</android.support.v4.view.ViewPager>

自定義Fragment

現在布局文件都準備好了,接下來就是定義要顯示的View也就是自定義的Fragment,為了更好的顯示滑動切換的效果,給每一個Fragment設置了不同的背景色。

public class FragmentTest extends Fragment{

    private String fragmentText;
    private int backColor;

    private TextView fragmentTextView;

    public FragmentTest(String fragmentText,int color) {
        this.fragmentText=fragmentText;
        this.backColor=color;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.test_fragment,container,false);
        RelativeLayout relativeLayout= (RelativeLayout) view.findViewById(R.id.fragment_relative_layout);
        fragmentTextView= (TextView) view.findViewById(R.id.fragment_text);
        relativeLayout.setBackgroundColor(backColor);
        fragmentTextView.setText(fragmentText);
        return view;
    }
}

自定義適配器

現在Fragment都已經準備好了,就相當于ListView中自定義的布局item準備好了,所以接下來就是要自定義ViewPager的適配器。讓它繼承自FragmentPagerAdapter。

重寫函數

自定義該適配器需要至少重寫兩個函數

  • 一個是public Fragment getItem(int position),重寫這個函數就是要根據索引顯示對應的Fragment到屏幕上;
  • 一個是public int getCount(),這個函數很顯然是返回ViewPager中所有View即Fragment的總數的。

構造器

另外還需要實現一個帶FragmentManager的構造器 ,用于初始化所有的Fragment
下面是自定義MyViewPagerAdapter

public class MyViewPagerAdapter extends FragmentPagerAdapter{

    private final int PAFER_NUM=4;
    private FragmentTest fragmentTest1;
    private FragmentTest fragmentTest2;
    private FragmentTest fragmentTest3;
    private FragmentTest fragmentTest4;

    public MyViewPagerAdapter(FragmentManager fm) {
        super(fm);
        fragmentTest1=new FragmentTest("Home", Color.rgb(34,139,34));
        fragmentTest2=new FragmentTest("List",Color.rgb(255,99,71));
        fragmentTest3=new FragmentTest("Polymer",Color.rgb(0,139,139));
        fragmentTest4=new FragmentTest("User",Color.rgb(139,0,139));
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment=null;
        switch (position){
            case MainActivity.PAGE_ONE:
                fragment=fragmentTest1;
                break;
            case MainActivity.PAGE_TWO:
                fragment=fragmentTest2;
                break;
            case MainActivity.PAGE_THREE:
                fragment=fragmentTest3;
                break;
            case MainActivity.PAGE_FOUR:
                fragment=fragmentTest4;
                break;
            default:
                break;
        }
        return fragment;
    }

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

可以看出ViewPager的適配器和ListView這種的適配器不一樣,ListView的數據是從構造器傳進來的,而ViewPager的適配器的數據源就是Fragment,所以它是直接在自定義適配器定義并初始化了所有的Fragment。

使用ViewPager

ViewPager的基本使用其實很簡單。

  • 首先用FindViewById初始化ViewPager的實例viewPager;
  • 調用自定義的MyViewPagerAdapter適配器得到一個適配器實例adapter,然后調用viewPager的setAdapter傳入該adapter,這樣ViewPager其實就已經準備好了;
  • 接下來還要給ViewPager添加頁面滑動的事件監聽,重寫onPageScrollStateChanged方法以處理手勢滑動要處理的邏輯;
  • 利用setCurrentItem方法給viewPager設置一個初始的Fragment;

具體的代碼:

public class MainActivity extends AppCompatActivity implements View.OnClickListener,ViewPager.OnPageChangeListener{

    LinearLayout homeLinear;

    LinearLayout listLinear;

    LinearLayout polyLinear;

    LinearLayout userLinear;

    private FragmentManager mfragmentManger;

    private ViewPager viewPager;

    private MyViewPagerAdapter myViewPagerAdapter;

    public static final int PAGE_ONE=0;
    public static final int PAGE_TWO=1;
    public static final int PAGE_THREE=2;
    public static final int PAGE_FOUR =3;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        homeLinear= (LinearLayout) findViewById(R.id.linear_home);
        listLinear= (LinearLayout) findViewById(R.id.linear_list);
        polyLinear= (LinearLayout) findViewById(R.id.linear_polymer);
        userLinear= (LinearLayout) findViewById(R.id.linear_user);
        viewPager= (ViewPager) findViewById(R.id.my_viewpager);
        homeLinear.setOnClickListener(this);
        listLinear.setOnClickListener(this);
        polyLinear.setOnClickListener(this);
        userLinear.setOnClickListener(this);
        viewPager.addOnPageChangeListener(this);
        myViewPagerAdapter=new MyViewPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myViewPagerAdapter);
        viewPager.setCurrentItem(PAGE_ONE);
        homeLinear.performClick();

    }

    @Override
    public void onClick(View view) {
        setAllFalse();
        switch (view.getId()){
            case R.id.linear_home:
                homeLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_ONE);
                break;
            case R.id.linear_list:
                listLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_TWO);
                break;
            case R.id.linear_polymer:
                polyLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_THREE);
                break;
            case R.id.linear_user:
                userLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_FOUR);
                break;
        }

    }


    private void setAllFalse() {
        homeLinear.setSelected(false);
        listLinear.setSelected(false);
        polyLinear.setSelected(false);
        userLinear.setSelected(false);
    }

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

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if(state==2){
            setAllFalse();
            switch (viewPager.getCurrentItem()){
                case PAGE_ONE:
                    homeLinear.setSelected(true);
                    break;
                case PAGE_TWO:
                    listLinear.setSelected(true);
                    break;
                case PAGE_THREE:
                    polyLinear.setSelected(true);
                    break;
                case PAGE_FOUR:
                    userLinear.setSelected(true);
            }
        }

    }
}

總結

本文主要是應用了ViewPager實現底部菜單導航,不過底部導航的方法和形式還有很多種,后續還會記錄其他的一些常用的方式。

歡迎批評指正,小弟感激不盡。

2017.4.12 22:45
806 實驗室

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容