Android中MaterialDesign的使用,以及实现仿网易新闻客户端的UI效果(三)

前两次我们说了MaterialDesign中,Toolbar,DrawerLayout和NavigationView组成的Activity界面,下面我们来说说TabLayout,ViewPager,Fragment和RecyclerView组成的带有标签的界面,先来看看效果:
这里写图片描述
如图,Toolbar下多了一行标签,点击标签就会跳到对应的页面。我们先来说说每个控件负责显示什么以及它的范围:
1.TabLayout:负责标签行,区域就在Toolbar下的蓝色区域。
2.ViewPager:负责加载动态加载每个标签对应的Fragment。区域是TabLayout下所有的区域。
3.Fragment:负责加载对应的RecyclerView。由ViewPager加载到Activity中。区域也是TabLayout下 所有的区域。
4.RecyclerView:负责显示数据。图中的图片加字符串,就是由RecyclerView负责显示以及加载的。
在代码中,TabLayout和ViewPager会创建联系,ViewPager和Fragment会创建联系,Fragment和RecyclerView会创建联系。

总结就是:TabLayout会随着ViewPager的滑动,而切换标签,同样,ViewPager会随着TabLayout标签的选择而滑动到对应的页面。ViewPager会随着标签的不同加载对应的Fragment,而Fragment中则会加载RecyclerView。下面我们来看看代码。先来看看布局文件我们接着在activity_main的基础上进行修改:

<android.support.v4.widget.DrawerLayout
    >

    <LinearLayout

        >

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
           />

            <android.support.design.widget.TabLayout
                android:id="@+id/main_tab_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabTextColor="#fff"
                app:tabMode="scrollable"/>
        </android.support.design.widget.AppBarLayout>

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

    </LinearLayout>


    <android.support.design.widget.NavigationView

        />


</android.support.v4.widget.DrawerLayout>

方便起见,我把前面定义过的控件都只留下标签,里面的属性都删减了,我们重点要看的是TabLayout和ViewPager还有一个AppBarLayout的部分。
1.AppBarLayout:design包下的控件,其实就是一个垂直方向的LinearLayout,但是其内部做了很多滚动事件的封装。而且包含了一些MaterialDesign的设计理念。这节我们不会说到它的具体作用,暂且先把她理解为一个垂直方向的LinearLayout,其作用就是将ToolBar和TabLayout包裹成一个整体。
2.TabLayout:design包下的控件,作用上面已经说过了,我们主要来看看它的属性app:tabMode,这个属性有两个值可选,分别是scrollable和fixed。这里我们指定的是scrollable,顾名思义,就是可滑动的,那么另外的fixed就是固定的。这个属性是用来控制TabLayout的标签是否可以滑动,当我们的标签比较多时就选择scrollable,比较少时就选择fixed。不同之处我们来看看图,如下:
这里写图片描述
上面的状态时我们将tabMode的属性值改成fixed,可以看到标签栏部分的标签显示不完整,因为,当选择fixed即是不可滑动,那么TabLayout又要将所有标签显示出来,就会出现图中的情况,标签都被压缩的不成样子,所以,标签很多的时候,我们需要把该属性的值设置为scrollable。
3.ViewPager:ViewPager就没啥特别的属性了,只是要注意,它并不是AppBarLayout的子控件,他在TabLayout的外面。

ok,布局文件就是这样,并没有什么复杂的,我们接下来看看代码,在这之前我们需要准备一下Fragment和RecyclerView,这里我们只贴Fragment的代码,RecyclerView在前面的博文中已经很详细的说过了,如果有疑问可以去前面的博文看看。(注意,这里的RecyclerView显示的数据我在定义RecyclerView的布局文件的时候都已经直接指定了(ImageView指定了src,TextView指定了text)。所以里面的每一个子项的数据都是一样的)。下面我们来看看Fragment的代码:

public class RecyclerViewFragment extends Fragment {

    private RecyclerView view;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayout.VERTICAL,false));
        view.setAdapter(new MyAdapter());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        view =(RecyclerView) inflater.inflate(R.layout.layout,container,false);
        return view;

    }
}

如上,定义Fragment需要继承Fragment - -,注意继承的Fragment是support包下的。这里我们重写了两个方法,分别是onCreateView和onActivityCreate。我们来看看这两个方法的作用:
1.onCreateView:看代码中,我们可以知道这个方法中有一个参数:LayoutInflater,那么很明显,这个方法一般是用来加载Fragment布局的。前面说过,我们的Fragment中就只有一个RecyclerView,那么代码中加载的布局文件R.layout.layout也就只是一个RecyclerView。
2.onActivityCreate:这个方法,在确保与Fragment关联的Activity被创建时调用,在这个方法里,我们为RecyclerView设置了LinearLayoutManager和Adapter,也就是在这,我们为Fragment加载了RecyclerView。

Fragment我们定义好了,接着我们来看看MainActivity中的代码:

public class MainActivity extends AppCompatActivity {

  *****************省略上两节的代码*******************

    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private List<String> titleList;
    private List<RecyclerViewFragment> mFragmentList;

    private void initView() {
        //找到控件
        mTabLayout = findViewById(R.id.main_tab_layout);
        mViewPager = findViewById(R.id.main_view_pager);
        initTab();

    }

    private void initTab() {
        //这里创建两个List一个用来存储每个Tab的标题,一个用来存储Fragment
        titleList = new ArrayList<>();
        mFragmentList = new ArrayList<>();

        //为titleList添加数据
        titleList.add("时事");
        titleList.add("国内");
        titleList.add("国际");
        titleList.add("时政");
        titleList.add("体育");
        titleList.add("娱乐");
        titleList.add("头条");
        titleList.add("社会");
        titleList.add("时事");
        titleList.add("国内");
        titleList.add("国际");
        titleList.add("时政");
        titleList.add("体育");
        titleList.add("娱乐");
        titleList.add("头条");
        titleList.add("社会");

        //遍历titleList中的数据,并创建对应数量的Tab添加到TabLayout中
        for(int i = 0;i<titleList.size();i++){
            //创建Tab
            TabLayout.Tab tab = mTabLayout.newTab();
            //为Tab添加标题
            tab.setText(titleList.get(i));
            //将定义好的Tab添加到TabLayout中
            mTabLayout.addTab(tab);

        }

        RecyclerViewFragment fragment;
        //这里创建我们定义好的RecyclerViewFragment,并添加到mFragmentList中
        for (int i = 0;i<titleList.size();i++){

            fragment = new RecyclerViewFragment();
            mFragmentList.add(fragment);

        }

        //注释1 这是我们自己创建的 FragmentStatePagerAdapter
        MyFragmentAdapter fragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),titleList,mFragmentList);

        //将定义好的MyFragmentAdapter和viewPager关联 注释2
        mViewPager.setAdapter(fragmentAdapter);
        //这里关联TabLayout和ViewPager 注释3
        mTabLayout.setupWithViewPager(mViewPager);


    }

}

接着我们贴出MyFragmentAdapter的代码,如下:

public class MyFragmentAdapter extends FragmentStatePagerAdapter {

    private List<String> mTitleList;
    private List<RecyclerViewFragment> mFragmentList;

    public MyFragmentAdapter(FragmentManager fm, List<String> titleList,List<RecyclerViewFragment> fragmentList) {
        super(fm);
        mTitleList = titleList;
        mFragmentList = fragmentList;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mTitleList.get(position);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }
}

如上,我们先来说说MyFragmentAdapter这个类,这个类是继承自support.v4包FragmentStatePagerAdapter的。这里重写了三个普通方法和一个构造方法,我们先来看看构造方法。
这个构造方法有三个参数,第一个FragmentManager是固定的,后面两个List类型的参数是我们自己定义了,用来获取数据的。
我们再来看看三个普通方法,分别是getPageTitle,getItem和getCount:
1.getPageTitle:返回值类型是CharSequence,也就是也就是字符串。这里我们根据参数position返回mTitleList中对应的值。
2.getItem:返回值类型是Fragment,很明显这里我们只要根据参数的position返回mFragmentList中对应的RecyclerViewFragment即可。
3.getCount:返回值类型是int,就是返回子项的数量,随便返回一个List的size就可以。

ok,MyFragmentAdapter很简单,我们回到MainActivity代码中,来看看代码中标记的3个注释:
1.注释1:创建MyFragmentAdapter,将我们定义的titleList和mFragmentList传进去,需要注意的是,这里我们用的Fragment是继承support库的,所以获取的FragmentManager需要使用getSupportFragmentManager这个方法。
2.注释2:将创建的MyFragmentAdapter和viewPager关联,使ViewPager能获取对应position下的title和fragment。
3.注释3:将ViewPager和Tablayout关联起来,使ViewPager能响应TabLayout中Tab的切换,从而切换Fragment显示Tab标签对应的数据。同样,使TabLayout能响应Viewpager的滑动,从而更换Tab标签。

ok,这次就说那么多,下次我们说说Toolbar的折叠。

本人菜鸟,不对之处,请各路大神指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值