JetPack Material Design 組件簡單介紹

基于最新的 com.google.android.material:material:1.4.0-alpha01。因?yàn)闆]有release,所以只是介紹了解,以后release了可以直接使用

1.BadgeDrawable

未讀消息數(shù)和右上角小紅點(diǎn)

        findViewById<TextView>(R.id.txt).post {
            val badgeDrawable = BadgeDrawable.create(this)
            badgeDrawable.number = 15
            badgeDrawable.badgeTextColor = Color.BLACK
            badgeDrawable.badgeGravity = BadgeDrawable.BOTTOM_END
            badgeDrawable.isVisible = true
            badgeDrawable.horizontalOffset = 100//如果沒有下面兩句,BadgeDrawable 會在右下角
            badgeDrawable.verticalOffset = 100
            BadgeUtils.attachBadgeDrawable(badgeDrawable, findViewById(R.id.txt));
        }

注意點(diǎn):

    1. attachBadgeDrawable 需要 UnsafeExperimentalUsageError 注釋,這也是沒有release的鍋
    1. attachBadgeDrawable方法都必須在anchor創(chuàng)建以后才能用,也就是不能在onCreate里調(diào)用這些方法,或者你要view.post調(diào)用,保證anchor已經(jīng)繪制好了


      BadgeDrawable.png

2.FloatingActionButton && ExtendedFloatingActionButton

這個應(yīng)該比較眼熟了,但是和support庫還是有區(qū)別的

<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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@android:drawable/ic_btn_speak_now"
        app:backgroundTint="@color/design_default_color_error"
        app:fabCustomSize="50dp" />

    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="100dp"
        android:text="12131"
        app:icon="@android:drawable/ic_btn_speak_now"/>

    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="200dp"
        android:text="12131"
        app:icon="@android:drawable/ic_btn_speak_now"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

注意

FloatingActionButton

  • backgroundTint 前面必須是app,不然不會生效,具體看代碼,里面是空的
  • android:src 設(shè)置的icon,如果沒有 fabCustomSize 會導(dǎo)致位置偏移。而且 fabCustomSize 屬性值必須和 width,height 一致

ExtendedFloatingActionButton

  • app:icon 設(shè)置圖標(biāo)而不是 android:src
  • 設(shè)置 wrap_content 會讓text icon全部顯示出來。但是如果不設(shè)置 wrap_content,比如固定值,會導(dǎo)致 icon 出現(xiàn)細(xì)小的偏移
FloatingActionButton & ExtendedFloatingActionButton.png

3.BottomAppBar

其實(shí)就是個底部的 ToolBar,但是搭配 FloatingActionButton 可以有別樣的效果

        val mBottomAppBar = findViewById<BottomAppBar>(R.id.bottomappbar)
        val size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32f, resources.displayMetrics)
        val triangleEdgeTreatment = TriangleEdgeTreatment(size, true)
        val builder = ShapeAppearanceModel().toBuilder()
        builder.setTopEdge(triangleEdgeTreatment)//添加倒三角
        val materialShapeDrawable = MaterialShapeDrawable(builder.build())
        mBottomAppBar?.background = materialShapeDrawable

layout代碼

<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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomappbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:fabAlignmentMode="center"
        app:fabCradleMargin="10dp"
        android:layout_gravity="bottom"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_anchor="@id/bottomappbar" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

展示樣子

BottomAppBar.png

PS:BottomAppBarCutCornersTopEdge 這個類可以將 FloatingActionButton 變成菱形,但是 getEdgePath 里面的 getFabDiameter 返回是 0,而且對應(yīng)的 set 方法是 RestrictedApi。暫時無法處理。最終的理想效果在【譯】Android材質(zhì)組件的動手實(shí)踐:Bottom App Bar 這篇文章最下面

4.BottomNavigationView

用法和之前的 NavigationBarView 基本一致。主要是要注意涉及到小紅點(diǎn)

        val mBnv = findViewById<BottomNavigationView>(R.id.bnv)
        val badgeDrawable = mBnv.getOrCreateBadge(R.id.action_favorites)
        badgeDrawable.number = 5
        // mBnv.removeBadge(R.id.action_favorites)

示例如下


BottomNavigationView.png

5.BottomSheetBehavior

底頁是包含補(bǔ)充屏幕內(nèi)容的表面組件。它們固定在屏幕底部(使它們在移動/平板電腦設(shè)備上符合人體工程學(xué)),并且類似于Dialogs,它們位于主屏幕內(nèi)容上方。在大多數(shù)情況下,可以通過向上/向下拖動手勢來擴(kuò)展/關(guān)閉它們。

        val llBottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet)
        val bottomSheetBehavior: BottomSheetBehavior<LinearLayout> = BottomSheetBehavior.from(llBottomSheet)
        //默認(rèn)的折疊狀態(tài), bottom sheets只在底部顯示一部分布局。顯示高度可以通過 app:behavior_peekHeight 設(shè)置(默認(rèn)是0)
        bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
        //不折疊,全部展開內(nèi)容
        // bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        bottomSheetBehavior.isHideable = false//一般是false。如果設(shè)為true,當(dāng) state == STATE_COLLAPSED,然后用戶繼續(xù)往下滑的話會導(dǎo)致整個view徹底消失再也無法滑動出現(xiàn)
        bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, newState: Int) {
            }
            override fun onSlide(bottomSheet: View, slideOffset: Float) {
            }
        })

layout文件在這里

<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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="7300dp"
        android:background="@android:color/darker_gray"
        android:orientation="vertical"
        app:behavior_hideable="true"
        app:behavior_peekHeight="80dp"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="測試第一行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="center"
            android:text="測試第二行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="測試第三行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="center"
            android:text="測試第四行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="測試第五行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="center"
            android:text="測試第六行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="測試第七行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="center"
            android:text="測試第八行"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="測試第九行"
            android:textColor="@android:color/white" />
    </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

示意圖


BottomSheetBehavior.gif

6.BottomSheetDialog

IOS的很多菜單都是從底部彈出的,這種展示方式還是很好看的,而丑爆的Android默認(rèn)彈框一直都是大家一定要摒棄的,那么我們Android如何做出相應(yīng)效果的彈框(其實(shí)這個類已經(jīng)沒啥意義了,一般的老項(xiàng)目肯定存在類似的控件)

    private fun initDialog() {
        val bottomSheetDialog = BottomSheetDialog(this)
        bottomSheetDialog.setContentView(R.layout.dialog_layout)
        bottomSheetDialog.show();
    }

dialog_layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:alpha="0.8"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="item1"
        android:textColor="@android:color/white"
        tools:ignore="HardcodedText" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="item2"
        android:textColor="@android:color/white"
        tools:ignore="HardcodedText" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        android:text="item3"
        android:textColor="@android:color/white"
        tools:ignore="HardcodedText" />
</LinearLayout>

示意圖


BottomSheetDialog.gif

7.MaterialButton

這個相對簡單,沒啥介紹的,唯一有亮點(diǎn)的地方就是含有icon的button,但其實(shí)這些一般都會在項(xiàng)目里面有,而且也用不到那么多的功能

8.MaterialCardView

這個和CardView差別也不大,主要是背景色的設(shè)置有區(qū)別,是app開頭的屬性

9.MaterialCheckBox

這個和CheckBox可以說完全沒有區(qū)別,繼承自AppCompatCheckBox,基本沒加方法

10.Chip && ChipGroup

其實(shí)就是我們熟悉的流式布局FlowLayout。ChipGroup 可以設(shè)置橫向和縱向間距。Chip 就是布局中的每個item。下面這段代碼就來展示常用的屬性

    <com.google.android.material.chip.ChipGroup
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.chip.Chip
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="背景色"
            app:chipBackgroundColor="@color/colorPrimary" />

        <com.google.android.material.chip.Chip
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5dp圓弧"
            app:chipCornerRadius="5dp" />

        <com.google.android.material.chip.Chip
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="搜索icon"
            app:chipIcon="@android:drawable/ic_menu_search" />

        <com.google.android.material.chip.Chip
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="stroke"
            app:chipStrokeWidth="2dp"
            app:chipStrokeColor="@color/colorPrimaryDark"/>

        <com.google.android.material.chip.Chip
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="close icon"
            app:closeIconVisible="true"
            app:closeIcon="@android:drawable/ic_menu_close_clear_cancel"/>

    </com.google.android.material.chip.ChipGroup>

效果圖


Chip && ChipGroup.png

11.MaterialDatePicker

年月日的選擇器,用法

        val builder = MaterialDatePicker.Builder.datePicker()//單選
        //val builder = MaterialDatePicker.Builder.dateRangePicker()//多選,可以選擇時間范圍
        //val builder = MaterialDatePicker.Builder.customDatePicker()//自定義,暫時標(biāo)注RestrictTo
        val picker = builder.build()
        picker.show(supportFragmentManager, "date_picker_tag")

示例圖


MaterialDatePicker.gif

評價:太丑了,一般都和ios保持同步,所以一般用不到

12.ShapeableImageView

個人認(rèn)為沒啥意義,只是比(ImageView+自定義background)多了一個ShapeAppearanceModel屬性??梢酝ㄟ^style來配置,也可以通過代碼實(shí)現(xiàn)

ShapeAppearanceModel.builder()
            .setAllCorners(CornerFamily.ROUNDED,20f)
            .setTopLeftCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
            .setTopRightCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
            .setBottomRightCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
            .setBottomLeftCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
            .setAllCornerSizes(ShapeAppearanceModel.PILL)
            .setTopLeftCornerSize(20f)
            .setTopRightCornerSize(RelativeCornerSize(0.5f))
            .setBottomLeftCornerSize(10f)
            .setBottomRightCornerSize(AbsoluteCornerSize(30f))
            .build()

代碼接收一個ShapeAppearanceModel,通過構(gòu)建者模式實(shí)現(xiàn)

  • setTopLeft表示處理左上角,其他同理。
  • cornerSize表示設(shè)置的大小,有RelativeCornerSize和AbsoluteCornerSize,RelativeCornerSize構(gòu)造方法接收一個百分比,范圍0-1;AbsoluteCornerSize構(gòu)造方法接收一個具體數(shù)值,這個數(shù)值就是圓角的數(shù)值。
  • CornerFamily,它表示處理的方式,有ROUNDED和CUT兩種,ROUNDED是圓角,CUT是直接將圓角部分裁切掉.
  • setAllCornerSizes(ShapeAppearanceModel.PILL)可以直接實(shí)現(xiàn)圓形效果。

13. Slider

加強(qiáng)版的SeekBar.先上測試代碼

    <com.google.android.material.slider.Slider
        android:id="@+id/slider"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:value="0.3"
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:stepSize="0.1"
        app:tickColor="@android:color/holo_orange_dark"
        app:thumbColor="@android:color/holo_green_light"
        app:haloColor="@android:color/holo_blue_bright"
        app:trackColorActive="@android:color/black"
        app:trackColorInactive="@android:color/holo_red_dark" />

說明

  • tickColor是指刻度的顏色,必須指明stepSize大于0.0f,否則不顯示
  • thumbColor是指中間的進(jìn)度的圓圈顏色
  • haloColor是指長按以后thumb外圈的顏色
  • trackColor整個進(jìn)度條的顏色

上動圖


Slider.gif

14.SwitchMaterial

加強(qiáng)版的Switch。從功能來講,它還是有點(diǎn)丑,無法滿足日常開發(fā)需求,還是要自己定制。。。。。。

15.TextInputLayout

和android 5.0的時候推出的TextInputLayout差別不大,用法在這里

16.MaterialTimePicker

google自帶的時間選擇器,用法如下

            val builder = MaterialTimePicker.Builder()
            builder.setInputMode(MaterialTimePicker.INPUT_MODE_CLOCK)
            //builder.setInputMode(MaterialTimePicker.INPUT_MODE_KEYBOARD)
            val picker = builder.build()
            picker.show(supportFragmentManager, "click")

示例圖


MaterialTimePicker.gif

本人不推薦,主要有兩方面,第一,確實(shí)挺難看的,一般還是按照ios的來做,做成底部滾輪的那種。第二,builder的可配置項(xiàng)太少了,做不了什么修改

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容