Material_Design

13 篇文章 0 订阅
3 篇文章 0 订阅

Android Material Design

  • 今天就来谈谈 android 给我们提供的 Material 库的好用又好看的组件

ToolBar

  • ToolBar这个是来替代ActionBar的

    具体的做法很简单:

    1. 将主题的ActionBar设置为没有

    2. 然后在需要ToolBar的地方 放在他的布局文件里 在他的创建视图的时候 调用 **setSupportActionBar(binding.toolbar) **这个方法就可以了

      传入的就是在布局文件里定义的ToolBar

    看代码

在这里插入图片描述

  • 圈出来的地方就是要改变的地方

然后在代码中设置

setSupportActionBar(binding.toolbar) // 将ToolBar 用作 ActionBar
  • 由于ActionBar只有Activity才有 所以这个方法也只有Activity才有=
<androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/design_default_color_primary"
                android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar" //指定顶部栏是暗色主题
                app:popupTheme="@style/Theme.AppCompat.Light"/> //指定弹出来的菜单是浅色主题
  • 既然ActionBar有Action按键 那么ToolBar在Activity中也有 调用的方法还是一样的
//这个方法是将菜单布局加载到ToolBar上
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.toobal,menu)
        return true //返回TRUE表示加载完成
    }

//在Activity中重写这个方法,就可以实现ToolBar上有action按键的点击事件了
override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            R.id.backup -> Toast.makeText(this,"backup",Toast.LENGTH_SHORT).show()
            R.id.delete -> Toast.makeText(this,"delete",Toast.LENGTH_SHORT).show()
            R.id.setting -> Toast.makeText(this,"setting",Toast.LENGTH_SHORT).show()
        }
        return true//表示事件点击处理了
    }
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/backup"//这里
        android:icon="@drawable/ic_backup"
        android:title="BackUp"
        app:showAsAction="always"/> <!--表示永远显示到ToolBar上 但是空间不够就不显示-->

    <item
        android:id="@+id/delete"///这里
        android:icon="@drawable/ic_delete"
        android:title="Delete"
        app:showAsAction="ifRoom"/> <!--表示 如果空间足够才显示,空间不够就不显示-->


    <item
        android:id="@+id/setting"//这里
        android:icon="@drawable/ic_settings"
        android:title="Delete"
        app:showAsAction="never"/> <!--不在ToolBar上显示-->

</menu>
  • ToolBar设置一个homeAction按键 默认的图标是一个返回键
  • 但是我们可以自定义修改
supportActionBar?.let{
            it.setDisplayHomeAsUpEnabled(true) //这个表示显示Home Action按键
            it.setHomeAsUpIndicator(R.drawable.align) //这个重新设置Home Action的图标
        }
  • 然后就是设置这个按键的点击事件了
override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            android.R.id.home -> binding.drawerLayout.openDrawer(GravityCompat.START) //看这里
            R.id.backup -> Toast.makeText(this,"backup",Toast.LENGTH_SHORT).show()
            R.id.delete -> Toast.makeText(this,"delete",Toast.LENGTH_SHORT).show()
            R.id.setting -> Toast.makeText(this,"setting",Toast.LENGTH_SHORT).show()
        }
        return true
    }
  • 只要他还是个ToolBar 那么他的点击事件的响应就要在 onOptionsItemSelected 这个方法进行处理
  • 注意 : home的id 是系统指定的 : android.R.id.home

滑动菜单 — DrawerLayout

  • 就是将菜单选项隐藏起来,不放置在主屏幕上,通过滑动的方式来显示

  • DrawerLayout 只允许有两个直接子控件 第一个控件 : 在主屏幕中显示内容,第二个子控件显示滑动菜单中的内容

  • 唯一值得注意的是 必须指定 第二个控件的layout_gravity 并且只能是一个方向

NavigationView

  • 这里先说明一些 无关的东西
  • NavigationView 是 Material库中的所以的添加依赖
dependencies {
    implementation 'com.google.android.material:material:1.5.0'
}
  • 因为使用了NavigationView 使用到了Material库中的东西 就得将应用的主题换成 Material的
  • 具体就是

  • 这个就是整个应用的主体

  • 改成 Theme.MaterialComponents.DayNight.DarkActionBar

  • 现在继续来介绍 NavigationView

    他主要分为两个部分 一个 headerlayout 一个是 menu

    通过名字可以发现 : headerlayout 是一个布局 menu是一个菜单

    看代码

     <com.google.android.material.navigation.NavigationView
            android:id="@+id/navView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            <!--注意是app的命名空间-->
            app:menu="@menu/nav_menu" //引用了一个menu
            app:headerLayout="@layout/nav_header"/> <!-- 引用了一个布局-->
    
    //nav_menu
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single"> //这里的single的意思是里面的选项只能单选
            <item
                android:id="@+id/navCall"
                android:icon="@drawable/nav_call"
                android:title="Call"/>
    
    
            <item
                android:id="@+id/navFriends"
                android:icon="@drawable/nav_friends"
                android:title="Friends"/>
    
            <item
                android:id="@+id/navLocation"
                android:icon="@drawable/nav_location"
                android:title="Location"/>
    
            <item
                android:id="@+id/navMail"
                android:icon="@drawable/nav_mail"
                android:title="Mail"/>
    
            <item
                android:id="@+id/navTask"
                android:icon="@drawable/nav_task"
                android:title="Task"/>
        </group>
    
    
    </menu>
    
    
    
    //nav_header
    <?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:background="@color/design_default_color_primary">
    
        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/iconImage"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:src="@drawable/nav_icon"
            android:layout_centerInParent="true"/>
    
        <TextView
            android:id="@+id/mailText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="tonygreendev@gmail.com"
            android:textColor="#FFF"
            android:textSize="14sp"/>
    
        <TextView
            android:id="@+id/userText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/mailText"
            android:text="Tony Green"
            android:textColor="#FFF"
            android:textSize="14sp"/>
    
    </RelativeLayout>
    
    • 然后为菜单选项键设置监听事件
    binding.navView.setCheckedItem(R.id.navCall) //这个来设置默认的选择
    binding.navView.setNavigationItemSelectedListener {
        //设置监听事件的
        when(it.itemId){
            R.id.navCall -> Toast.makeText(this,"电话",Toast.LENGTH_SHORT).show()
            R.id.navFriends -> Toast.makeText(this,"朋友",Toast.LENGTH_SHORT).show()
            R.id.navLocation -> Toast.makeText(this,"地址",Toast.LENGTH_SHORT).show()
            R.id.navMail -> Toast.makeText(this,"邮箱",Toast.LENGTH_SHORT).show()
        }
        binding.drawerLayout.closeDrawers()//关闭滑动菜单
        true//表示事件已经处理
    }
    

悬浮式按键 — FloatingActionButton

  • 这个可以做一种悬浮的效果 而且还有阴影

  • 这个按键没有什么特别的 还是一个按键 有这样几个属性值得关注

  • layout_gravity : 可以指定这个按键位于他父控件的那个位置 前提是他的父容器支持

<com.google.android.material.floatingactionbutton.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"/>//位于锚点的位置

他的点击事件的监听很简单和按键基本没啥区别

binding.fab.setOnClickListener { view ->
           /*这个等下介绍*/ Snackbar.make(view,"Data Deleted",Snackbar.LENGTH_SHORT).setAction("Undo"){
                Toast.makeText(this,"Data restored",Toast.LENGTH_SHORT).show()
            }.show()
        }

Snackbar — 可以交互的Toast

  • 众所周知Toast只能显示通知不能和用户交互 而SnackBar就是既可以和用户交互又可以显示同时显示通知
Snackbar.make(view,"Data Deleted",Snackbar.LENGTH_SHORT)/*这一部分就是和Toast很类似 Data Deleted 是显示的内容 Snackbar.LENGTH_SHORT显示的时长view: 这个注意一下*/.setAction("Undo"){
    //这一部分就是设置的一个按键 (Undo是名字)
    //lambda是点击的响应逻辑
    Toast.makeText(this,"Data restored",Toast.LENGTH_SHORT).show()
            }.show()
  • view : 是将一个视图传给他 他会自动去找根视图的,来展示信息 这个view是用来指定 Snackbar是基于谁触发的

CoordinatorLayout

  • 这个就是一个加强版的FrameLayout 他可以监听子控件的各种事件并将我们作出合理的响应
<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
		<!--这个布局的作用是 悬浮按键-->
        <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/ic_done"
            android:elevation="8dp"/>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 这样就可以监听了悬浮按键的点击事件

    在上面的代码中我们点击按键会弹出一个通知 那么这个时候就会自动然悬浮按键上移 流出一个通知的位置

卡片式布局 — MaterialCardView

  • 这个布局的实质也还是FrameLayout 只是提供了阴影和圆角的效果
<androidx.cardview.widget.CardView 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:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/fruitImage"
            android:layout_width="wrap_content"
            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>

</androidx.cardview.widget.CardView>

AppBarLayout

  • 实际上是一个垂直方向上的LinearLayout 内部做了很多滚动事件的封装
  • 滚动事件的处理要用到两个布局
<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/design_default_color_primary"
                android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar"
                app:popupTheme="@style/Theme.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways|snap" //这个就是用来指定滚动时ToolBar的显示 />

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



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

  • 在要监听的滚动事件的组件上加上 app:layout_behavior="@string/appbar_scrolling_view_behavior" 就可以了 那么当RecyclerView 滚动的时候 APPBar会作出相应的响应
  • scroll — 滚动是消失
  • enterAlways — 向上移动时显示
  • snap — 隐藏或显示一部分时 自动判断是显示还是隐藏

SwipeRefershLayout —下拉刷新的布局

  • 想要实现下拉刷新的效果只需要在需要的布局外套一个 SwipeRefershLayout 这个布局就可以

  • 注意 : 必须添加依赖 :

    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
    
  • 具体的刷新逻辑得靠我们自己来实现

private fun refreshFruits(adapter:FruitAdapter){
        thread{
            Thread.sleep(2000)
            runOnUiThread {
                initFruit()
                adapter.notifyDataSetChanged() //这个就是让列表项全部刷新
                binding.swipeRefresh.isRefreshing = false //这个的意思是刷新完成后 隐藏刷新的那个图标
            }
        }
    }

//设置刷新的处理时间
binding.swipeRefresh.setOnRefreshListener {
            refreshFruits(binding.recyclerView.adapter as FruitAdapter)
        }

可折叠的标题栏 — CollapsingToolbarLayout

  • 是一个作用域Toolbar基础之上的布局 它不仅仅是展示一个标题了还可以有很多的效果
  • 但是 : 他不能单独存在 他只能是AppbarLayout的直接子布局 而 APPBarLayout又只能是CoordinatorLayout的直接子布局
<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="150dp" // 这个可以随便指定
        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/Theme.AppCompat.DayNight.DarkActionBar"
            app:contentScrim="@color/design_default_color_primary"
            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>
  • app:layout_collapseMode=“parallax” 这个属性是来指定折叠时的动画效果 parallax 产生一定的错位偏移 pin 就是位置保持不变
  • app:contentScrim="@color/design_default_color_primary" : 用来指定趋于折叠状态时 和 折叠时的状态的背景色
  • app:layout_scrollFlags=“scroll|exitUntilCollapsed” 因为 CollapsingToolbarLayout 是APPBarLayout的子布局 所以他会根据APPBarLayout 监听到滚动事件来对子布局产出一定的响应 exitUntilCollapsed 这个就是折叠完成后就不在移出屏幕

NestedScrollView

  • 这个视图只是在ScrollView的基础上可以嵌套在一个可以响应滚动事件的的功能
<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="150dp"
        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/Theme.AppCompat.DayNight.DarkActionBar"
            app:contentScrim="@color/design_default_color_primary"
            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.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">

            <androidx.cardview.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/fruitContentText"
                    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: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"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • **app:layout_behavior="@string/appbar_scrolling_view_behavior" ** 这个滚动的事件会被APPBarLayout监听到 然后他的子控件对这个滚动的事件能作出响应

  • 重复利用状态栏的空间 : 可以设置属性 : android:fitsSystemWindows=“true” 来让控件出现在状态栏中 如果你想让一个控件在状态栏中显示 那么你就得让他的全部父控件都添加这个属性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值