Material Design 中 CoordinatorLayout 概述及实现方式详解

前言

Material Design 是 Google 推出的一种全新的设计语言,旨在为移动端和 Web 应用程序带来一致性的设计风格和用户体验。其中 CoordinatorLayout 是 Material Design 中重要的 UI 控件之一,它可以与其他控件配合使用,实现各种丰富的效果,并且可适配不同的移动设备。

概述

CoordinatorLayout 是一种专门用来协调其他控件并提供交互反馈的布局容器,它的主要作用在于控制子视图之间的行为,例如在滚动时,一个视图可以跟随着另一个视图一起滚动,或者把一个视图固定在屏幕的某个位置等等。

实现方式

CoordinatorLayout 布局结构介绍:

CoordinatorLayout 包含一个或者多个子视图(View), 这些子视图可以是任何布局。在 CoordinatorLayout 布局内,每个子视图(称之为 Behavior View)可以使用 CoordinatorLayout.Behavior 实现特定的交互效果,这些效果包括:浮动动作按钮、拉伸式头部等效果。

这里我们以 FloatingActionButton(浮动动作按钮) 为例来说明:

在这个布局中,RecyclerView 作为一个列表的容器,浮动按钮 FloatingActionButton 指定了其在 CoordinatorLayout 中的位置关系,通过android.support.design.widget.CoordinatorLayout.LayoutParams 这样一个自定义属性布局可以达到效果

  • app:layout_anchor:是指定子视图的“锚点”。
  • app:layout_anchorGravity:是指定子视图的重心(重心是指水平和竖直方向上的对齐方式)。

Behavior 实现方式

CoordinatorLayout.Behavior 类是负责实现视图交互的类。只需要实现 Behavior 类,然后协调它与相应的视图进行配对即可,例如,FloatingActionButton 的效果是随着 RecyclerView 的滚动而上下浮动。

在代码中我们通过继承 Behavior 类,并重写 onNestedScroll() 方法,该方法在滑动时被调用 。我们判断滑动方向,当向上滑动时悬浮按钮隐藏,向下时悬浮按钮显示。

在布局 xml 文件中,我们需要指定该 Behavior类,在 FloatingActionButton 的属性中添加 android:layout_behavior 属性

总结

CoordinatorLayout 可以灵活地布局子视图,为 Material Design UI 控件提供了优异的支持。我们可以通过使用 CoordinatorLayout.Behavior 实现个性化的视图交互效果,来满足不同应用场景的需求。了解和掌握这些技能,对于前端开发来说将有很大的指导意义。

完整代码如下:

public class ScrollAwareFabBehavior extends FloatingActionButton.Behavior {

    public ScrollAwareFabBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, FloatingActionButton child,
                                       View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
                super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
                               View target, int dxConsumed, int dyConsumed,
                               int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

        if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
            child.hide();
        } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
            child.show();
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:id="@+id/main_coordinator_layout"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

      <androidx.recyclerview.widget.RecyclerView
          android:id="@+id/main_list_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>

      <com.google.android.material.floatingactionbutton.FloatingActionButton
          android:id="@+id/main_fab"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="16dp"
          android:src="@drawable/ic_add"
          app:layout_anchorGravity="bottom|end"
          app:layout_anchor="@id/main_list_view"
          app:layout_behavior=".ScrollAwareFabBehavior"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a2181fadd4f0e0ffa28ac5


纠错反馈