转自:

CollapsingToolbarLayout的使用

注意:使用前需要添加Design依赖包,使用toolbar时需要隐藏标题头

CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。

NestedScrollView:它是support-v4包提供的控件,继承至FrameLayout, 并实现了NestedScrollingParent,NestedScrollingChild, ScrollingView接口.

它的作用类似于Android.widget.ScrollView,不同点在于NestedScrollView支持嵌套滑动.

需实现的布局:

最外层是CoorinatorLayout,然后里面包含了AppBarlayout和NestedScrollView

AppBarLayout里包含了CollspsingToolbar和Tableyout,它的作用是可以将所有的子控件都当成一个整体

CollapsingToolbarLayout里面则包含了一个ImageView和ToolBar作为伸缩的区域。

1. AppBarLayout的子布局有5种滚动标识(layout_scrollFlags属性):

  • scroll:将此布局和滚动时间关联。这个标识要设置在其他标识之前,没有这个标识则布局不会滚动且其他标识设置无效。
  • enterAlways:任何向下滚动操作都会使此布局可见。这个标识通常被称为“快速返回”模式。
  • enterAlwaysCollapsed:假设你定义了一个最小高度(minHeight)同时enterAlways也定义了,那么view将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。
  • exitUntilCollapsed:当你定义了一个minHeight,此布局将在滚动到达这个最小高度的时候折叠。
  • snap:当一个滚动事件结束,如果视图是部分可见的,那么它将被滚动到收缩或展开。例如,如果视图只有底部25%显示,它将折叠。相反,如果它的底部75%可见,那么它将完全展开。

  实践证明,scroll和enterAlwaysCollapsed,scroll和exitUntilCollapsed使用时效果无阴影,scroll和enterAlways配合使用时,效果有阴影。

2.CollapsingToolbarLayout中通过layout_collapseMode属性来指定其内部的子控件是折叠还是固定在屏幕上方。

  1. <!-- layout_collapseMode(折叠模式)-有两个值:
  2. 1.parallax:在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,
  3. 实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用。如果不想实现联动效果,可以设置为0,效果就和scrollview一样了
  4. 2.pin - 当CollapsingToolbarLayout完全收缩后,Toolbar还可以固定在屏幕上。
  5. -->

xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. xmlns:app="http://schemas.android.com/apk/res-auto"
  7. android:orientation="vertical"
  8. tools:context="fanggao.qf.collapsingtoolbarlayout.MainActivity">
  9. <!-- android:fitsSystemWindow = "true" 表示整个布局展示是整个屏幕出去状态栏,标题栏和导航栏剩下的区域-->
  10. <android.support.design.widget.AppBarLayout
  11. android:id="@+id/layout_appbar"
  12. android:layout_width="match_parent"
  13. android:layout_height = "wrap_content"
  14. >
  15. <!--
  16. app:expandedTitleMarginStart="10dp"
  17. 设置扩张时候(还没有收缩时)title离屏幕左边的距离
  18.  
  19. app:contentScrim="?attr/colorPrimary"
  20. 设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色
  21. -->
  22. <android.support.design.widget.CollapsingToolbarLayout
  23. android:id="@+id/ctb"
  24. android:layout_width="match_parent"
  25. android:layout_height="250dp"
  26. android:fitsSystemWindows="true"
  27. app:contentScrim="?attr/colorPrimary"
  28. app:expandedTitleMarginStart="10dp"
  29. app:layout_scrollFlags="scroll|exitUntilCollapsed">
  30.  
  31. <ImageView
  32. android:id="@+id/image"
  33. android:layout_width="match_parent"
  34. android:layout_height="match_parent"
  35. android:scaleType="centerCrop"
  36. app:layout_collapseMode="parallax"
  37. android:src = "@drawable/cat"
  38. />
  39. <!--标题-->
  40. <android.support.v7.widget.Toolbar
  41. android:id="@+id/toolbar"
  42. android:layout_width="match_parent"
  43. android:layout_height="30dp"
  44. app:layout_collapseMode="pin"
  45. app:title="Toolbar"/>
  46. </android.support.design.widget.CollapsingToolbarLayout>
  47. <!--选项卡-->
  48. <android.support.design.widget.TabLayout
  49. android:id="@+id/tabLayout"
  50. android:layout_width="match_parent"
  51. android:layout_height="wrap_content"
  52. app:tabIndicatorColor="@color/colorAccent"
  53. app:tabMode="scrollable"
  54. app:tabSelectedTextColor="@color/colorAccent"
  55. app:tabTextColor="@android:color/black"/>
  56.  
  57. </android.support.design.widget.AppBarLayout>
  58. <android.support.v4.widget.NestedScrollView
  59. android:id="@+id/nestedScrollView"
  60. android:layout_width="match_parent"
  61. android:layout_height="match_parent"
  62. android:fillViewport="true"
  63. app:layout_behavior="@string/appbar_scrolling_view_behavior">
  64.  
  65. <android.support.v4.view.ViewPager
  66. android:id="@+id/viewPager"
  67. android:layout_width="match_parent"
  68. android:layout_height="wrap_content"/>
  69. </android.support.v4.widget.NestedScrollView>
  70.  
  71. </android.support.design.widget.CoordinatorLayout>

主程序:

  1. public class MainActivity extends AppCompatActivity {
  2. private Toolbar toolbar;
  3. private ImageView image;
  4. private ViewPager viewpager;
  5. private TabLayout tabLayout;
  6. private CollapsingToolbarLayout collapsingToolbarLayout;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. initView();
  12. initData();
  13. }
  14. private void initData() {
  15. toolbar.setLogo(R.mipmap.ic_launcher);
  16. setSupportActionBar(toolbar);
  17. //设置返回按钮
  18. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  19. //设置收缩展开toolbar字体颜色
  20. collapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);
  21. collapsingToolbarLayout.setCollapsedTitleTextColor(Color.BLACK);
  22.  
  23. //设置tablayout与viewPager
  24. viewpager.setAdapter(new TestViewPageAdapter());
  25. tabLayout.setupWithViewPager(viewpager);
  26. }
  27. private void initView() {
  28. toolbar = (Toolbar) findViewById(R.id.toolbar);
  29. image = (ImageView) findViewById(R.id.image);
  30. viewpager = (ViewPager) findViewById(R.id.viewPager);
  31. tabLayout = (TabLayout) findViewById(R.id.tabLayout);
  32. collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.ctb);
  33. }
  34. class TestViewPageAdapter extends PagerAdapter{
  35. @Override
  36. public Object instantiateItem(ViewGroup container, int position) {
  37. TextView textView = new TextView(MainActivity.this);
  38. textView.setGravity(Gravity.CENTER);
  39. textView.setText("pager "+(position+1));
  40. textView.setTextSize(30);
  41. textView.setTextColor(Color.BLUE);
  42. container.addView(textView);
  43. return textView;
  44. }
  45. @Override
  46. public void destroyItem(ViewGroup container, int position, Object object) {
  47. container.removeView((View)object);
  48. }
  49. @Override
  50. public int getCount() {
  51. return 5;
  52. }
  53. @Override
  54. public boolean isViewFromObject(View view, Object object) {
  55. return view == object;
  56. }
  57. /*获得标题*/
  58. /*该方法必须写,不然tablayout不能显示标题*/
  59. @Override
  60. public CharSequence getPageTitle(int position) {
  61. return "TAB"+(position+1);
  62. }
  63. }
  64. }

效果:

滑动前

向下滑动后:

如果有viewpager嵌套fragment的场景,可以在fragment的根布局中加上NestedScrollView,这样就不会产生滑动冲突事件。如果使用的是ScrollView,会导致上下2个分离,CollapsingToolbarLayout未滑动时,scrollview也可以滑动(不支持嵌套滑动),这样就跟实际需求背离了。

NestedScrollView参考资料:

https://www.jianshu.com/p/f55abc60a879

add:

如何监听CollapsingToolbarLayout的展开与折叠?

这里我们使用官方提供的AppBarLayout.OnOffsetChangedListener就可以实现了,不过封装下效果更好。代码如下。

  1. import com.google.android.material.appbar.AppBarLayout
  2.  
  3. abstract class AppBarStateChangeListener : AppBarLayout.OnOffsetChangedListener {
  4. private var mCurrentState = State.IDLE
  5.  
  6. enum class State {
  7. EXPANDED,
  8. COLLAPSED,
  9. IDLE
  10. }
  11.  
  12. override fun onOffsetChanged(appBarLayout: AppBarLayout?, i: Int) {
  13. appBarLayout?.let {
  14. if (i == 0) {
  15. if (mCurrentState != State.EXPANDED) {
  16. onStateChanged(it, State.EXPANDED)
  17. }
  18. mCurrentState = State.EXPANDED
  19. } else if (Math.abs(i) >= it.totalScrollRange) {
  20. if (mCurrentState != State.COLLAPSED) {
  21. onStateChanged(it, State.COLLAPSED)
  22. }
  23. mCurrentState = State.COLLAPSED
  24. } else {
  25. if (mCurrentState != State.IDLE) {
  26. onStateChanged(it, State.IDLE)
  27. }
  28. mCurrentState = State.IDLE
  29. }
  30. }
  31. }
  32.  
  33. abstract fun onStateChanged(appBarLayout: AppBarLayout?, state: State)
  34. }

使用:

  1. appbar_layout.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
  2. override fun onStateChanged(appBarLayout: AppBarLayout?, state: State) {
  3. if( state == State.EXPANDED ) {
  4. //展开状态
  5.  
  6. }else if(state == State.COLLAPSED){
  7. //折叠状态
  8. }else{
  9. //中间状态
  10. }
  11. }
  12. })

FAQ:

1.CoordinatorLayout中的recyclerview下拉刷新卡顿,当从下往上快速滑动时,每次需要等待几秒才能刷新,怎么解决?

  当recyclerview快速滑动时,不能触发下拉刷新,这是因为onSrollStateChanged()回调没有及时调用,当快速滑动时,会调用

  1. SCROLL_STATE_SETTLING(快速滑动)状态,该状态等到fling结束才会调用onSrollStateChanged()方法改变为SCROLL_STATE_IDLE(停止)状态(大概时间为2-3秒)。
  1.  
  1. recycleviewCars.addOnScrollListener(new RecyclerView.OnScrollListener() {
  2. @Override
  3. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  4. super.onScrollStateChanged(recyclerView, newState);
  5. if(newState == RecyclerView.SCROLL_STATE_SETTLING){
  6. recycleviewCars.stopScroll();
  7. }
  8. }
  9. });
  1.  

  

安卓Design包之CollapsingToolbarLayout(可折叠的工具栏布局)的简单使用的更多相关文章

  1. 安卓Design包之Toolbar控件的使用

    转自:ToolBar的使用 ToolBar的出现是为了替换之前的ActionBar的各种不灵活使用方式,相反,ToolBar的使用变得非常灵活,因为它可以让我们自由往里面添加子控件.低版本要使用的话, ...

  2. 安卓Design包之TabLayout控件的使用

    转自: 安卓Design包之TabLayout控件的简单使用 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android ...

  3. 安卓Design包之AppBar和Toolbar的联用

    前面讲了Design包的的CoordinatorLayout和SnackBar的混用,现在继续理解Design包的AppBar; AppBarLayout跟它的名字一样,把容器类的组件全部作为AppB ...

  4. 安卓Design包下的TextInputLayout和FloatingActionButton的简单使用

    终于介绍到Design包的最后的东西了. 也很简单,一个是TextInputLayout. TextInputLayout作为一个父容器,包含一个新的EditText,可以给EditText添加意想不 ...

  5. 安卓Design包之超强控件CoordinatorLayout与SnackBar的简单使用

    在前面的Design中,学习使用了TabLayout,NavigationView与DrawerLayout实现的神奇效果,今天就带来本次Design包中我认为最有意义的控件CoordinatorLa ...

  6. 安卓Design包之TabLayout控件的简单使用

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个supp ...

  7. 安卓Design包之CoordinatorLayout配合AppBarLayout,ToolBar,TabLaout的使用

    转载: CoordinatorLayout配合AppBarLayout,Toolbar和TabLayout的使用 控件的简单介绍: AppBarLayout:它是继承LinerLayout实现的一个V ...

  8. 安卓Design包之NavigationView结合DrawerLayout,toolbar的使用,FloatingActionButton

    注意:使用前需要添加Design依赖包,使用toolbar时需要隐藏标题头 FloatingActionButton 悬浮按钮:FloatingActionButton是重写ImageView的,所有 ...

  9. 带你实现开发者头条APP(四)---首页优化(加入design包)

    title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...

随机推荐

  1. log4net配置的两种方式

    ----------文件配置:------------------- <?xml version="1.0" encoding="utf-8" ?> ...

  2. php资料站

    Veda 原型:http://www.nowamagic.net/librarys/veda/cate/PHP

  3. Java工具类 Apache Commons:commons-lang

    Commons Lang The standard Java libraries fail to provide enough methods for manipulation of its core ...

  4. 28.怎样在Swift中实现单例?

    1.回忆一下OC中的单例实现 //AFNetworkReachabilityManager中的单例,省略了其他代码 @interface AFNetworkReachabilityManager : ...

  5. 关于新建JSP文件后,文件开头报错的处理

    新建了一个web工程,之后建立了jsp页面,刚建立完成,文件开头就报错:The superclass "javax.servlet.http.HttpServlet" was no ...

  6. How a non-windowed component can receive messages from Windows -- AllocateHWnd

    http://www.delphidabbler.com/articles?article=1 Why do it? Sometimes we need a non-windowed componen ...

  7. 用一个I/O口控制1个三色指示灯, 2个单色指示灯

    http://www.baiheee.com/Documents/081207/081207184434.htm http://www.baiheee.com/Documents/081207/081 ...

  8. 提升jQuery开发技能的教程

    iPhone-like Sliding Headers Simple jQuery Spy Effect Simple use of Event Delegation Adding Keyboard ...

  9. 10 个实用的 jQuery 表单操作代码片段

    jQuery 绝对是一个伟大的开源JavaScript类库,是帮助我们快速和高效开发前端应用的利器.可能大家在日常的开发过程中常常会处理表单相关的 JavaScript,在今天这篇代码片段分享文章中, ...

  10. WP8异常错误:Error HRESULT E_FAIL has been returned from a call to a COM component.

    在做WP8开发的过程中,使用到了longlistselector这个控件,本来使用没有问题. 但是突然出现了一个闪退的错误,错误信息如下: {MS.Internal.WrappedException: ...