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 实验室

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容