美文网首页
Material Design(四)--AppBarLayout

Material Design(四)--AppBarLayout

作者: 往事一块六毛八 | 来源:发表于2018-03-05 16:22 被阅读26次

    本节主要讲AppBarLayout,但是一讲到AppBarLayout必然会讲另外两个布局,CoordinatorLayout和CollapsingToolbarLayout ,因为这三个布局一起使用的时候会产生非常炫酷的效果!前一篇文章我们讲过CoordinatorLayout,说它是一个加强版的FrameLayout,不过它可以监听其所有子控件的各种事件,然后帮我们做出合理的相应。但是它到底是怎样监听各个子控件的呢?具体的用法接下来一一跟大家分享!

    CoordinatorLayout

    CoordinatorLayout.png

    首先看看官方文档的解释:
    加强版的Framelayout,两种使用场景

    • 作为顶层布局使用
    • 作为具有一个或多个相互作用的子控件的容器

    那么CoordinatorLayout是怎样协调子view的呢?当然是通过behavior。 app:layout_behavior="@string/appbar_scrolling_view_behavior"这是开发中最常见的behavior。通过给滑动控件设置behavior,CoordinatorLayout的子view通过这个behavior可以做出具体的响应操作!对于behavior实怎样操作的?内部有哪些方法?我会单独在讨论的!

    AppbarLayout

    AppbarLayout .png

    官网的描述是:AppbarLayout 是一个垂直方向的Linearlayout,它实现了material design控件的特征,通过手势改变子view的动作。那么当滑动手势改变时,内部的子view应该提供怎样的响应动作呢?


    image.png
    app:layout_scrollFlags.//设置响应动作
    
    • 注意点:


      image.png

      AppbarLayout 严重依赖于CoordinatorLayout,必须用于CoordinatorLayout 的直接子View,如果你将AppbarLayout 放在其他的ViewGroup 里面,那么它的这些功能是无效的。

    app:layout_scrollFlags的值有哪些?具体的效果是什么?

    layout_scrollFlags.png

    layout_scrollFlags有5种动作,分别是 scroll,enterAlways,enterAlwaysCollapsed,exitUntilCollapsed,snap

    • scroll
    int SCROLL_FLAG_SCROLL
    The view will be scroll in direct relation to scroll events. 
    This flag needs to be set for any of the other flags to take effect.
     If any sibling views before this one do not have this flag, then this value has no effect.
    

    该属性是:当子view设置该属性是,该子view会随着滑动控件滚动而滚动。

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll"
                />
        </android.support.design.widget.AppBarLayout>
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <android.support.v7.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="15dp"
                    android:layout_marginLeft="15dp"
                    android:layout_marginRight="15dp"
                    android:layout_marginTop="35dp"
                    app:cardCornerRadius="4dp">
    
                    <TextView
                        android:id="@+id/fruit_content_text"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_margin="10dp"/>
                </android.support.v7.widget.CardView>
            </LinearLayout>
        </android.support.v4.widget.NestedScrollView>
    </android.support.design.widget.CoordinatorLayout>!
    
    scoll.gif
    • enterAlways
     SCROLL_FLAG_ENTER_ALWAYS
    When entering (scrolling on screen) the view will scroll on any downwards scroll event,
     regardless of whether the scrolling view is also scrolling. 
    This is commonly referred to as the 'quick return' pattern.
    

    当子view设置该属性的时候,当NestedScrollView向下滑动的时候,改子view直接向下滑动,不管NestedScrollView是否在滑动。注意:要与scroll 搭配使用,否者是不能滑动的。

      <android.support.design.widget.AppBarLayout
            android:id="@+id/appBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"
                />
        </android.support.design.widget.AppBarLayout>
    
    enterAlways.gif
    • enterAlwaysCollapsed


      enterAlwaysCollapsed.png

      enterAlwaysCollapsed 是对enterAlways 的补充,当NestedScrollView向下滑动的时候,滑动View(也就是设置了enterAlwaysCollapsed 的View)下滑至折叠的高度,当NestedScrollView到达滑动范围的结束值的时候,滑动View剩下的部分开始滑动。这个折叠的高度是通过View的minimum height (最小高度)指定的
      补充说明:要配合scroll|enterAlways 一起使用

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
                />
        </android.support.design.widget.AppBarLayout>
    
    enterAlwaysCollapsed
    • exitUntilCollapsed


      image.png

      当ScrollView 滑出屏幕时(也就时向上滑动时),滑动View先响应滑动事件,滑动至折叠高度,也就是通过minimum height 设置的最小高度后,就固定不动了,再把滑动事件交给 NestedScrollView 继续滑动。

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                />
        </android.support.design.widget.AppBarLayout>
    
    exitUntilCollapsed.gif
    • snap


      snap.png

      在滚动结束时,如果视图只是部分可见,那么它将被断开并滚动到它最接近的边缘。例如,如果视图只显示底部的25%,那么它将会被完全关闭。相反,如果它的底部75%是可见的,那么它就会被完全地滚动到视图中。

    snap.gif

    介绍一下AppbarLayout几个常用且重要的方法

    • addOnOffsetChangedListener 当AppbarLayout 的偏移发生改变的时候回调,也就是子View滑动。
    • getTotalScrollRange 返回AppbarLayout 所有子View的滑动范围
    • removeOnOffsetChangedListener 移除监听器
    • setExpanded (boolean expanded, boolean animate)设置AppbarLayout 是展开状态还是折叠状态,animate 参数控制切换到新的状态时是否需要动画
    • setExpanded (boolean expanded) 设置AppbarLayout 是展开状态还是折叠状态,默认有动画

    CollapsingToolbarLayout

    CollapsingToolbarLayout .png

    CollapsingToolbarLayout 是对Toolbar的包装并且实现了折叠app bar效果,使用时,要作为 AppbarLayout 的直接子View。CollapsingToolbarLayout有以下特性:

    • Collapsing title


      image.png

      当布局全部可见的时候,title 是最大的,当布局开始滑出屏幕,title 将变得越来越小,你可以通过setTitle(CharSequence) 来设置要显示的标题。

    • Content scrim(内容纱布)


      image.png
    CollapsingToolbarLayout.gif

    滑动到一个确定的阀值时将显示或者隐藏内容纱布,可以通过setContentScrim(Drawable)来设置纱布的图片。

    提醒:纱布可以是图片也可以是颜色色值,如果要显示颜色,在xml 布局文件中用contentScrim属性添加,代码如下:app:contentScrim="@color/colorPrimary"

    • Status bar scrim(状态栏纱布)


      image.png

    当CollapsingToolbarLayout滑动到一个确定的阀值时,状态栏显示或隐藏纱布,你可以通过setStatusBarScrim(Drawable)来设置纱布图片。

    • Parallax scrolling children(有视差地滚动子View)


      image.png

      让CollapsingToolbarLayout 的子View 可以有视差的滚动,需要在xml中用 添加如下代码:

    app:layout_collapseMode="parallax"

    • Pinned position children(固定子View的位置)


      image.png

      子View可以固定在全局空间内,这对于实现了折叠并且允许通过滚动布局来固定Toolbar 这种情况非常有用。在xml 中将collapseMode设为pin,代码如下:

    app:layout_collapseMode="pin"

    接下来要实现这样的效果:


    CollapsingToolbarLayout.gif

    布局

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:fitsSystemWindows="true">
    
            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                android:fitsSystemWindows="true"
                app:contentScrim="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|exitUntilCollapsed">
    
                <ImageView
                    android:id="@+id/fruit_image_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"
                    android:fitsSystemWindows="true"
                    app:layout_collapseMode="parallax" />
    
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin" />
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <android.support.v7.widget.CardView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="15dp"
                    android:layout_marginLeft="15dp"
                    android:layout_marginRight="15dp"
                    android:layout_marginTop="35dp"
                    app:cardCornerRadius="4dp">
    
                    <TextView
                        android:id="@+id/fruit_content_text"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_margin="10dp" />
                </android.support.v7.widget.CardView>
            </LinearLayout>
        </android.support.v4.widget.NestedScrollView>
    
        <android.support.design.widget.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_comment"
            app:layout_anchor="@id/appBar"
            app:layout_anchorGravity="bottom|end" />
    </android.support.design.widget.CoordinatorLayout>
    

    代码:

    package com.jimmy.xg.materialdesigndemo;
    
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.design.widget.CollapsingToolbarLayout;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.MenuItem;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.bumptech.glide.Glide;
    
    public class FruitActivity extends AppCompatActivity {
    
        public static final String FRUIT_NAME = "fruit_name";
    
        public static final String FRUIT_IMAGE_ID = "fruit_image_id";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_fruit);
            Intent intent = getIntent();
            String fruitName = intent.getStringExtra(FRUIT_NAME);
            int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID, 0);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
            ImageView fruitImageView = (ImageView) findViewById(R.id.fruit_image_view);
            TextView fruitContentText = (TextView) findViewById(R.id.fruit_content_text);
            setSupportActionBar(toolbar);
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(true);
            }
            collapsingToolbar.setTitle(fruitName);
            Glide.with(this).load(fruitImageId).into(fruitImageView);
            String fruitContent = generateFruitContent(fruitName);
            fruitContentText.setText(fruitContent);
        }
    
        private String generateFruitContent(String fruitName) {
            StringBuilder fruitContent = new StringBuilder();
            for (int i = 0; i < 500; i++) {
                fruitContent.append(fruitName);
            }
            return fruitContent.toString();
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case android.R.id.home:
                    finish();
                    return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Material Design(四)--AppBarLayout

          本文链接:https://www.haomeiwen.com/subject/fgwrxftx.html