Bootstrap

Android Material Design 之 图形

格式塔原理介绍

Material Design 运用了格式塔原理,尤其是在图形的设计上。

格式塔理论是心理学中为数不多的理性心理学之一。格式塔学派以某些相当抽象的,与知觉和思维的性质以及心理经验的结构有关的观念解释了熟悉的观察资料。
格式塔心理学派断言:人们在观察时,眼脑并不是在一开始就区分一个形象的各个单一的组成部分,而是将各个部分组成起来,使之成为一个更易于理解的整体。此外,他们坚持认为,在一个格式塔(即一个单一视场,或单一参照系)内,眼睛的能力只能接受少数几个不相关联的整体单位。这种能力的强弱取决于这些整体单位的不同与相似,以及它们之间的相关位置。如果一个格式塔中包含了太多的互不相关的单位,眼脑就会试图简化,把各个单位加以组合,使之成为易于处理的整体。如果办不到这一点,整体形象将继续呈现无序状态或混乱,从而无法被正确认知,简单的说就是看不懂或无法接受。格式塔理论明确提出:眼脑作用是一个不断组织,简化,统一的过程,正是通过这一过程,才产生出易于理解,协调的整体。

格式塔心理学主要有五个原则:
1. Proximity 接近
2. Similarity 相似
3. Closure 闭合
4. Continually 连续
5. Simplicity 简单

Gestalt laws of grouping 又被称为Principles of grouping

关于格式塔的介绍,推荐这篇文章:

Tencent CDC( http://cdc.tencent.com/2010/07/23/格式塔心理学5项法则的学习与思考/

网格和关键线

关于元素组件之间的布局,可按照一定的原则来设计。
1. 使用8dp的网格来对齐组件,即图像,图标的大小,间距,外边框,内边框都是8dp的整数
2. 使用4dp的网格来对齐文字,即文本高度是4dp的整数。
3. 这些8dp和4dp的网格,允许我们很轻松的就运用上面介绍的分组定律即laws of grouping,使我们的UI有序,平衡,并且和操作协调的其他部分协调一致。
4. 关键线用来在用户界面中垂直或水平对齐组件对象。从美学上来讲,关键线使得UI井然有序,也能更快速的扫描屏幕并接受信息。常用的关键线,对于图片和头像等辅助的对象,经常使用从左到右16dp的外边框;而对于标题和内容等主要内容,则使用从左到右72dp的外边框。如果没有辅助内容,那么主要内容也应该从左到右16dp的外边框。

色彩
  1. Primary color 使用这个主色彩来展现应用的品牌定位或品牌个性。可以将这个色彩应用到一个大的区块里面,比如appbar或toolbar使得我们的应用一眼就被认出来。
  2. Accent color 这个强调色,颜色更加饱和,更加鲜亮。可以使用这个颜色来讲用户的注意力引导到特定的元素上面,比如我们使用的FAB。
  3. 只使用两种色彩显然是不够用的,material design提供了一些人工选出来的调色板,在调色板上对应着一些数字,这些数字对于我们来说只需要记住,500 代表的是primary color,比500更大的数字表示颜色更深,反之颜色更浅,而使用A开头的数字代表accent color。
  4. 假设我们要使用一个靛蓝色为主色,而粉红色为强调色的风格,那么我们应该如何进行配置呢
    4.1. 添加颜色到资源文件中

    <resources>
        <color android:name="indigo_300">#7986CB</color>
        <color android:name="indigo_500">#3551B5</color>
        <color android:name="indigo_700">303F9F</color>
        <color android:name="pink_a200">#FF4081</color>
    </resources>    

    4.2. 应用到主题中

    <resources>
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <item name="colorPrimary">@color/indigo_500</item>
            <item name="colorPrimaryDark">@color/indigo_700</item>
            <item name="colorAccent">@color/pink_a200</item>
        </style>
    </resources>

    4.3 使用这些色彩

        <android.support.design.widget.AppBarLayout
                android:id="@+id/app_bar_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="?colorPrimary">
    
        </android.support.design.widget.AppBarLayout>   

    注意:这里为什么使用?colorPrimary而不直接使用那个颜色值比如:@color/indigo_500
    这里?colorPrimary表示使用主题中的本地属性的值,也可以将其改为?attr/colorPrimary
    除了可以定制material design 主题的这三个色彩,我们还可以定制android:statusBarColor ,windowBackground ,navigationBarColor等,参考官方文档

  5. 从图像中提取色彩
    我们可以根据一张图片利用com.android.support.palette来提取一张图片的重要的色彩。
    首先:
    build.gradle 文件添加依赖

    ...
    dependencies {
        ...
        compile 'com.android.support:palette-v7:23.4.0'
    }

          其次:

    private void processPalette(){
        Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.drawable.xk);
        Palette p = Palette.form(bitmap).generate(new Palette.PaletteAsyncListner(){
            @override
            public void onGenerated(Palette p){

            }
        });
    }

material design palette

字体
  • 西文字体: Roboto, 这是随着Andorid 4.0引入的一种无衬线字体系列,详见Github Roboto
  • 非拉丁字体,如中文: Android 官方预设的Noto系列的字体,详见Google Noto。中文的话就是: Noto Sans CJK SC/TC,这个字体和Adobe fonts 中的思源黑体(Source Han Sans)是同一种字体。
  • sp 是英语(Scale-independent pixel)的缩写,缩放独立像素,主要用于字体大小的尺寸,Android 允许用户自定义其字体的大小,在“设置”–“辅助功能”中,我们可以找到这项字体大小的设置,那么这个设置会对字体的显示进行改变,通常normal (100%)字体大小,我们app设置的16sp大小的字体就和16dp大小的字体一样大,但若设置为大好字体,即125%后,16sp = 16dp * 125% = 20dp。 当然如果我们不想我们设置的字体大小会随着这个设置进行改变,那么我们可以直接将字体的大小设置为其他的单位,如dp,px甚至mm。
  • 关于西文字体,在绘制的时候,需要注意字体的几个概念,baseline, x-height, cap height, ascenders, descenders, leading。如下图所示 详细的西文字体解剖
    这里写图片描述
    但中文中并没有这些概念,自然在绘制的时候会出现一些问题,如Android Canvas drawText实现中文垂直居中
  • 加载自定义字体

    • 首先将字体放在assets文件夹中,如assets/NotoSans-Bold.ttf
    • 在代码中加载字体

      @override
      protected void onCreate(Bundle savedInstanceState){
          Typeface myTypeface = Typeface.createFromAssets(getAssets(), "NotoSans-Bold.ttf");
          TextView tv = (TextView)findViewById(R.id.text1);
          tv.setTypeface(myTypeface);
      }
图片
  • 优质的图像是使得用户与主题构成联系并与他们的喜怒哀乐产生共鸣,尽管只是通过感受,好的图像还能让我们回忆起熟悉的味道和声音。选择图片时,应该选择贴近用户的图像,是用户触景生情或者取悦用户。
    • 照片 photography
      如果是针对内容,照片会是一个很好的选择,如果显示的是特定的人物,地点或者事物,照片能够快速且漂亮的将其传达给用户。在使用照片时得确保使用高质量的照片以避免像素不足的情况, 也完全可以把照片当作背景用来设定希望屏幕所传达出来的情感。
    • 插图 illustration
      如果我们要传达照片无法体现的抽象概念或比喻,插图会是个很好的办法。创建插图时,务必做到清晰明确,避免过度修饰,只要想传达的聚焦点和消息即可,并最好让一系列插图之间保持一致性,使它们能够相互的联系起来,例如,使用统一的视角,调色板或纹理。
    • 图标 icon
      图标的使用是为了便于寻找。它与插图相反,插图是为了简明扼要的解释清楚意思,图标应方便识别,并在应用中起来解释的作用。获取更多的icon , 如何设计icon

 

  • 图片的缩放,ImageView.ScaleType: 三个Center,四个Fit,一个Matrix:
    图片的缩放本质上对ImageView的mDrawableMatrix进行设置,我们知道Matrix矩阵的值,用来定义缩放,平移,旋转,错切等。
    Matrix矩阵对应值 matrix详解
ScaleType理解
CENTER图像并不会进行缩放,但会将drawable进行平移到imageView的中央
CENTER_CROP图像会进行等比例缩放,并且保证图像的宽或高缩放后都大于或者等于ImageView的相应的宽或者高,即缩放后的图像能够遮盖住imageview;然后再将缩放后的图像进行平移居中,超出的部分将会被剪裁
CENTER_Inside这个分两种情形,当我们的图像的宽和高都小于或者等于imageView时,图像将会和Center一样,即不进行缩放;但是当图像的宽或高至少有一个大于imageview相应的宽或高时,会进行等比例缩放以保证宽或高都小于或等于imageview的宽或高的,此时与FitCenter效果一样。
FIT_CENTER和Matrix.ScaleToFit为CENTER一样,对图像进行等比例压缩,并保证图像的宽和高压缩后都比imageview的宽或高小或等于。并将图像居中,空白的地方分别上下左右
FIT_START和Matrix.ScaleToFit为START一样,对图像进行等比例压缩,并保证图像的宽和高压缩后都比imageView的宽或高小或等于。并将图像左对齐或者上对齐
FIT_END和Matrix.ScaleToFit为END一样,对图像进行等比例压缩,并保证图像的宽和高压缩后都比imageView的宽或高小或等于。并将图像右对齐或者下对齐
FIT_XY和Matrix.ScaleToFit为FILL一样,对图像进行缩放,不用保持原来的比例,只须保证图像的宽或高和imageview的宽和高一样。
MATRIX利用matrix来对drawable进行缩放,平移或者选择等,这是上面所有类型的原理

 

  • 圆形的图片
    通常我们会使用到圆形的图片来作为用户的头像等,介绍material design 库来生成圆形的图片:

    public void createRoundDrawable(Bitmap bitmap){
        RoundedBitmapDrawerable drawable = RoundedBitmapDrawerableFactory.create(context.getResources(),bitmap);
        drawable.setCircular(true);
    }

     

  • 宽高固定比的ImageView,例如宽:高 = 3: 2

    • 创建一个类继承ImageView
     class ThreeTowImageView extends ImageView {
            public void ThreeTowImageView(Context context){
                super(context);
            }
    
            pulic void ThreeTowImageView(Context context, Attributes attrs){
            super(context, attrs);
        }
            public ThreeTowImageView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
    public ThreeTowImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public void onMeasure(int widthSpec, int heightSpec){
            int threeTowHeight = MeasureSpec.getSize(widthSpec) * 2 / 3;
            int threeTowHeighSpec = MeasureSpec.makeMeasureSpec(threeTowHeight, MeasureSpec.EXACTLY);
            super.onMeasure(widthSpec, threeTowHeightSpec);
        }
    }
    • 在xml中使用
      <com.yolosiro.ThreeTowImageView
          android:width="match_parent"
          android:height="0dp"
          android:scaleType="centerCrop"/>

 

  • 背景保护
    当图片作为背景的时候,图片上的文字或者图标有可能会因为色彩相近而让用户很难辨别清楚,这是时候最好在xml中处理一下,即在图片上添加一层渐变色。
    backgroundProtect

    • 创建渐变

      <shape android:shape="rectangle">
          <gradient
              android:angle="-90"
              android:startColor="#00000000"
              android:centerColor="#00000000"
              android:endColor="#00000000"
              android:type="linear"/> 
      </shape>
      
    • 使用到xml布局中

      <FrameLayout ...>
          <ImageView .../>
          <View
              android:background="@drawable/gradient"
              ... />
          <TextView 
              android:layout_gravity="bottom"
          ... />
      </FrameLayout>
;