Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar_CoordinatorLayout

好了,现在来讲讲上图是怎么实现的吧!讲之前先讲讲几个控件:

  • CoordinatorLayout 

该控件也是Design包下的一个控件,然而这个控件可以被称为Design包中最复杂、功能最强大的控件: CoordinatorLayout。为什么这样说呢?原因是:它是组织它众多子view之间互相协作的一个ViewGroup。


CoordinatorLayout 的神奇之处就在于 BehaviorCoordinatorLayout 所做的事情就是当成一个通信的桥梁,连接不同的view,使用 Behavior 对象进行通信。


比如:在CoordinatorLayout中使用AppBarLayout,如果AppBarLayout的子View(如ToolBar、TabLayout)标记了app:layout_scrollFlags滚动事件,那么在CoordinatorLayout布局里其它标记了app:layout_behavior的子View(LinearLayout、RecyclerView、NestedScrollView等)就能够响应(如ToolBar、TabLayout)控件被标记的滚动事件。如:


[html]  view plain copy





1. <android.support.design.widget.CoordinatorLayout  
2. xmlns:android="http://schemas.android.com/apk/res/android"  
3. xmlns:app="http://schemas.android.com/apk/res-auto"  
4. android:id="@+id/coordinator_layout"  
5. android:layout_width="match_parent"  
6. android:layout_height="match_parent">  
7.   
8. <android.support.design.widget.AppBarLayout  
9. android:id="@+id/appbar_layout"  
10. android:layout_width="match_parent"  
11. android:layout_height="wrap_content"  
12. android:fitsSystemWindows="true">  
13. <android.support.v7.widget.Toolbar  
14. android:id="@+id/toolBar"  
15. android:layout_width="match_parent"  
16. android:layout_height="?attr/actionBarSize"  
17. android:background="#30469b"  
18. app:layout_scrollFlags="scroll|enterAlways" />  
19. <android.support.design.widget.TabLayout  
20.             ......  
21. />  
22. </android.support.design.widget.AppBarLayout>  
23.   
24. <LinearLayout  
25. android:layout_width="match_parent"  
26. android:layout_height="match_parent"  
27. android:orientation="vertical"  
28. android:scrollbars="none"  
29. app:layout_behavior="@string/appbar_scrolling_view_behavior">  
30. <!-- content view .....-->  
31. </LinearLayout>  
32.   
33. </android.support.design.widget.CoordinatorLayout>




上面这段代码中,ToolBar标记了layout_scrollFlags滚动事件,那么当LinearLayout滚动时便可触发ToolBar中的layout_scrollFlags效果。即往上滑动隐藏ToolBar,下滑出现ToolBar,而不会隐藏TabLayout,因为TabLayout没有标记scrollFlags事件,相反,如果TabLayout也标记了ScrollFlags事件,那么LinearLayout的下滑时ToolBar和TabLayout都会隐藏了。


layout_scrollFlags中的几个值:


scroll: 所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。

enterAlways:这个flag让任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。

enterAlwaysCollapsed:当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。 

exitUntilCollapsed:滚动退出屏幕,最后折叠在顶端。




【注意】: 设置了layout_scrollFlags标志的View必须在没有设置的View的之前定义,这样可以确保设置过的View都从上面移出, 只留下那些固定的View在下面。





  • TabLayout

说到TabLayout,就是实现多个Tab之间的切换,不过Google在Design library新推出的TabLayout既实现了固定的选项卡 - (Tab的宽度平均分配),也实现了可滚动的选项卡 - (Tab宽度不固定,同时可以横向滚动),还实现了所有Tab居中显示。它还有一个重要作用就是结合ViewPager来实现多个Tab之间的切换。



来看看TabLayout的三种实现方式:



  • 固定的Tab,根据TabLayout的宽度适配

Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar_android_02



  • 固定的Tab,在TabLayout中居中显示

Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar_android_03



  • 可滑动的Tab

Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar_AppBarLayout_04






要实现上述效果,首先就需要加入TabLayout:



[html]  view plain copy





1. <android.support.design.widget.TabLayout  
2. android:id="@+id/tabLayout"  
3. android:layout_width="match_parent"  
4. android:layout_height="wrap_content"  
5. android:background="#30469b"  
6. app:tabGravity="fill"  
7. app:tabMode="fixed"  
8. app:tabSelectedTextColor="#ff0000"  
9. app:tabTextColor="#ffffff" />



  • tabGravity  —Tab的重心,有填充和居中两个值,为别为fill和center。
  • tabMode  —Tab的模式,有固定和滚动两个模式,分别为 fixed 和 scrollable。
  • tabTextColor  —设置默认状态下Tab上字体的颜色。
  • tabSelectedTextColor  —设置选中状态下Tab上字体的颜色。

然后在代码中动态添加Tab:



[java]  view plain copy





    1. TabLayout mTabLayout = (TabLayout) findViewById(R.id.tabLayout);  
    2. "TabOne"));//给TabLayout添加Tab  
    3. "TabTwo"));  
    4. "TabThree"));  
    5. //给TabLayout设置关联ViewPager,如果设置了ViewPager,那么ViewPagerAdapter中的getPageTitle()方法返回的就是Tab上的标题



    [java]  view plain copy





    1. ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);  
    2. new MyViewPagerAdapter(getSupportFragmentManager());  
    3. "TabOne");//添加Fragment  
    4. "TabTwo");  
    5. "TabThree");  
    6. //设置适配器



    MyViewPagerAdapter.java



    [java]  view plain copy





      1. public class MyViewPagerAdapter extends FragmentPagerAdapter {  
      2. private final List<Fragment> mFragments = new ArrayList<>();//添加的Fragment的集合  
      3. private final List<String> mFragmentsTitles = new ArrayList<>();//每个Fragment对应的title的集合  
      4. public MyViewPagerAdapter(FragmentManager fm) {  
      5. super(fm);  
      6.     }  
      7. /**
      8.      * @param fragment      添加Fragment
      9.      * @param fragmentTitle Fragment的标题,即TabLayout中对应Tab的标题
      10.      */  
      11. public void addFragment(Fragment fragment, String fragmentTitle) {  
      12.         mFragments.add(fragment);  
      13.         mFragmentsTitles.add(fragmentTitle);  
      14.     }  
      15.   
      16. @Override  
      17. public Fragment getItem(int position) {  
      18. //得到对应position的Fragment  
      19. return mFragments.get(position);  
      20.     }  
      21.   
      22. @Override  
      23. public int getCount() {  
      24. //返回Fragment的数量  
      25. return mFragments.size();  
      26.     }  
      27.   
      28. @Override  
      29. public CharSequence getPageTitle(int position) {  
      30. //得到对应position的Fragment的title  
      31. return mFragmentsTitles.get(position);  
      32.     }  
      33. }






      上面两个控件如果明白怎么用了,那么这个效果就很简单了,我就直接贴代码了。。。



      主布局:activity_main.xml



      [html]  view plain copy





      1. <android.support.design.widget.CoordinatorLayout  
      2. xmlns:android="http://schemas.android.com/apk/res/android"  
      3. xmlns:app="http://schemas.android.com/apk/res-auto"  
      4. android:id="@+id/coordinator_layout"  
      5. android:layout_width="match_parent"  
      6. android:layout_height="match_parent">  
      7.   
      8. <android.support.design.widget.AppBarLayout  
      9. android:layout_width="match_parent"  
      10. android:layout_height="wrap_content"  
      11. android:fitsSystemWindows="true">  
      12.   
      13. <android.support.v7.widget.Toolbar  
      14. android:id="@+id/toolBar"  
      15. android:layout_width="match_parent"  
      16. android:layout_height="?attr/actionBarSize"  
      17. android:background="#30469b"  
      18. app:layout_scrollFlags="scroll|enterAlways" />  
      19.   
      20. <android.support.design.widget.TabLayout  
      21. android:id="@+id/tabLayout"  
      22. android:layout_width="match_parent"  
      23. android:layout_height="wrap_content"  
      24. android:background="#30469b"  
      25. app:tabGravity="fill"  
      26. app:tabMode="fixed"  
      27. app:tabSelectedTextColor="#ff0000"  
      28. app:tabTextColor="#ffffff" />  
      29. </android.support.design.widget.AppBarLayout>  
      30.   
      31. <LinearLayout  
      32. android:layout_width="match_parent"  
      33. android:layout_height="match_parent"  
      34. android:orientation="vertical"  
      35. android:scrollbars="none"  
      36. app:layout_behavior="@string/appbar_scrolling_view_behavior">  
      37. <android.support.v4.view.ViewPager  
      38. android:id="@+id/viewpager"  
      39. android:layout_width="match_parent"  
      40. android:layout_height="match_parent" />  
      41. </LinearLayout>  
      42.   
      43. </android.support.design.widget.CoordinatorLayout>



      [java]  view plain copy





      1. public class MainActivity extends ActionBarActivity {  
      2. @Override  
      3. protected void onCreate(Bundle savedInstanceState) {  
      4. super.onCreate(savedInstanceState);  
      5.         setContentView(R.layout.activity_main);  
      6.   
      7.         Toolbar mToolbar = (Toolbar) findViewById(R.id.toolBar);  
      8. //设置ToolBar的titl颜色  
      9.         setSupportActionBar(mToolbar);  
      10.   
      11.         ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);  
      12. new MyViewPagerAdapter(getSupportFragmentManager());  
      13. "TabOne");//添加Fragment  
      14. "TabTwo");  
      15. "TabThree");  
      16. //设置适配器  
      17.   
      18.         TabLayout mTabLayout = (TabLayout) findViewById(R.id.tabLayout);  
      19. "TabOne"));//给TabLayout添加Tab  
      20. "TabTwo"));  
      21. "TabThree"));  
      22. //给TabLayout设置关联ViewPager,如果设置了ViewPager,那么ViewPagerAdapter中的getPageTitle()方法返回的就是Tab上的标题  
      23.     }  
      24. }