第一行代码第三版Material Design中的组件学习笔记

在使用Material库时需要引入依赖

/*加入Material库*/
    implementation 'com.google.android.material:material:1.8.0'
    //处理图片,变成圆形化的工具的依赖
    implementation 'de.hdodenhof:circleimageview:3.0.1'

1使用ToolBar

第一步在values/themes.xml文件中关闭默认的ActionBar,改成NoActionBar即可

<style name="Theme.MaterialDesign" parent="Theme.MaterialComponents.DayNight.NoActionBar">

第二步 :在主xml文件中引入toolbar

 <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/purple_200"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

theme表示bar的主题
popupTheme表示弹出bar的主题

第三步,指定bar里需要添加的元素样式
新建一个menu/toolbar.xml文件,在里面指定样式

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app1="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/backup"
        android:icon="@drawable/ic_baseline_filter_drama_24"
        android:title="Backup"
        app1:showAsAction="always"/>
    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_baseline_delete_24"
        android:title="Delete"
        app1:showAsAction="ifRoom"/>
    <item
        android:id="@+id/setting"
        android:icon="@drawable/ic_baseline_settings_24"
        android:title="Settings"
        app1:showAsAction="never"/>
</menu>

showAsAction属性共有五个值:ifRoom、never、always、withText、collapseActionView,可以混合使用。
ifRoom 会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。当然个数并不仅仅局限于4个,依据屏幕的宽窄而定
never 永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上。
always 无论是否溢出,总会显示。
withText withText值示意Action bar要显示文本标题。Action bar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。
collapseActionView 声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。
一般要配合ifRoom一起使用才会有效果。

第四步在主程序中进行menu的加载和点击按钮的绑定

package com.njupt.materialdesign

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //启用toolbar
        setSupportActionBar(toolbar)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    
    
        menuInflater.inflate(R.menu.toolbar,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    
        when(item.itemId){
    
    
            R.id.backup->{
    
    
                Toast.makeText(this,"点击了备份按钮",Toast.LENGTH_SHORT).show()}
            R.id.delete->Toast.makeText(this,"点击了删除按钮",Toast.LENGTH_SHORT).show()
            R.id.setting->Toast.makeText(this,"点击了设置按钮",Toast.LENGTH_SHORT).show()
        }
        return true
    }
}

在这里插入图片描述
可以通过更改Manifest文件里的lable标签指定当前显示的名称
在这里插入图片描述

2更加美观的隐藏菜单NavigationView

在这里插入图片描述
主要有四个部分,第一部分是整张图,使用DrawerLayout布局,表示里面的元素中包含了抽屉元素
第二个部分是黄色线条,表示弹出的界面,即整个抽屉,用NavigationView布局
第三部分是粉色线条,表示抽屉元素中的nav_header
第四部分是黑色线条,表示里面可选的内容nav_menu
真正实现是需要从里往外去实现

第四部分的黑色线条内容

在menu下新建一个nav_menu.xml文件,里面绘制第四部分数据的展示

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">

    <item
        android:id="@+id/phone"
        android:icon="@drawable/ic_baseline_local_phone_24"
        android:title="Phone"/>
    <item
        android:id="@+id/friends"
        android:icon="@drawable/ic_baseline_people_alt_24"
        android:title="Friends"/>
    <item
        android:id="@+id/location"
        android:icon="@drawable/ic_baseline_location_on_24"
        android:title="Location"/>
    <item
        android:id="@+id/email"
        android:icon="@drawable/ic_baseline_email_24"
        android:title="Email"/>
</group>
</menu>

第三部分紫色线条nav_header

在layout下新建布局nav_header.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="180dp"
    android:padding="10dp"
    android:background="@color/teal_700">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/iconImage"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:src="@drawable/yueyue"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/mailText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:textSize="14sp"
        android:text="[email protected]"
        android:textColor="#FFF"/>

    <TextView
        android:id="@+id/userText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/mailText"
        android:textSize="14sp"
        android:text="yueyue"
        android:textColor="#FFF"/>

</RelativeLayout>

绘制了显示的基本信息

第二部分和第一部分

<?xml version="1.0" encoding="utf-8"?>

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/drawerLayout"
    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">

    <!--这里是主布局-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/purple_500"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="主界面中数据展示"/>

    </LinearLayout>
    <!--这里是隐藏的布局滑动的菜单-->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_View"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"/>

</androidx.drawerlayout.widget.DrawerLayout>

在NavigationView中将第三部分和第四部分进行组装,然后放在整个抽屉布局中即可。

主程序中进行加载和数据响应


class MainActivity : AppCompatActivity() {
    
    

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //绑定自定义的toolbar
        setSupportActionBar(toolbar)
        if(supportActionBar!=null){
    
    
            supportActionBar?.setDisplayHomeAsUpEnabled(true)
            supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_baseline_menu_24)
        }
        //当抽屉被拉开时,默认勾选电话
        nav_View.setCheckedItem(R.id.phone)
        //处理点击里面item之后的回调函数
        nav_View.setNavigationItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.phone ->{
    
    
                    Log.d("aa","点击了电话")
                }
                R.id.friends->{
    
    
                    Log.d("aa","点击了朋友信息")
                }
                R.id.email ->{
    
    
                    Log.d("aa","点击了邮箱")
                }
            }
            //只要点击了就进行关闭抽屉
            drawerLayout.closeDrawers()
            true
        }

    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
    
    
        menuInflater.inflate(R.menu.toolbar,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    

        when(item.itemId){
    
    
        //只要点击了这个id,就进行隐藏菜单的打开
            android.R.id.home->drawerLayout.openDrawer(GravityCompat.START)
            R.id.backup->{
    
    
                Log.d("aa","点击了备份按钮")
                Toast.makeText(this,"点击了备份按钮",Toast.LENGTH_SHORT).show()}
            R.id.delete->Toast.makeText(this,"点击了删除按钮",Toast.LENGTH_SHORT).show()
            R.id.setting->Toast.makeText(this,"点击了设置按钮",Toast.LENGTH_SHORT).show()
        }
        return true
    }
}

3悬浮式按钮和可变布局CoordinatorLayout

1悬浮式按钮

悬浮式按钮和其他普通按钮一样,没有任何区别,可以实现点击监听事件等功能
在这里插入图片描述

 <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_margin="16dp"
                android:src="@drawable/baseline_diamond_24"
                app:elevation="9dp"
                />
            <!--指定悬浮按钮的高度-->

主程序中绑定监听事件。

fab.setOnClickListener {
    
    view->

            Log.d("aa","点击了浮动按钮")
            //Snackbar是Material中可以交互的提示库,比Toast功能更加的强大
            Snackbar.make(view,"删除数据",Snackbar.LENGTH_SHORT).setAction("撤销"){
    
    
                Log.d("aa","点击了撤销删除按钮")
                Toast.makeText(this,"数据取消删除",Toast.LENGTH_SHORT).show()
            }.show()
        }

2CoordinatorLayout可以监听里面各个元素的布局

当里面元素出现遮挡时,可以自动监听里面的元素进行调整位置
在这里插入图片描述
实现方法很简单,直接将需要监听的元素放在此布局内部即可

			<androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
            需要监听的布局元素
            </androidx.coordinatorlayout.widget.CoordinatorLayout>

4卡片式布局和下拉刷新列表

需要使用到RecyclerView来实现卡片式的布局
第一步引入RercyclerView的依赖

 //加入RecyclerView的库
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    //Glide是一个强大的开源图片加载库,不仅可以用于加载本地图片,而且可以加载网络图片,gif和本地视频
    implementation 'com.github.bumptech.glide:glide:4.9.0'
     //下拉刷新RecyclerView
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'

第二步,绘制Recycler的子布局,使用MaterialCardView

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/fruitImage"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop"/>

        <TextView
            android:id="@+id/fruitName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp"/>

    </LinearLayout>


</com.google.android.material.card.MaterialCardView>

第三步 在主布局中加入RecyclerView,因为要下拉刷新,所以将RecyclerView放在SwipeRefreshLayout下,因为牵扯到列表遮挡ToolBar的问题,所以引入AppBarLayout

<?xml version="1.0" encoding="utf-8"?>

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--这里是主布局-->
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
<!--AppBarLayout可以处理遮挡toorbar的问题-->
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/purple_500"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                />
            <!--表示滑动时Toolbar会进行隐藏显示和自定义调整-->

        </com.google.android.material.appbar.AppBarLayout>

        <!--下拉刷新的布局-->
        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <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.swiperefreshlayout.widget.SwipeRefreshLayout>




        <!--<com.njupt.materialdesign.util.DragFloatActionButton-->
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/baseline_diamond_24"
            app:elevation="9dp" />
        <!--指定悬浮按钮的高度-->
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <!--这里是隐藏的布局滑动的菜单-->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_View"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu" />

</androidx.drawerlayout.widget.DrawerLayout>

第四步,编写水果类的实体类和准备图片资源,图片资源网上下载放在drawable目录下即可

class Fruit(val name:String,val imageId:Int) {
    
    
}

第五步,编写Adapter

package com.njupt.materialdesign.util

import android.content.Context
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
import com.njupt.materialdesign.R
import com.njupt.materialdesign.entity.Fruit


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

    inner class ViewHolder(view:View):RecyclerView.ViewHolder(view){
    
    
        var fruitImage=view.findViewById<ImageView>(R.id.fruitImage)
        var fruitName=view.findViewById<TextView>(R.id.fruitName)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    
    

        val view=LayoutInflater.from(parent.context).inflate(R.layout.fruit_item,parent,false)
        return ViewHolder(view)
    }



    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    
    
        val fruit=fruitList[position]
        holder.fruitName.text=fruit.name
        //使用这个图片工具进行绑定图片
        Glide.with(context).load(fruit.imageId).into(holder.fruitImage)
    }

    override fun getItemCount(): Int {
    
    
        return fruitList.size
    }
}

第六步编写主程序进行数据的准备,adapter的适配和下拉刷新的程序

package com.njupt.materialdesign

import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.njupt.materialdesign.entity.Fruit
import com.njupt.materialdesign.util.FruitAdapter
import kotlinx.android.synthetic.main.activity_main.*
import kotlin.concurrent.thread

class MainActivity : AppCompatActivity() {
    
    

    val fruits= mutableListOf(Fruit("苹果",R.drawable.apple),Fruit("橙子",R.drawable.orange)
    , Fruit("香蕉",R.drawable.banana),Fruit("荔枝",R.drawable.lizhi),Fruit("樱桃",R.drawable.cherry)
    , Fruit("哈密瓜",R.drawable.hamigua), Fruit("蓝莓",R.drawable.lanmei),Fruit("柠檬",R.drawable.lemon)
    , Fruit("猕猴桃",R.drawable.mihoutao), Fruit("桃子",R.drawable.peach), Fruit("草莓",R.drawable.strewbarry)
        , Fruit("葡萄",R.drawable.puple)
    )
    val fruitList=ArrayList<Fruit>()


    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //绑定自定义的toolbar
        setSupportActionBar(toolbar)
        if(supportActionBar!=null){
    
    
            supportActionBar?.setDisplayHomeAsUpEnabled(true)
            supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_baseline_menu_24)
        }
        //当抽屉被拉开时,默认勾选电话
        nav_View.setCheckedItem(R.id.phone)
        //处理点击里面item之后的回调函数
        nav_View.setNavigationItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.phone ->{
    
    
                    Log.d("aa","点击了电话")
                }
                R.id.friends->{
    
    
                    Log.d("aa","点击了朋友信息")
                }
                R.id.email ->{
    
    
                    Log.d("aa","点击了邮箱")
                }
            }
            Toast.makeText(this,"点击了电话按钮",Toast.LENGTH_SHORT).show()
            drawerLayout.closeDrawers()
            true
        }

        //实现动态移动的悬浮按钮

        fab.setOnClickListener {
    
    view->

            Log.d("aa","点击了浮动按钮")
            //Snackbar是Material中可以交互的提示库,比Toast功能更加的强大
            Snackbar.make(view,"删除数据",Snackbar.LENGTH_SHORT).setAction("撤销"){
    
    
                Log.d("aa","点击了撤销删除按钮")
                Toast.makeText(this,"数据取消删除",Toast.LENGTH_SHORT).show()
            }.show()
        }

        //绑定RecyclerView
        initFruits()
        val layoutManager=GridLayoutManager(this,3)
        recyclerView.layoutManager=layoutManager
        val adapter=FruitAdapter(this,fruitList)
        recyclerView.adapter=adapter

        //下拉刷新功能
        swipeRefresh.setColorSchemeResources(R.color.teal_700)
        swipeRefresh.setOnRefreshListener {
    
    
            refreshFruit(adapter)
        }



    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
    
    
        menuInflater.inflate(R.menu.toolbar,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    

        when(item.itemId){
    
    
            android.R.id.home->drawerLayout.openDrawer(GravityCompat.START)
            R.id.backup->{
    
    
                Log.d("aa","点击了备份按钮")
                Toast.makeText(this,"点击了备份按钮",Toast.LENGTH_SHORT).show()}
            R.id.delete->Toast.makeText(this,"点击了删除按钮",Toast.LENGTH_SHORT).show()
            R.id.setting->Toast.makeText(this,"点击了设置按钮",Toast.LENGTH_SHORT).show()
        }
        return true
    }
    //初始化水果参数
    private fun initFruits(){
    
    

        fruitList.clear()
        //随机挑选50个水果放在集合中
        repeat(50){
    
    
            val index=(0 until fruits.size).random()
            fruitList.add(fruits[index])
        }
    }
    private fun refreshFruit(adapter: FruitAdapter){
    
    
        //模仿网络请求进行刷新
        thread{
    
    
            Thread.sleep(2000)
            runOnUiThread{
    
    

                initFruits()
                //模仿在加一个苹果
                fruitList.add(fruits[1])
                adapter.notifyDataSetChanged()
                swipeRefresh.isRefreshing=false
            }
        }
    }
}

结果展示

在这里插入图片描述

下滑时Toolbar消失
在这里插入图片描述

往下滑时,开始刷新。
在这里插入图片描述

5可折叠式的标题栏CollapsingToolbarLayout

点击上述图片时,跳转到细节界面时的优美展示
在这里插入图片描述
第一步:绘制上图的布局
这里需要的布局很多,新建当前界面的layout名为fruit_layout.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >
    <!--android:fitsSystemWindows="true"让背景图能够和系统状态栏融合-->

    <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/design_default_color_primary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true">

            <!--app:contentScrim属性用于指定CollapsingToolbarLayout在趋于折叠状态以及折叠之后的背景色,
            其实CollapsingToolbarLayout在折叠之后就是一个普通的Toolbar,那么背景色肯定应该是colorPrimary
            了,具体的效果我们待会儿就能看到。app:layout_scrollFlags属性我们也是见过的,只不过之前是给Toolbar
            指定的,现在也移到外面来了。其中,scroll表示CollapsingToolbarLayout会随着水果内容详情的滚动一起滚
            动,exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就保留在界面上,不再移
            出屏幕。-->
            <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" />
            <!--可以看到,我们在CollapsingToolbarLayout中定义了一个ImageView和一个Toolbar,也就
意味着,这个高级版的标题栏将是由普通的标题栏加上图片组合而成的。这里定义的大多数属
性我们是已经见过的,就不再解释了,只有一个app:layout_collapseMode比较陌生。它用
于指定当前控件在CollapsingToolbarLayout折叠过程中的折叠模式,其中Toolbar指定成
pin,表示在折叠的过程中位置始终保持不变,ImageView指定成parallax,表示会在折叠的
过程中产生一定的错位偏移,这种模式的视觉效果会非常好。-->

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <!--学过ScrollView的用法,它允许使用滚动的方式来查看屏幕以外的
数据,而NestedScrollView在此基础之上还增加了嵌套响应滚动事件的功能。由于
CoordinatorLayout本身已经可以响应滚动事件了,因此我们在它的内部就需要使用
NestedScrollView或RecyclerView这样的布局。另外,这里还通过app:layout_behavior
属性指定了一个布局行为,-->

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

            <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>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@drawable/baseline_diamond_24"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end"/>
    <!--可以看到,这里加入了一个FloatingActionButton,它和AppBarLayout以及
NestedScrollView是平级的。FloatingActionButton中使用app:layout_anchor属性指定
了一个锚点,我们将锚点设置为AppBarLayout,这样悬浮按钮就会出现在水果标题栏的区域
内,接着又使用app:layout_anchorGravity属性将悬浮按钮定位在标题栏区域的右下角。
-->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

第二步给主界面中水果列表绑上点击监听事件

package com.njupt.materialdesign.util

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
import com.njupt.materialdesign.FruitActivity
import com.njupt.materialdesign.R
import com.njupt.materialdesign.entity.Fruit


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

    inner class ViewHolder(view:View):RecyclerView.ViewHolder(view){
    
    
        var fruitImage=view.findViewById<ImageView>(R.id.fruitImage)
        var fruitName=view.findViewById<TextView>(R.id.fruitName)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    
    

        val view=LayoutInflater.from(parent.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
    }



    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    
    
        val fruit=fruitList[position]
        holder.fruitName.text=fruit.name
        //使用这个图片工具进行绑定图片
        Glide.with(context).load(fruit.imageId).into(holder.fruitImage)
    }

    override fun getItemCount(): Int {
    
    
        return fruitList.size
    }
}

第三步:当前展示界面的Activity代码

package com.njupt.materialdesign

import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.toolbar
import kotlinx.android.synthetic.main.fruit_activity.*

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.fruit_activity)
        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)
}

猜你喜欢

转载自blog.csdn.net/m0_56184347/article/details/129834214