【Android】Material Design 之四 五 六 AppBarLayout、CoordinatorLayout、CollapsingToolbarLayout使用

一、AppBarLayout

AppBarLayout是继承自LinearLayout,默认是垂直方向,可以看成是一个垂直方向的线性布局,其作用是将APPBarLayout包裹的内容都作为AppBar,支持手势滑动。

AppBarLayout必须作为Toolbar的父布局容器,换句话就是说,使用AppBarLayout布局时,需要包裹Toolbar布局。

支持手势滑动时,需要和CoordinatorLayout配合使用。

二、CoordinatorLayout

CoordinatorLayout是一个为子视图之间相互协调手势效果的协调布局, 在不指定视图位置时,和FrameLayout一样,所有视图都位于在左上角。一般都是和AppBarLayout 、CollapsingToolbarLayout配合使用。

三、CollapsingToolbarLayout

CollapsingToolbarLayout一般作为AppBarLayout的子视图使用,当其包裹Toolbar时,提供了一个可以折叠的Toolbar,需要有折叠效果的组件还需设置 layout_collapseMode属性。是继承自FrameLayout布局,如果包裹的视图不指定位置,会和FrameLayout一样位于在左上角。

使用上面这些布局,都要导入Material Design依赖包,我使用的是Android Studio 3.0版本,导入包

implementation 'com.android.support:design:28.0.0-alpha1'

四、使用 CoordinatorLayout + RecyclerView + AppBarLayout +( Toolbar) 实现Toolbar可手势滑动

(1)自定义一个Toolbar布局toolbar_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginLeft="10dp"
        android:src="@drawable/toolbar_pic"
        android:layout_centerVertical="true"/>

    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_toRightOf="@+id/iv"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="主标题"
            android:textSize="15sp"
            android:textColor="#000000"
            android:padding="5dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="副标题"
            android:textSize="13sp"
            android:textColor="#ece8e8"
            android:padding="5dp"/>

    </LinearLayout>

    <ImageView
        android:id="@+id/iv2"
        android:layout_toLeftOf="@+id/iv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_search"
        android:layout_centerVertical="true"
        android:layout_marginRight="10dp"/>

    <ImageView
        android:id="@+id/iv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_more"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"/>

</RelativeLayout>

(2)activity_app_bar_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".SAppBarLayoutActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways">

            <include layout="@layout/toolbar_layout"/>
        </android.support.v7.widget.Toolbar>
    </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:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>

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

(3)RecyclerView的适配器

public class RVMyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    private List<String> list;

    public RVMyAdapter(Context context, List<String> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        TextView textView=new TextView(context);
        return new RecyclerView.ViewHolder(textView) {};
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        ((TextView)viewHolder.itemView).setText(list.get(i));
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}

(4)AppBarLayoutActivity.java

public class AppBarLayoutActivity extends Activity {

    private Toolbar toolbar;
    private RecyclerView recyclerView;
    private List<String> list;

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

        //设置toolbart替代ActionBar
        toolbar=findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
         
        //设置recyclerView填充数据
        recyclerView=findViewById(R.id.recyclerView);
        list=new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(String.format(Locale.CHINA,"第%03d条数据",i));
        }
        recyclerView.setAdapter(new RVMyAdapter(this,list));
    }
}

 (5)运行界面

 (6)效果实现说明:

为了使Toolbar可以手势滑动,首先,给Toolbar设置app:layout_scrollFlags="scroll | enterAlways"属性。其次,CoordinatorLayout布局下必须包裹一个可以滑动的布局,比如,可以是RecyclerView(经测试,ListView、ScrollView不支持) , 并且给这滑动组件设置属性app:layout_behavior="@string/appbar_scrolling_view_behavior"来告诉CoordinatorLayout,该组件是带有滑动行为的组件,然后CoordinatorLayout在接收到滑动时会通知AppBarLayout 中可滑动的Toolbar可以滑出屏幕了。

给想要实现手势滑动的组件设置的layout_scrollFlags属性有如下几种选项:

scroll: 所有想滚动出屏幕的view都需要设置这个值,没有设置这个值的view将被固定在屏幕顶部。enterAlways: 任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。 enterAlwaysCollapsed: 当滚动视图到达顶部时view才扩大到完整高度。exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。

(7)总结

为了使Toolbar有手势滑动的效果,必须做到下面几点:

1、CoordinatorLayout作为整个布局的父布局容器

2、Toolbar的父布局容器须为AppBarLayout,给Toolbar设置属性

app:layout_scrollFlags=" ",值为scroll|enterAlways表示滚动出屏幕|任意向下滑动就可见,值为scroll|enterAlwaysCollapsed表示滚动出屏幕|向下滑动顶端出现才可见

3、CoordinatorLayout需包裹一个滑动组件,比如RecyclerView,并给滑动组件设置属性:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

(8)扩展一下,稍稍修改下activity_app_bar_layout.xml布局,在AppBarLayout中增加一个ImageView控件,其他地方不变

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".SAppBarLayoutActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:paddingTop="10dp"
            android:src="@drawable/toolbar_pic" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways">

            <include layout="@layout/toolbar_layout"/>
        </android.support.v7.widget.Toolbar>

    </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:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>

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

界面如下图所示,运行中我们可以发现,这种情况下,即使Toolbar设置了属性app:layout_scrollFlags="scroll | enterAlways",RecyclerView在滑动过程中Toolbar也没有出现滑动。如果将app:layout_scrollFlags="scroll | enterAlways"属性设置给AppBarLayout,Toolbar仍然没有滑动。如果将app:layout_scrollFlags="scroll | enterAlways"属性设置给刚添加的ImageView,ImageView却出现了滑动,向上滑动时Toolbar会固定在顶部位置。如果这种情况想要实现Toolbar也可滑动,怎么办?这个问题将会在下面给出解决。

五、使用 CoordinatorLayout + RecyclerView + AppBarLayout + (CollapsingToolbarLayout +( ToolBar) ) 实现可折叠的Toolbar

(1)CollapsingToolbarLayout的常用属性

app:contentScrim="@color/colorAccent"    //设置被折叠到顶部固定时候的背景

app:layout_scrollFlags="scroll | exitUntilCollapsed"   //设置滑动标志  scroll: 所有想滚动出屏幕的view都需要设置这个值,exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。

app:layout_collapseParallaxMultiplier="0.2"   //设置CollapsingToolbarLayout滑动时其子视图的视觉差

app:layout_collapseMode="parallax"  // 设置子视图的折叠模式  “pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。

(2)自定义的toolbar_layout布局、代码文件、RecyclerView适配器文件与上面的一样,这里就不重复贴了,这里只贴一下布局文件。

(3)布局文件

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".AppBarLayoutActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:contentScrim="@color/colorAccent"
            app:layout_collapseParallaxMultiplier="0.2"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:layout_collapseMode="parallax">

            <ImageView
                android:layout_width="80dp"
                android:layout_height="200dp"
                android:layout_gravity="center"
                android:src="@drawable/toolbar_pic" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?actionBarSize"
                android:layout_gravity="bottom">

                <include layout="@layout/toolbar_layout"/>
            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>

    </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:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>

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

(5)运行界面

 

(6)注意:Toolbar的高度layout_height必须固定,不能是“wrap_content”,否则Toolbar不会滑动,也不会折叠。

(7)扩展:如果将CollapsingToolbarLayout的属性app:layout_scrollFlags=""设置为scroll | enterAlways,就会实现可滑动的ImageView+Toolbar,这刚好可以解决四(7)中的问题。

说了这么多,具体还是要自己动手去实练一遍才有感觉。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我知道你的问题了。针对你的问题,可以通过如下代码实现AppBarLayout的滚动监听: ```java AppBarLayout appBarLayout = findViewById(R.id.appBarLayout); appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { // 在这里处理滚动事件 } }); ``` 其中,`addOnOffsetChangedListener` 方法可以添加滚动监听器,该监听器中的 `onOffsetChanged` 方法中可以处理 AppBarLayout 的滚动事件。 关于CoordinatorLayoutAppBarLayoutCollapsingToolbarLayout 和 RecyclerView 的结合使用,可以参考以下代码: ```xml <androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/coordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/appBarLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true"> <com.google.android.material.appbar.CollapsingToolbarLayout android:id="@+id/collapsingToolbarLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerCrop" android:src="@drawable/image" app:layout_collapseMode="parallax" /> <com.google.android.material.toolbar.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" /> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` 其中,`CoordinatorLayout` 是一个可以协调多个子视图之间交互的布局容器。`AppBarLayout` 是一个垂直的 LinearLayout,可以包含一个或多个子视图,用于实现应用程序栏。`CollapsingToolbarLayout` 是一个具有可折叠效果的 Toolbar 布局。`RecyclerView` 是一个可以滚动的列表视图。 以上代码实现了一个具有可折叠效果的 Toolbar 和一个可以滚动的列表视图。在 `CollapsingToolbarLayout` 中的 `ImageView` 和 `Toolbar` 都有一个 `layout_collapseMode` 属性,用于指定它们的行为。`ImageView` 的 `layout_collapseMode` 属性设置为 `parallax`,表示在滚动时具有视差效果;`Toolbar` 的 `layout_collapseMode` 属性设置为 `pin`,表示在折叠时固定在顶部。 `RecyclerView` 的 `layout_behavior` 属性设置为 `appbar_scrolling_view_behavior`,表示它是一个可以与 `AppBarLayout` 协同工作的滚动视图。这样,`AppBarLayout` 就可以根据 `RecyclerView` 的滚动情况来调整自身的显示状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值