Android基础学习总结(七)——简单实现新闻选项卡滑动效果(CoordinatorLayout+AppBarLayout+Toolbar+TabLayout+ViewPager大合成)

引言

曾经看到网易、头条新闻就想自己实现一下效果,结果花费了不少时间,基础不牢,地动山摇,现在一步步深入学习Android后发现实现一下也不难,现在就简单记录下自己的实现思路和方法,供自己以后参考。

实现思路

首先能看到的应该是三个部分Toolbar+TabLayout+ViewPager,再细分下去,ViewPager包含了一个Recyclerview,里面有很多itemview来显示和滑动,往大了看,还有AppBarLayout包裹Toolbar和TabLayout作为顶部栏,最后整个包上CoordinatorLayout协调其所包裹的子view的手势操作的,大致就酱,具体实现下面一步步看。

关于ViewPager

1.一个页面切换的组件,可以往里面填充多个View,可以通过触摸屏幕左右滑动来切换不同的View,官方连接ViewPager ,和大多数情况一样需要一个Adapter适配器,将要显示的View和ViewPager绑定,由于官方建议使用Fragment来填充ViewPager这样方便生成与管理生命周期等等,一般主要使用FragmentPageAdapter,它的缓存机制是缓存当前页,前一页和后一页共3页这样。
2.使用PagerAdapter的重要方法:

  • getCount( ):获得viewpager中有多少个view
  • destroyItem( ):移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。
  • instantiateItem( ):①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来 ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,当然你也可以自定义自己的key,但是key和每个view要一一对应的关系
  • isViewFromObject( ):判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写return view == object;就可以了,至于为什么要这样讲起来比较复杂,后面有机会进行了解吧,貌似是ViewPager中有个存储view状态信息的ArrayList,根据View取出对应信息的吧!

关于AppBarLayout

AppBarLayout控件,它是继承LinerLayout实现的一个ViewGroup容器组件,是为了Material Design而设计的App Bar,支持手势滑动操作。
默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。
使用方式非常简单,直接在布局文件中包裹想要作为顶部栏的控件,例如Toolbar和TabLayout.

关于CoordinatorLayout

CoordinatorLayout是一个增强型的FrameLayout,它的作用就是用来协调其所包裹的子view的手势操作的.
为了达到手势动画效果,我们必须做如下设置,通过app:layout_scrollFlags=”scroll|enterAlways” 属性来确定哪个组件是可滑动的.关于layout_scrollFlags的属性设置,在布局文件中描述,这里就不多说了.
同时,为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如: RecyclerView,NestedScrollView(ListView,ScrollView不支持)具有滑动效果的组件。并且还需要给这些组件设置如下属性来告诉CoordinatorLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
该组件是带有滑动行为的组件,然后CoordinatorLayout在接受到滑动时会通知AppBarLayout中可滑动的Toolbar可以滑出屏幕了。

关于TabLayout

TabLayout是design库提供的控件,可以方便的使用指示器,功能类似ViewPagerIndicator.
使用非常方便,Android Studio只需要在gradle中引入design即可使用.
来看看配合ViewPager的使用方式,实现如下效果图:
Android基础学习总结(七)——简单实现新闻选项卡滑动效果(CoordinatorLayout+AppBarLayout+Toolbar+TabLayout+ViewPager大合成)_第1张图片

  • app:tabGravity=”center” 对齐方式,可选fill和center
  • app:tabIndicatorColor=”@color/colorAccent” 设置tab下划线的颜色
  • app:tabMode=”scrollable” scrollable是可以横行滚动,fixed是指固定个数
  • app:tabSelectedTextColor=”@color/colorPrimaryDark” 选择tab的文本颜色
  • app:tabTextColor=”@color/colorPrimary” 普通tab字体颜色
    //1.支持添加字符串文本tab 
    //tabLayout.addTab(tabLayout.newTab().setText("TAB" + i));

    //2.支持添加图片tab 
    //tabLayout.addTab(tabLayout.newTab().setIcon(R.mipmap.ic_launcher));

    //3.支持添加View
    View tabView = View.inflate(TabLayoutOnlyActivity.this, R.layout.view_tab, null);
    ((TextView)tabView.findViewById(R.id.tv_title)).setText("TAB" + i);
    tabLayout.addTab(tabLayout.newTab().setCustomView(tabView));

关于Toolbar和Recyclerview

这部分可以参考我之前的文章(✿◡‿◡)
Toolbar
Recyclerview

开始大合成

1.使用之前,别忘了在gradle中引入Material Design支持包

  compile 'com.android.support:design:25.3.1'

另外,由于使用了Toolbar需要修改style中的ActionBar

   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

2.直接看完整布局activity_main.xml:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="study.test6.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#c0f9d0"
        app:layout_scrollFlags="scroll|enterAlways"
        />
        
   <android.support.design.widget.TabLayout
       android:id="@+id/tablayout"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:tabGravity="center"
       android:background="#c0f9d0"
       app:tabIndicatorColor="@color/colorAccent"
       app:tabMode="scrollable"
       app:tabSelectedTextColor="@color/colorPrimaryDark"
       app:tabTextColor="@color/colorPrimary"
       />
    android.support.design.widget.AppBarLayout>
    
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
       >
    android.support.v4.view.ViewPager>
android.support.design.widget.CoordinatorLayout>

3.fragment.xml
fragment的布局就简单包含一个RecyclerView

"http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    .support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

item.xml
这个是用来显示的item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/list_item">
    <ImageView
        android:id="@+id/image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        />
    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
LinearLayout>

4.接着给ViewPager弄个适配器
mFragmentPagerAdapter.java

public class mFragmentPagerAdapter extends FragmentPagerAdapter {
    private MyFragment myFragment =null;
    public mFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int position) {
        myFragment =new MyFragment();
       //这里可以根据位置返回相应的Fragment,例如娱乐,体育,新闻等等单独弄个Fragment
        myFragment.setTitle("This is "+position);
        return myFragment;
    }
    @Override       
    public CharSequence getPageTitle(int position) {     //返回Tab名字
        String name ="Tag"+position;
    return  name;
    }
    @Override
    public int getCount() {
        return 6;           //这里就简单返回个固定数字,可以根据需要返回Tab的数量
    }

}

5.配置好RecyclerAdapter
主要就是自定义个MyViewHolder,具体配置看代码:
RecyclerAdapter.java

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
    static class MyViewHolder extends RecyclerView.ViewHolder
    {
        private TextView textView;
        private ImageView   imageView;
        public MyViewHolder(View itemview)
        {
            super(itemview);
            textView= (TextView) itemview.findViewById(R.id.content);
            imageView= (ImageView) itemview.findViewById(R.id.image);

        }
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
        MyViewHolder viewHolder =new MyViewHolder(view);//实例化viewholder
        return viewHolder;
    }
    @Override
    public void onBindViewHolder(MyViewHolder myViewHolder, int position) {
        myViewHolder.textView.setText("Test"+position);
        myViewHolder.imageView.setImageResource(R.drawable.back);
    }
    @Override
    public int getItemCount() {
        return 15;          //返回个每页的数量
    }
}

6.自定义MyFragment

public class MyFragment extends Fragment {

    private String Title;   //可以根据这个修改item里面的内容
    private RecyclerView recyclerView;
    public void setTitle(String title) {
        Title = title;
    }

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
    //拿到fragment的view,之后实例化recyclerView,然后创建适配器,再挂上recyclerView
        View view =inflater.inflate(R.layout.fragment,container,false);
        recyclerView= (RecyclerView) view.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        RecyclerAdapter recyclerAdapter=new RecyclerAdapter();
        recyclerView.setAdapter(recyclerAdapter);

        return view;
    }
}

7.最后是主代码MainActivity.java
主要就是初始化布局,以及关联viewPager和tablayout并且配置好相应的适配器


public class MainActivity extends AppCompatActivity {

   private TabLayout tabLayout;
   private ViewPager viewPager;
   private mFragmentPagerAdapter mFragPAdapter;
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        tabLayout = (TabLayout) findViewById(R.id.tablayout);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        toolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);
        mFragPAdapter=new mFragmentPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mFragPAdapter);
        tabLayout.setupWithViewPager(viewPager);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu,menu);
        return true;
    }
}

最终效果

你可能感兴趣的:(Android)