谈Material Design样式的控件

一个讲讲Material Design相关控件的一个文章,随缘更新:<
列了但是没有写的表示我想说这个控件,不过还在写:>

搞了大半天的tomcat+servlet,对于bot还是一筹莫展,内心有点无奈,选择来折腾一下ui

在很久以前Google就已经开始提倡Android的UI设计向Material Design的方向发展。所以说一些相关的控件也在陆陆续续的进行推出,除了投入使用的Tab LayoutNavigation ViewsSnake Bar等,还推出了一些推广度并不高,但是使用效果的一些控件。
根据官方的更新记录来看,这些东西大部分都是在5月的时候推出了……(消息过于滞后),不过应该是最近才作为design包的一部分(即28.0.0版本),需要配合Android Pie进行开发,同时整个工程的style需要转换为Material Design相关的(详见官网内容)
另外一提,在这里推一下Material Design官网,正常来说可以直接访问,如果图加载不出来的话,推荐科学上网。

Material Button

我们知道,Button这个控件在我们的开发之中是异常必要的,但是很多时候因为原生Button/ImageButton自身的限制让我们不得不有些时候采用ImageView/TextView+shape这样的操作来还原设计图上面的形式,但是有些时候这样画UI也异常烦躁。

而这个时候Material Button在某种程度上解决了我们的一些自定义设置问题

  • 按钮圆角弧度自定义
  • 可在文字旁边添加icon
  • 纯文字无背景Button
  • 可描边
  • 扩展style增加
  • etc…

跟原生button的差异
在原生button里面内置了4dp的左右padding值,但是这个padding值在material button之中是没有的,如果像恢复到原生button的内置padding,可通过insetLeftinsetRight设置为4dp或者其他值即可
当然,也可以通过其他方式来修正由于material button的引入而造成的差异

在这里只是简单的介绍一些调用的api,更多的去官网或者developer Android查阅吧(笑

注:Material Button的颜色还是跟随你所选用的主题里面的@color/colorPrimaryDark所对应的颜色,如果需要改变请直接在style里面改变对应的颜色或者通过backgroudTint来指定背景颜色

  • cornerRadius
    顾名思义,这个是设置按钮的圆角半径,根据自己需求进行更改即可

  • icon
    通过该方式在Botton内部添加一个icon,默认的放置是在Button的最左边,如果需要更改icon的其他设置的话需要修改icon的对应属性即可。(例如通过gravity/tint/tintMode等属性设置来对icon的展示进行修改)

  • strokeWidth/strokeColor
    设置该Button的描边宽度以及描边的颜色

  • style
    针对于新出的material button,官方设置了很多style来应对于不同的情况,也导致了material button在原生Button的基础上可使用到的方面更多,在这里列举在官方网站中提及的,并作一定的介绍

    • Filled, elevated button(填充以及有阴影的)
      这个是material button导入目前布局的时候一种默认的sytle(即背景+阴影)
      在md之中,推荐一般用于完成一系列操作的提示,譬如保存操作和完成操作。可以通过设置style@style/Widget.MaterialComponents.Button或直接采用默认值达到该目的

      默认样式效果图

      default

    • Filled, unelevated button(填充的,无阴影的)
      这个与默认的Button模式来说只是去掉了阴影显示而已,让这个Button平面化,不再会有因为立体感而导致整个界面显得不协调的情况。可以设置style@style/Widget.MaterialComponents.Button.UnelevatedButton来进行设置

      无阴影样式效果图

      unelevated

    • Text Button(无背景/阴影,仅展示文字)
      这种Button的产生就是解决了我们很多时候需要一种纯文字+icon展现给用户的一种形式,同时配合描边,使用效果更佳。
      在整体的页面设计之中,可以将这个部分用于次重要的一些入口引入,或者其他功用。
      当然令人惊讶的是这个点击依然还是有md特有的水波纹效果,这个时候水波纹的颜色与@color/colorPrimaryDark的样色相同。可以设置style@style/Widget.MaterialComponents.Button.TextButton来进行设置

      只有文字效果图

      text

      有描边样式效果图

      text-with-stroke

    • Icon Button(含有icon)
      这个是针对上述每一种Button的一种扩展,意思是当你的Button加入了icon之后并引入了这个sytle,会自动进行一定的调整以求达到整个按钮上面的视觉平衡。
      如果需要使用的话,直接在原本的style的基础之上添加.Icon即可

      比较图:(上面的icon是添加了icon字段的情况)

      默认:

      default

      无阴影:

      unelevated

      纯文字:

      text

      有描边:

      text-with-stroke

      当然,style也不只这些:>有兴趣的朋友们可以利用Android Studio的自动补全进行效果查看以及研究

  • rippleColor
    设置水波纹的颜色,如果不需要大概设置一个透明色就可以了:>

注意:上面提到了除了style其他的都是material button自己引入的一些属性,需要以app字段开头才能够找到对应的方法:>

BottomAppBar

看见AppBar这个词汇,可能大多数人的第一反应就是联想到CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+Toolbar的形式,通过设置scrollFlag以及相对应的RecyclerView或者NestedScrollView来达到头部展现的部分随着用户滚动回收成一个Toolbar的样式。
而上面我所叙述的部分,在Material Design里面是被称作了Top AppBar进行了粗略的介绍,然后给出了CollapsingToolbarLayout的相关连接。大概知道了这个就是这么联动使用的吧:>

但是今天我想提的是另外一个东西,也就是小标题所示的Bottom AppBar
虽然你想问,谁会把导航栏直接这么简单粗暴的放在下面啊?这不是非常奇怪的事情吗?假如说做Fragment相关的导航也应该是Botton Navigation,那这个Bottom AppBar存在的意义是什么呢?

啊,当你看见这个动画的时候你可能就惊艳于Material Design的神奇了吧_(:з」∠)_

bottomappbar+fab

难道!!就没有觉得这个很酷吗???(
反正我是被这样的效果给震撼到了o<-<,我不管,是真的很酷,而且我个人认为这样的设计方案在某些情景之中是可以用到的(例如说一个通讯录管理,完全可以把一些集中的操作点放在下端,使得用户不用专门要把手移上去点对不对,反正我觉得没什么毛病。
说不定这个效果配合FloatActionBotton里面一些相关的behavior能够打造出来更加酷炫的效果(不管啦我就是要吹爆它

而这个的主要构成也仅仅是通过一个BottomAppBar+FloatActionBar进行的组成
上面图片对应的示例代码见下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- something else, like recycler view -->

<android.support.design.bottomappbar.BottomAppBar
android:id="@+id/bab_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:hideOnScroll="true"
app:navigationIcon="@drawable/ic_arrow_back_black_24dp"
app:fabAlignmentMode="end"
app:backgroundTint="@color/colorPrimaryDark">

</android.support.design.bottomappbar.BottomAppBar>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_build_black_24dp"
app:backgroundTint="@color/colorPrimary"
app:layout_anchor="@id/bab_bottom"
/>

</android.support.design.widget.CoordinatorLayout>

显然,在这个里面主要是通过layout_anchor这个设置使得fab能够跟这个appBar进行了关联并使用了内嵌的方式将东西给展现出来,同时在通过不同的设置对fab在整个appBar里面进行位置的偏移以及其他的设置。
在这里就大概提一下吧_(:з」∠)_

  • fabAlignmentMode
    设置fab在appBar里面的对齐方式,有两个参数:center/end
  • fabCradleMargin
    更改fab与bar之间的距离,值越大fab与bar之间的空隙会越大
  • fabCradleRoundedCornerRadius
    更改bar中进入凹陷的时候的拐角部分的弧度
  • fabCradleVerticalOffset
    更改fab与bar之间的垂直偏移量,默认为0,即fab的一半左右是在bar以内
    不能够通过设置负数以达到fab全部陷入bar的目的
  • hideOnScroll
    在滚动的时候收起bar,效果同上面的gif图
    注意,该属性必须要在外面嵌套一个CoordinatorLayout才能够达到相应的behavior的目的
    给自己暗戳戳贴一个源码地址,等什么时候有空了去研究一下这个view是怎么做出来的(对于内陷效果异常好奇了.jpg)
    当然,它也能当做一个普通的Toolbar使用(大概是不会有人用的吧)

Chip/ChipDrawable/ChipGroup

未完成,每次看都有很大的不一样,因为自己折腾的demo没写完导致缓更拖延症

Chip

Chip在翻译之中被称为“小片/薄片”,这也应该是为什么Chip出现的原因了吧。它的整个UI设计就是如同薄片一般,同时也有点击反馈,同时响应点击事件。
defaultChip
有人可能会说这样不就是跟material button里面没有阴影的style非常相似吗?相似是相似,但是两个的作用差异还是很大的,不要着急,听我一一道来:>

首先两个面向的方面不一样,一个是面向的一个流程完成了之后的一个确定,譬如说Save,但是Chip是可以用一定的范围来表示一定的需要展示的内容,这个就可以参见iOS系统在发送消息的时候显示的联系人部分,就跟这种Chip很相似,而且一些扩展功能也能够实现这样的效果。

首先就是在style样式上定制的区别啦:>

  • Action Chip
    style="@style/Widget.MaterialComponents.Chip.Action"
    这个是每个chip里面的一种默认的形式,形式就如同上面展示的simple chip一般用于触发与主要内容上下文相关的动作,譬如来说一种联系人条目,或者是一些下方的显示选项
    当然有些时候也可以相应点击事件,在修改了内容之后同步到这个chip本身的内容里面去,这个样子。
    (大概可以配合Bottom Sheets

  • Entry Chip
    style="@style/Widget.MaterialComponents.Chip.Entry"
    entryChip
    看见它其实多了两个功能,一个是选中以及未选中,一个是点击旁边的icon之后有一个反馈(选中和未选中的样子是默认的)
    这个反馈是通过以下方式进行调用

    1
    2
    3
    chip.setOnCloseIconClickListener { 
    // something you want after click
    }

    啊,当然这个东西功能肯定不止这一些,在后面会讲一切其他的用法。
    在这里先提一下checkedIcon这个是这是你选中这个Chip之后显示的一个drawable,相对应的,chipIcon会一直显示在显示的文本的左边,当然,也可以通过其他对应的设置来修改这个icon的显示位置,自然的,closeIcon就可以修改对应的上图里面关闭响应的图标了。啊,这样贴一个图可能更加确切的说明
    iconType
    但是我们能够发现,其实checkedIconchipIcon在已选中状态的时候会进行重叠(chipIcon在下面),所以说在处理的时候记得要处理好相关的关系ovo(倒还不如说是好好设计吧)

其中还有其他样式的,不过主要是结合ChipGroup进行一些综合的实际应用进行使用,在下面就结合这两个部分一起介绍了。

ChipGroup

ChipGroup主要的话就是存放一系列的chip以及一同对他们的布局进行管理,同时对于他们的相关的点击事件可以进行一同的管理,可以类比于RadioGroup
不过在里面需要注意的是,如果使用了padding会导致内容显示不全:>

在其中可以按照不同的实际需求进行一定的限制,譬如说

  • app:singleLine="true"
    使得该ChipGroup仅显示一排,当然,在外面需要用一层HorizontalScrollView进行包裹,才能够让内容能够全部显示。

  • app:singleSelection="true"
    使得该部分内的所有chip只能够选择一个,这个时候我们就能够通过这个来定制一些比原来的RadioGroup颜值更加高,但是功能其实相似的部分了。

  • chipgroup.setOnCheckedChangeListener(OnCheckedChangeListener)
    这个方法使得在逻辑层里面能够通过这个方法来对于chipgroup里面实时有点击变化的部分进行相应,通过返回的chip的对应id值来对于不同chip的点击操作进行相应并进行一定的扩展。

在这个时候我们再来介绍一些配合食用的style:

  • Filter Chip
    filter,意思就是过滤器,在进行了选择了之后就能够通过chipgroup统一管理每个chip的状态,并进行选择
    大概默认的一种浏览图:
    filter-gif
    不过在这个里面为了达成仅用一层显示并能够滚动,不仅仅是添加singleLine的属性,同时这个chipGroup需要在外面包裹一个HorizontalScrollView,并且把里面的滚动条隐藏掉才能够展现上面的效果

  • Chioce Chip
    表示选择,能够不同的设置展示不同效果,点击的效果也可以根据不同的api进行自定义

    在有空了之后准备自己写一个类似的demo,业务逻辑应该是掌上重邮的空教室部分,毕竟这个部分是自己在负责这个样子

    这个效果就异常符合Google自身的一些构想了吧。同时这种点击反馈也是看着比较友好这个样子。
    choise-gif

    当然,只要你有脑洞,这样的设置也能够做成不同的,令人惊异的效果。譬如说wps里面的文本编辑里面的东西选择,当然就能够利用Choise chip+app:singleSelection="true"来进行分组,同时完成需要的逻辑效果。
    自然,也可以用这个来做tag的选择以及选择之后的展示,都是很ok的效果ouo

ChipDrawable

在有一些情况之下,需要动态加入一些chip相关的ui,大概配合editText的效果如下:
chipdrawable
不过有些缺点是一些具体的点击事件并不好进行操作 :>
具体的操作代码如下(Kotlin进行的操作,逻辑考虑得不是很周全)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mb_sure.setOnClickListener {
setSpan()
}

fun setSpan() {
val chip = ChipDrawable.createFromResource(this@ChipActivity, R.xml.standalone_chip)
val text = et_chip.text
chip.apply {
setText(text)
setBounds(0, 0, chip.intrinsicWidth, chip.intrinsicHeight)
}
val span = ImageSpan(chip)
text.setSpan(span, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}

同时需要在res/xml/..下文件中新建一个.xml文件,在里面利用<chip>标签对于东西进行定制。

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:chipIcon="@drawable/ic_star_black_24dp" />

当然,可以在里面通过style对于展示的具体形式进行操作。在这里默认的是Entry类型
emm,其实感觉使用方面并不是很高。
或者说进行了一些部分的组合定制了之后效果可能也会挺不错的:>

啊,那大概暂时bb到这里,之后有相关的东西也会在这里更新 :>