可折叠式标题栏

660 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

CollapsingToolbarLayout

顾名思义,这是一个作用在Toolbar上的布局,但是要注意的是CollapsingToolbarLayout不能单独存在,它必须要作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout(监听子控件的事件,做出合理的响应)的子布局。所以可以得到:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:id="@+id/appbar">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

接着为了让标题栏高级一些,在CollapsingToolbarLayout中放一张图片和一个Toolbar

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:id="@+id/appbar">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:id="@+id/fruit_image_view"/>
            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:id="@+id/toolbar"
                app:layout_collapseMode="pin"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

这里有一个layout_collapseMode属性,表示在折叠过程中的折叠样式,parallax表示在折叠过程中会产生错位偏移,而pin表示会始终不变。

NestedScrollView

标题栏完成之后,就是开始编写水果内容的部分了。这里使用NestedScrollView,这和ScrollView,RecyclerView一样都是可以通过滚动的方式来查看屏幕外的数据。同样的和之前的RecyclerView一样,这里也要指定一个布局行为。 由于NestedScrollView和ScrollView一样,只允许存在一个直接子布局,这里就可以嵌套一个LinearLayout作为它的直接子布局。然后在LinearLayout中放具体的内容就可以了。

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <androidx.cardview.widget.CardView
                android:layout_marginTop="35dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginBottom="15dp"
                app:cardCornerRadius="4dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/fruit_content_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"/>
            </androidx.cardview.widget.CardView>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

这里添加了一个布局行为(和之前的RecyclerView一样)。 为了让之前的知识尽可能用到,这里再加一个悬浮按钮。

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:src="@drawable/ic_comment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|end"/>

这是目前的效果图 在这里插入图片描述 接着就是通过逻辑代码将数据给填进去了。

MainActivity→FruitActivity

由于数据是在MainActivity得到的,FruitActivity并不能得到数据,所以需要通过MainActivity将数据传输过去,这里可以用Intent来传输。

        ViewHolder viewHolder=new ViewHolder(view);
        viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(context,FruitActivity.class);
                int position=viewHolder.getAdapterPosition();
                Fruit fruit=FruitList.get(position);
                intent.putExtra("fruitName",fruit.getName());
                intent.putExtra("fruitId",fruit.getId());
                context.startActivity(intent);
            }
        });

这里选择在每次生成ViewHolder的时候就为其中的cardView绑定点击事件,将id和name传递给FruitAcitivity。

FruitActivity进行数据处理。

       ImageView imageView=findViewById(R.id.fruit_image_view);
        TextView textView=findViewById(R.id.fruit_content_text);
        Toolbar toolbar=findViewById(R.id.toolbar);
        //将ActionBar换成toolbar
        setSupportActionBar(toolbar);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        CollapsingToolbarLayout collapsingToolbarLayout=findViewById(R.id.collapsing_toolbar);
        Intent intent=getIntent();
        String name=intent.getStringExtra(fruitName);
        int id=intent.getIntExtra(fruitId,0);
        //用Glide来加载图片
        Glide.with(this).load(id).into(imageView);
        textView.setText(ExtraText(name));
        //为可折叠标题栏设置标题。
        collapsingToolbarLayout.setTitle(name);

充分利用状态栏空间。

为ImageView的父布局和其本身添加fitsSystemWindows属性。

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

为FruitActivity自定义一个主题。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="FruitActivityTheme" parent="Theme.ListView">
        <item name="android:statusBarColor">
            @android:color/transparent
        </item>
    </style>
</resources>

引入这个主题

 <activity android:name=".FruitActivity" android:theme="@style/FruitActivityTheme">