Material Design

前言

一、设计阶段
Material Design 提供了跨设备和 Web 的一致性用户体验。它的四项原则:

  • 有型的外观(Tangible surface):应用像现实中的实物一样。
  • 仿印刷品的设计(Print-like design):内容醒目、形象生动、意图明确。
  • 有意义的运动效果(Meaningful motion):吸引用户的兴趣,在应用状态切换时保持连续性。
  • 自适应设计(Adaptive deisgn):用户在手机、平板、Android TV、Android Wear、Android Auto 等不同设备上都能感到熟悉、一致,而不需要重新适应应用。

文档

官方API

官方博客

使用须知

开源库

App Bar layout

Material Design 新特性

Ripple api > = 21

实践应用

自定义Ripple背景颜色

drawable-v21/selectable_item_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

自定义Ripple的颜色,在主题style中

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    <item name="android:colorControlHighlight">@color/your_custom_color</item>
  </style>
</resources>

兼容库

RippleEffect api > 9 缺点是引入比较麻烦,需要包一层Layout,布局起来不是很方便

相关博文

SVG

工具

转化

相关博文

TV

Toolbar

ToolBar详解

TabLayout

TabLayout:另一种Tab的实现方式

  • 如下代码,Tab间隔转换会有更好的动画效果。
    Method animateToTab = clz.getDeclaredMethod("animateToTab", new Class[]{int.class});
    animateToTab.setAccessible(true);
    animateToTab.invoke(tabLayout, new Object[]{5});
  • 与ViewPager结合标准代码
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.ac_tab_layout);
      // 获取ViewPager
      ViewPager viewPager = (ViewPager) findViewById(R.id.ac_tab_vp);
      // 构造一个TabPagerAdapter对象
      TabPagerAdapter adapter = new TabPagerAdapter();
      // 获取ViewPager
      TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout);
      // 设置TabLayout模式
      tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
      // 设置ViewPager的适配器
      viewPager.setAdapter(adapter);
      // 设置ViewPager
      tabLayout.setupWithViewPager(viewPager);
    }
  • Design库-TabLayout属性详解

Bottom Navigation

Dependence

compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'

TextInputLayout

AppBarLayout

ConstraintLayout

CardView

  • android.support.v7.widget.CardView

引用

implementation 'com.android.support:cardview-v7:27.1.1'

属性详解

属性 解析
app:cardBackgroundColor 置背景颜色
app:cardCornerRadius 设置圆角大小
app:cardElevation 设置z轴阴影高度
app:cardMaxElevation 设置z轴最大高度值
app:contentPadding 内容与边距的间隔
app:contentPaddingLeft 内容与左边的间隔
app:contentPaddingTop 内容与顶部的间隔
app:contentPaddingRight 内容与右边的间隔
app:contentPaddingBottom 内容与底部的间隔
app:paddingStart 内容与边距的间隔起始
app:paddingEnd 内容与边距的间隔终止
app:cardUseCompatPadding 设置内边距,在API21及以上版本和之前的版本仍旧具有一样的计算方式
app:cardPreventConrerOverlap 在API20及以下版本中添加内边距,这个属性为了防止内容和边角的重叠

注意:CardView中使用android:background设置背景颜色无效。

使用技巧

Ripple 效果

android:foreground=”?android:attr/selectableItemBackground”

cardUseCompatPadding

pre-Lollipop平台中,不同cardPreventCornerOverlap值的效果对比图(左false,右true)

设置在Lollipop及以上版本的系统中没有任何影响,除非cardUseCompatPadding的值为true。

lift-on-touch 效果

drawable/lift_on_touch.xml

注意: 设置click效果才会出现

<?xml version="1.0" encoding="utf-8"?>
<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
 android:state_enabled="true"
 android:state_pressed="true">
        <set>
            <objectAnimator
 android:duration="@android:integer/config_shortAnimTime"
 android:propertyName="translationZ"
 android:valueTo="6dp"
 android:valueType="floatType"/>
        </set>
    </item>
    <item>
        <set>
            <objectAnimator
 android:duration="@android:integer/config_shortAnimTime"
 android:propertyName="translationZ"
 android:valueTo="0"
 android:valueType="floatType"/>
        </set>
    </item>
</selector>

小结:

<style name="AppCardView" parent="@style/CardView.Light">
 <item name="cardPreventCornerOverlap">false</item>
 <item name="cardUseCompatPadding">true</item>
 <item name="android:foreground">?android:attr/selectableItemBackground</item>
 <item name="android:stateListAnimator" tools:targetApi="lollipop">@drawable/lift_up</item>
</style>

参考:Android CardView的使用细节

NestedScrollView

BottomSheets

  1. 设置高度为屏幕3/2,去除状态栏

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            int screenHeight = getScreenHeight(getContext());
    
            if(screenHeight == 0){
                screenHeight = 1920;
            }
    
            Window window = getWindow();
            assert window != null;
    
            //设置成沉浸式
    //        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight);
    
            //需要设置最大高度 给dialog设置一个固定的高度
            //你想要减去的高度,dialog默认最大高度在状态栏下方
    //        float reduceHeight = getContext().getResources().getDimension(R.dimen.qb_px_120);
            int reduceHeight = ScreenUtils.getStatusBarHeight(getContext());
    //        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, (int) (dialogHeight - reduceHeight));
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, (int) (screenHeight/3*2 - reduceHeight));
    //        最后一步是必须的,否则BottomSheetDialog会显示在屏幕中间,底部会出现空白区域
            window.setGravity(Gravity.BOTTOM);
        }
    
        /**
         * 获取屏幕的高度
         * @param context
         * @return
         */
        public static int getScreenHeight(Context context) {
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Point point = new Point();
            assert wm != null;
            wm.getDefaultDisplay().getSize(point);
            return point.y;
        }
  2. 背景设置为透明,可以显示圆角

      //设置圆角背景不生效 原因:由于它上面蒙了一层布局 design_bottom_sheet是系统的布局,直接找到它,然后给它设全透明就好了
            FrameLayout bottomSheet = (FrameLayout) getDelegate().findViewById(R.id.design_bottom_sheet);
            bottomSheet.setBackgroundColor(mContext.getResources().getColor(R.color.transparent));
            //设置dialog的下拉拖拽与scrollView下拉冲突
            bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
            bottomSheetBehavior.setPeekHeight(bottomDialogHeight);//此处是dialog设置的最大高度

图片文字资源

资源

  • Demos the new Android Design library github star 6300+
  • MaterialDrawer The flexible, easy to use, all in one drawer library for your Android project
  • CircularAnim Android水波动画帮助类,一行代码实现View显示/隐藏/startActivity特效。(对 ViewAnimationUtils.createCircularReveal() 方法的封装)

字体和图片相关

主要特点:

  1. 包含1500+ 的矢量图标(大小: 200kb);
  2. 支持API>=4;
  3. 可以转化为Drawable,可以menu.xml 中使用, 可以在Toolbar menu中使用

使用:1. 在https://materialdesignicons.com找矢量图; 2.集成库使用;

主要特点:

  • 提供了三个矢量图库;
  • 可以在原生控件上使用;
  • 支持字体和矢量图片的自定义;

Material Animation 动画


New Feature 新的特性


Theme 主题

设置相关

原生控件的包装

兼容开源库

特别想实现的效果