12.7--可折叠标题栏

虽说我们现在的标题栏是使用 Toolbar 来编写的,不过它看上去和传统的 ActionBar 其实没什么两样,只不过可以响应 RecyclerView 的滚动事件来进行隐藏和显示。而 Material Design 中并没有限定标题栏必须是长这个样子的,事实上,我们可以根据自己的喜好随意定制标题栏的样式。那么本节中我们就来实现一个可折叠式标题栏的效果,需要借助 CollapsingToolbarLayout 这个工具。

12.7.1 CollapsingToolbarLayout

顾名思义,CollapsingToolbarLayout 是一个作用于 Toolbar 基础之上的布局,它也是由Material 库提供的。CollapsingToolbarLayout 可以让 Toolbar 的效果变得更加丰富,不仅仅是展示标题栏,而是能够实现非常华丽的效果。

不过,CollapsingToolbarLayout 是不能独立存在的,它在设计的时候就被限定只能作为AppBarLayout  的直接子布局来使用。而AppBarLayout 又必须是 CoordinatorLayout 的子布局,因此本节中我们要实现的功能其实需要综合运用前面所学的各种知识。那么话不多说,这就开始吧。

首先我们需要一个额外的Activity 来作为水果的详情展示界面,右击 com.example.materialtest 包 →New→ Activity> Empty Activity,创建一个 FruitActivity,并将布局名指定成 activity_fruit.xml,然后我们开始编写水果详情展示界面的布局。

首先实现标题栏部分,这里使用 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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

</androidx.coordinatorlayout.widget.CoordinatorLayout>

开始的代码还是比较简单的,相信没有什么需要解释的地方。注意始终记得要定义一个 xmlns:app 的命名空间,在 Material Design 的开发中会经常用到它。

接着我们在 CoordinatorLayout 中嵌套一个 AppBarLayout,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">

    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

目前为止也没有什么难理解的地方,我们给 AppBarLayout 定义了一个 id,将它的宽度指定为 match_parent,高度指定为 250dp。当然这里的高度值你可以随意指定,不过我尝试之后发现 250dp的视觉效果比较好。

接下来我们在 AppBarLayout  中再嵌套一个 CollapsingToolbar,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            >
            
        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

从现在开始就稍微有点难理解了,这里我们使用了新的布局CollapsingToolbarLayout。其中,id 、layout_width 和 layout_height 这几个属性比较简单,我就不解释了。android:theme 属性指定了一个ThemeOverlay.AppCompat.Dark.ActionBar 的主题,其实对于这个部分我们也并不陌生,因为之前在activity_main.xml 中给Toolbar 指定的也是这个主题,只不过这里要实现更加高级的Toolbar 效果,因此需要将这个主题的指定提到上一层来。app:contentScrim 属性用于指定CollapsingToolbarLayout 在趋于折叠状态已经折叠之后的背景色,其实CollapsingToolbarLayout 在折叠后就是一个普通的Toolbar ,那么背景色肯定应该是colorPrimary了,具体的效果我们待会儿就能看到。app:layout_scrollFlags 属性我们也是见过的,只不过之前是给Toolbar 指定的,现在也移到外面来了。其中,scroll 表示CollapsingToolbarLayout 会随着水果内容详情的滚动一起滚动,exitUntilCollapsed 表示当CollapsingToolbarLayout 随着滚动完成折叠之后就保留在界面上,不再移除屏幕。

接下来,我们在 CollapsingLayout 中定义标题栏的具体内容,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            >
            <ImageView
                android:id="@+id/fruitImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                />
            <androidx.appcompat.widget.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.coordinatorlayout.widget.CoordinatorLayout>

可以看到,我们在 CollapsingLayout 中定义了一个 ImageView 和一个 Toolbar,也就意味着,这个高级版的标题栏将是由普通的标题栏加上图片组合而成的。这里定义的大多数属性我们都是见过的,就不再解释了,只有一个 app:layout_collapseMode 比较陌生。它用于指定当前控件在 CollapsingToolbarLayout 折叠过程中的折叠模式,其中 Toolbar 指定成 pin,表示在折叠的过程中位置始终保持不变,ImageView 指定成 parallax,表示会在折叠的过程中产生一定的错位偏移,这种模式的视觉效果会非常好。

这样我们就将水果标题栏的界面编写完成了,下面开始编写水果内容详情部分。继续修改 activity_fruit.xml 中的代码,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">
        ...

    </com.google.android.material.appbar.AppBarLayout>
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >
        
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

水果内容详情的最外层布局使用了一个 NestedScrollView,注意它和 AppBarLayout是平级的。我们之前在 11.2.1 小节学过 ScrollView 的用法,它允许使用滚动的方式来査看屏幕以外的数据而 NestedScrollView 在此基础之上还增加了嵌套响应滚动事件的功能。由于 CoordinatorLayout 本身已经可以响应滚动事件了,因此我们在它的内部就需要使用 NestedScrollView 或 RecyclerView 这样的布局。另外,这里还通过 app:layout_behavior 属性指定了一个布局行为,这和之前在 RecyclerView 中的用法是一模一样的。

不管是 ScrolllView 还是 NestedScrollView,它们的内部都只允许存在一个直接子布局。因此如果我们想要在里面放入很多东西的话,通常都会先嵌套一个 LinearLayout,然后再在 LinearLayout 中放入具体的内容就可以了,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    ...
    <androidx.core.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">
            
        </LinearLayout>

    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

这里我们嵌套了一个垂直方向的 LinearLayout,并将 layout_width 设置为 match_ parent 将 layout_height 设置为 wrap_content。

接下来在 LinearLayout 中放入具体的内容,这里我准备使用一个 TextView 来显示水果的内容详情,并将 TextView 放在一个卡片式布局当中,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    ...
    <androidx.core.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">
            <com.google.android.material.card.MaterialCardView
                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/fruitContentText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    />
            </com.google.android.material.card.MaterialCardView>
        </LinearLayout>

    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

这段代码也没有什么难理解的地方,都是我们学过的知识。需要注意的是,这里为了让界面更加美观,我在 MaterialCardView 和 TextView 上都加了一些边距。其中,MaterialCardView 的 layout_marginTop 加了 35dp 的边距,这是为下面要编写的东西留出空间。

好的,这样就把水果标题栏和水果内容详情的界面都编写完了,不过我们还可以在界面上再添加一个悬浮按钮。这个悬浮按钮并不是必需的,根据具体的需求添加就可以了,如果加入的话,我们将免费获得一些额外的动画效果。

为了做出示范,我就准备在 activity_fruit.xml 中加入一个悬浮按钮了。这个界面是一个水果详情展示界面,那么我就加入一个表示评论作用的悬浮按钮吧。首先需要提前准备好一个图标这里我放置了一张 ic_comment.png 到 drawable--xxhdpi 目录下。然后修改 activity_fruit.xml 中的代码,如下所示:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FruitActivity">

    ...

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:src="@drawable/ic_comment"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end"
        />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

可以看到,这里加入了一个 FloatingActionButton,它和 App Layout 以及 NestedScrollView 是平级的。FloatingActionButton 中使用 app:layout_anchor 属性指定了一个锚点,我们将锚点设置为 AppBarLayout,这样悬浮按钮就会出现在水果标题栏的区域内,接着又使用 app:layout_anchorGravity 属性将悬浮按钮定位在标题栏区域的右下角。其他一些属性都比较简单,就不再进行解释了。

好了,现在我们终于将整个 activity_fruit.xml 布局都编写完了,内容虽然比较长,但由于是分段编写的,并且每一步我都进行了详细的说明,相信你应该看得很明白吧。

界面完成了之后,接下来我们开始编写功能逻辑,修改 FruitActivity 中的代码,如下所示:

class FruitActivity : AppCompatActivity() {
    companion object {
        const val FRUIT_NAME = "fruit_name"
        const val FRUIT_IMAGE_ID = "fruit_image_id"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_fruit)
        val fruitName = intent.getStringExtra(FRUIT_NAME) ?: ""
        val fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID,0)
        setSupportActionBar(toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        collapsingToolbar.title = fruitName
        Glide.with(this).load(fruitImageId).into(fruitImageView)
        fruitContentText.text = generateFruitContent(fruitName)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            android.R.id.home -> {
                finish()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }

    private fun generateFruitContent(fruitName: String) = fruitName.repeat(500)
}

FruitActivity 中的代码并不是很复杂。首先,在 onCreate() 方法中,我们通过 Intent 获取到传人的水果名和水果图片的资源 id。接着就是使用了 Toolbar 的标准用法,将它作为 ActionBar 显示,并启用 Home按钮。由于 Home按钮的默认图标就是一个返回箭头,这正是我们所期望的,因此就不用再额外设置别的图标了。

接下来开始填充界面上的内容,调用 CollapsingToolbarLayout 的 setTitle() 方法将水果名设冒成当前界面的标题,然后使用 Glide 加载传入的水果图片,并设置到标题栏的 ImageView 上面。接着需要填充水果的内容详情,由于这只是一个示例程序,并不需要什么真实的数据,所以我使用了一个 generateFruitContent() 方法将水果名循环拼接 500 次,从而生成了一个比较长的字符串,将它设置到了 TextView 上面。

最后,我们在 onOptionsItemSelected() 方法中处理了 Home 按钮的点击事件,当点击了这个按钮时,就调用 finish() 方法关闭当前的活动,从而返回上一个活动。

所有工作都完成了吗?其实还差最关键的一步,就是处理 RecyclerView 的点击事件,不然的话我们根本就无法打开 FruitActivity。修改 FruitAdapter 中的代码,如下所示:

package com.example.materialtest

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide

class FruitAdapter(val context:Context,val fruitList:List<Fruit>) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
    ...

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.fruit_item,parent,false)
        val holder = ViewHolder(view)
        holder.itemView.setOnClickListener { 
            val position = holder.adapterPosition
            val fruit = fruitList[position]
            val intent = Intent(context,FruitActivity::class.java).apply {
                putExtra(FruitActivity.FRUIT_NAME,fruit.name)
                putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.imageId)
            }
            context.startActivity(intent)
        }
        return holder
    }

    ...
}

最关键的一步其实也是最简单的,这里我们给 MaterialCardview 注册了一个点击事件监听器,然后在点击事件中获取当前点击项的水果名和水果图片资源 id,把它们传入到 Intent 中,最后调用 startActivity()方法启动 FruitActivity。

见证奇迹的时刻到了,现在重新运行一下程序,并点击界面上的任意一个水果,比如我点击了樱桃,效果如图所示。

你没有看错,如此精美的界面就是我们亲手敲出来的。这个界面上的内容分为三部分,水果标题栏、水果内容详情和悬浮按钮,相信你一眼就能将它们区分出来吧。Toolbar 和水果背景图完美地融合到了一起,既保证了图片的展示空间,又不影响 Toolbar 的任何功能,那个向左的箭头就是用来返回上一个活动的。

不过这并不是全部,真正的好戏还在后头。我们尝试向上拖动水果内容详情,你会发现水果背景图上的标题会慢慢缩小,并且背景图会产生一些错位偏移的效果,如图所示。

这是由于用户想要査看水果的内容详情,此时界面的重点在具体的内容上面,因此标题栏就会自动进行折叠,从而节省屏幕空间。

继续向上拖动,直到标题栏变成完全折叠状态,效果如图所示。

可以看到,标题栏的背景图片不见了,悬浮按钮也自动消失了,现在水果标题栏变成了一个最普通的 Toolbar。这是由于用户正在阅读具体的内容,我们需要给他们提供最充分的阅读空间。而如果这个时候向下拖动水果内容详情,就会执行一个完全相反的动画过程,最终恢复成最开始的界面效果。

不知道你有没有被这个效果所感动呢?在这里,我真心地感谢 Material Design 送给我们的礼物。

 

12.7.2 充分利用系统状态栏空间

虽说现在水果详情展示界面的效果已经非常华丽了,但这并不代表我们不能再进一步地提升。观察一下上图, 你会发现水果的背景图片和系统的状态栏总有一些不搭的感觉,如果我们能将背景图和状态栏融合到一起,那这个视觉体验绝对能提升好几个档次。

只不过很可惜的是,在 Android 5.0 系统之前,我们是无法对状态栏的背景或颜色进行操作的,那个时候也还没有 Material Design 的概念。但是 Android 5.0 及之后的系统都是支持这个功能的。恰好我们本书的所有代码最低兼容的就是Android 5.0 系统,因此这里完全可以进一步地提升视觉体验。

想要让背景图能够和系统状态栏融合,需要借助 android: fitsSystemWindows 这个属性来实现。在 CoordinatorLayout、App BarLayout、CollapsingToolbarLayout 这种嵌套结构的布局中,将控件的 android: fitsSystemWindows 属性指定成 true,就表示该控件会出现在系统状态栏里。对应到我们的程序,那就是水果标题栏中的 ImageView 应该设置这个属性了。不过只给 ImageView 设置这个属性是没有用的,我们必须将 ImageView 布局结构中的所有父布局都设置上这个属性才可以,修改 activity_fruit.xml 中的代码,如下所示

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".FruitActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:fitsSystemWindows="true">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            >
            <ImageView
                android:id="@+id/fruitImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:fitsSystemWindows="true"
                />
            <androidx.appcompat.widget.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.coordinatorlayout.widget.CoordinatorLayout>

但是,即使我们将 android: fitsSystemWindows 属性都设置好了还是没有用的,因为还必须在程序的主题中将状态栏颜色指定成透明色才行。指定成透明色的方法很简单,在主题中将 android: statusBarColor 属性的值指定成 @android:color/transparent 就可以了

打开res/values/styles.xml 文件,对主题内容进行修改,如下所示:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    <style name="FruitActivityTheme" parent="AppTheme">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>

这里我们定义了一个FruitActivityTheme 主题,它是专门给FruitActivity 使用的。FruitActivityTheme 的父主题是AppTheme 。也就是说,它继承了 AppTheme 中的所有特性。在此基础上,我们将FruitActivityTheme 的状态栏的颜色指定成透明色。

最后,我们还需要让 FruitActivity 使用这个主题オ可以,修改 AndroidManifest.xml 中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.materialtest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".FruitActivity"
            android:theme="@style/FruitActivityTheme"
            ></activity>
        <activity
            android:name=".MainActivity"
            android:label="Fruits">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这里使用 android:theme 属性单独给 FruitActivity 指定了 FruitActivityTheme 这个主题,这样我们就大功告成了。现在重新运行MaterialTest 程序,水果详情展示界面的效果就会如图所示。

相信我,再对比一下之前的效果,这两种视觉体验绝对不是在一个档次上的。

好了,关于Material Design 的知识我们就学到这里,接下来又该进入本章的Kotlin 课堂了。赶快看一看这次又学到了Kotlin 的什么心知识吧?

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值