CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout+NestedScrollView实现上下滑动悬停效果

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_17846019/article/details/83586904

这张图解析上面几个控件的关系: 

转载:https://www.jianshu.com/p/1f3974408528   CoordinatorLayout配合AppBarLayout、CollapsingToolbarLayout、Toolbar使用

转载:https://blog.csdn.net/feather_wch/article/details/80021699   

载:https://www.jianshu.com/p/f09723b7e887/  使用CoordinatorLayout打造各种炫酷的效果

精华文章:https://blog.csdn.net/a_yue10/article/details/78653805 一句代码解决CoordinatorLayout+AppBarLayout+NestedScrollView滑动不流畅的问题

Android Toolbar使用系统原生返回键,并改变其颜色,自定义图片替换系统原生返回键

 

先认识以下控件及属性

1、导入包://根据自己的模拟器版本

    implementation 'com.android.support:design:26.1.0'

2、CoordinatorLayout的作用

  1. 加强版FrameLayout,适合作为应用顶层的布局(必须是根部局),提供交互行为
  2. 通过给子View设定Behavior可以实现他们的交互性为。Behavior能实现一系列的交互行为和布局变化,包括侧滑菜单可滑动删除的UI元素View之间跟随移动
  3. 常用支持滑动效果的子View有:比如RecyclerView,NestedScrollView、TabLayout等    ScrollView是无效的!!

 3、CoordinatorLayout的Behavoir 观察者

布局: 需要给观察者设置Behavoir(一般搭配使用的RecyclerViewNestedScrollView、TabLayout都可以是它的观察者

AppBarLayout

8、AppBarLayout是什么 。 

  • 是一个vertical的LinearLayout,其子View应通过setScrollFlags(int)或者xmL中的app:layout_scrollFlags来提供他们的Behavior。
  • 具体的app:layout_scrollFlags有这么几个: scroll, exitUntilCollapsed, enterAlways, enterAlwaysCollapsed, snap
  • 他必须严格地是CoordinatorLayout的子View,不然他一点作用都发挥不出来。
  • AppBarLayout下方的滑动控件,比如RecyclerView,NestedScrollView(与AppBarLayout同属于CoordinatorLayout的子View,并列的关系,),必须严格地通过在xml中指出其滑动Behavior来与AppBarLayout进行绑定。
  • 通常这样:app:layout_behavior="@string/appbar_scrolling_view_behavior"

Toolbar:

  • 他的title如果需要带有CollapsingToolbarLayout的动画的话,就要用collapsingToolbarLayout.setTitle(); 否则是没有动画的,其他的和toolbar平时一样。

9、app:layout_scrollFlags的具体参数

参数 作用
scroll -值设为scroll的View会跟随滚动事件(可以滚动的View)一起发生移动
EnterAlways -实现quick return效果, 当向下移动时,立即显示View(比如Toolbar)。
ExitUntilCollapsed - 向上滚动时收缩View,但可以固定Toolbar一直在上面。
EnterAlwaysCollapsed 当你的View已经设置minHeight属性又使用此标志时,你的View只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
snap “观察者-标题栏”要么完全出现,要么完全为0 (同时出现,同时回收)

其中还设置了一些属性,简要说明一下:
contentScrim - 设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色。(不设置就不会有淡出淡入的效果)

expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。

10、AppBarLayout的联动使用实例 

  1. CoordinatorLayout包裹着一个AppBarLayout和一个Scrolling View(RV等等)
  2. AppBarLayout内部控件需要指明scrollFlags
  3. Scrolling View需要指定layout_behavior
<android.support.design.widget.CoordinatorLayout
  xxx>

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TabLayout
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:background="#00A999"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlwaysCollapsed|snap"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>

 11、AppBarLayout展开和折叠的状态判断

//监听是展开还是折叠
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        if(verticalOffset == 0){
            //完全展开状态
        }else if(Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()){
            //折叠状态
        }else{
            //中间状态
        }
    }
});

CollapsingToolBarLayout

  • 是一个专门用来包裹Toolbar的控件,里面可以放置一个imageView和一个toolbar然后轻松地实现:随着滑动,图片和toolbar的标题也有动画。
  • 内部的子View一般都要加上属性:app:layout_collapseMode="",常用的是parallax,pin。parallax是视差滚动,用在imageView, pin是固定,用在toolbar。
  • setContentScrimColor(int)或者setContentScrim(drawable)来设置内容纱布,就是当折叠到只剩下Toolbar的时候,用一个另外的图片或者颜色来设置toolbar的背景。
  1. 用于实现具有折叠效果的顶部栏
  2. CollapsingToolBarLayout必须是AppBarLayout的直接子View

13、CollapsingToolBarLayout包含的特性

特性  
Collapsing title(可折叠标题)    布局完全可见时,标题比较大;布局折叠起来时,标题会变小。外观可以通过expandedTextAppearance和collapsedTextAppearance属性调整。
contentScrim(内容抹布)  如果滚动到临界点,内容麻布会显示或者隐藏。setContentScrim(Drawable)设置抹布内容。
Status bar Scrim(状态栏纱布)   设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色。
app:layout_collapseMode(视差滚动) parallax,pin。parallax

14、CollapsingToolbarLayout的重要属性

/**======================
 * 自身属性
 *======================*/
# 纱布
app:contentScrim="?attr/colorPrimary" //完全折叠后的背景色
app:scrimAnimationDuration="1000"     //纱布动画持续时间
app:scrimVisibleHeightTrigger="20dp"  //纱布可见的最小距离(低于就会开始隐身)

# 状态栏纱布(下面会特别介绍)
app:statusBarScrim="@color/colorAccent"

# 标题
app:title="Hello"             //标题优先于"ToolBar标题Title"
app:titleEnabled="true"       //是否使用大标题,true-使用;false-不使用

app:expandedTitleMargin="1dp" //"自身Title"或者"ToolBar标题Title"的Margin值
app:expandedTitleMarginStart="1dp"
app:expandedTitleMarginEnd="1dp"
app:expandedTitleMarginTop="1dp"
app:expandedTitleMarginBottom="1dp"
app:expandedTitleTextAppearance="?attr/cardBackgroundColor"

app:expandedTitleGravity="bottom|center_horizontal" //"ToolBar标题Title"的重力

# 折叠后Title的重力和样式
app:collapsedTitleGravity="center_horizontal"
app:collapsedTitleTextAppearance="?attr/colorAccent"

# 需要参考AppBarLayout的`app:layout_scrollFlags`
app:layout_scrollFlags=“xxxx”

# 指明toolbar的ID
app:toolbarId="@id/stars_toolbar"

 一般是Toolbar放在顶部固定不动

/**======================
 * 内部控件的属性
 *======================*/
# 视差(以ParallaxMultiplier的速度折叠,0:最慢~1:最快)
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5"

# 折叠后会固定在顶部
app:layout_collapseMode="pin"

15、状态栏纱布(statusBarScrim)如何生效?

CollapsingToolBarLayout设置app:statusBarScrim="@color/colorAccent"

给父容器AppBarLayout设置属性android:fitsSystemWindows="true",防止状态栏透明后出现标题栏移位到状态栏的错误。

通过下面三种方法之一将状态栏设置为全透明

1.在style.xml中增加下面的代码把状态栏设置成全透明

 <item name="android:statusBarColor">@android:color/transparent</item>

2.在style.xml中增加下面的代码把状态栏设置成半透明

 <item name="android:windowTranslucentStatus">true</item>

3.在java代码中onCreate()方法里把状态栏设置成半透明

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

补充:如果你已经在style里面把状态栏设置成了透明,那么CollapsingToolbarLayout也想要透明效果的话就无需设置了。

16、FloatingActionButton的属性以及CoordinatorLayout中的锚点属性

# 参考的锚点 app:layout_anchor=”@id/appbar”

# 与锚点的位置关系 app:layout_anchorGravity=”end|bottom|right”

17、代码设置CollapsingToolbarLayout标题颜色

//1. 展开时标题颜色
mCollapsingToolbarLayout.setExpandedTitleColor(Color.BLACK);
//2. 折叠时标题颜色
mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE);

 

参考资料

  1. CollapsingToolBarLayout用法
  2. 利用 CollapsingToolbarLayout 完成联动的动画效果
  3. CollapsingToolbarLayout 收缩时状态栏颜色设置不生效

代码:

xml文件

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:id="@+id/collapsingToolbar"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:layout_height="wrap_content">
            <ImageView
                android:scaleType="centerCrop"
                android:src="@drawable/beauty"
                android:layout_width="match_parent"
                app:layout_collapseMode="parallax"
                android:layout_height="300dp" />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                app:layout_collapseMode="pin"
                android:layout_width="match_parent"
                android:minHeight="?attr/actionBarSize"
                android:layout_height="?attr/actionBarSize">

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"

        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_height="wrap_content">
        <TextView
            android:text="@string/textContent"
            android:textSize="20sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

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

</android.support.design.widget.CoordinatorLayout>

 

MainActivity:

public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    CollapsingToolbarLayout collapsingToolbarLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.coordinatory_layout);
        //toolbar
        toolbar = findViewById(R.id.toolbar);
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
        //Palette用来更漂亮地展示配色
        Palette.from(BitmapFactory.decodeResource(getResources(),R.drawable.beauty))
                .generate(new Palette.PaletteAsyncListener() {
                    @Override
                    public void onGenerated(@NonNull Palette palette) {
                        int color=palette.getVibrantColor(getResources().getColor(R.color.colorAccent));
                        collapsingToolbarLayout.setContentScrimColor(color);
                        //因为我暂时没有找到比较好的透明状态栏来适配这一套效果布局。
                        //因此就直接替换掉StatusBar的颜色,这样其实也蛮好看的。
                        getWindow().setStatusBarColor(color);
                    }
                });
        //CollapsingToolbarLayout
        collapsingToolbarLayout = findViewById(R.id.collapsingToolbar);
        collapsingToolbarLayout.setTitle("我是一个标题啊哈哈哈");
    }
}

下面是我自己的效果:

<?xml version="1.0" encoding="utf-8"?><!--
1.CoordinatorLayout 根部局
2.CollapsingToolbarLayout
(1.自身设置falg来进行滑动效果)
(2.添加一个Toolbar控件设置顶部标题栏不动)

3.NestedScrollView (提供滑动scroll的行为behivor)
当进行滑动时,设置有flag的布局就会随机滑动
-->
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">

        <!--app:contentScrim当完全收缩后的背景色-->
        <!--不设置这个属性,就没有淡入淡出的效果了-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:contentScrim="?attr/colorPrimary"
            app:collapsedTitleTextAppearance="@style/TextAppearance.AppCompat.Title"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlwaysCollapsed"
            app:titleEnabled="false">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_marginTop="50dp">

                <EditText
                    android:id="@+id/id_add_note_title_et"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:background="@null"
                    android:hint="标题"
                    android:minHeight="10dp"
                    android:textSize="30dp"
                    android:textStyle="bold" />

            </LinearLayout>


            <!--toolbar设置pin属性后,Toolbar还可以保留在屏幕上-->

            <android.support.v7.widget.Toolbar
                android:id="@+id/id_add_note_title_layout"
                android:layout_width="match_parent"
                android:layout_height="55dp"
                android:background="#fff"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin"
                app:title="@null">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">


                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="48dp"
                        android:orientation="horizontal">

                        <LinearLayout
                            android:layout_width="50dp"
                            android:layout_height="match_parent"
                            android:gravity="left">

                            <ImageView
                                android:id="@+id/id_add_note_back"
                                android:layout_width="30dp"
                                android:layout_height="30dp"
                                android:layout_gravity="center_vertical"
                                android:layout_margin="10dp"
                                android:background="@drawable/left_circle"
                                android:onClick="back" />

                        </LinearLayout>

                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:gravity="right">

                            <ImageView
                                android:id="@+id/id_note_delete_iv"
                                android:layout_width="30dp"
                                android:layout_height="30dp"
                                android:layout_margin="10dp"
                                android:background="@drawable/delete_btn"
                                android:onClick="deleteNote" />


                        </LinearLayout>

                    </LinearLayout>

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1dp"
                        android:background="#969191"

                        />
                </LinearLayout>
            </android.support.v7.widget.Toolbar>


        </android.support.design.widget.CollapsingToolbarLayout>


<!--下划线-->
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginEnd="10dp"
            android:layout_marginStart="10dp"
            android:background="#969191" />


    </android.support.design.widget.AppBarLayout>


<!--滑动的行为者 app:layout_behavior 默认的-->


    <android.support.v4.widget.NestedScrollView
        android:id="@+id/id_add_note_scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">


        <EditText
            android:id="@+id/id_add_note_content_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@null"
            android:gravity="top"
            android:hint="内容"
            android:minLines="10"
            android:textSize="20dp" />

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

</android.support.design.widget.CoordinatorLayout>

大家一起学习。。。。

展开阅读全文

没有更多推荐了,返回首页