[Android] 03 - UI and Material Design

背景

 

Ref: Lecture 2: UI and Layout [Android 2016]

Ref: chenyangcun/MaterialDesignExample

Ref: 加载图片助手:https://www.fresco-cn.org/

"5.0系统最大的改变就是Material Design了,因此新书中也是花了非常大的篇幅来详细讲解Material Design." ----《第一行代码 第2版》

 

Material Design的重要性

如果是色彩盲,请自行收藏这个网站Material Design Color Palette Generator
从一开始起就严格按照material design写Material Design
 

控件使用建议

不要自定义一堆padding margin,但你需要边框,边距的时候,请看看?android:attr/里面有木有你需求的(由于android studio强大的补全功能,你一般只需打几个关键词就有提示了),比如你需要给一个ImageButton加点击效果,不要傻不拉几的去写一个selector了,你只需要输入 item select这些关键词,自动补全就会给你提示了。

不要定义一大堆乱七八糟的字体大小了,materail design上的几种基本字体大小可以满足你!

再也不要使用ListView了,改成RecycleView

再也不要寻找第三方下拉刷新控件了,SwipeRefreshLayout肯定符合你的要求(不信你看,知乎Android客户端都是用的这个(●ˇ∀ˇ●))。

再也不要使用第三方侧滑栏了,DrawerLayout能满足你!

再也不要使用ViewPagerTabStripe这一类的第三方Tab控件了,请使用TabLayout!

再也不用找圆形头像控件,圆角控件了,其他的Univeral Image Loader /Picasso也不用看了,直接上Fresco | Fresco 中文说明吧,它都有!不如用省下的时间看看Fresco的源码。
 
 
 
 
 

本篇以《第一行代码 第2版》的内容为主,先复习基本UI,再了解material design
  
 

 

UI控件 

 

2.2.1 LinearLayout(线性布局)
2.2.2 RelativeLayout(相对布局)
2.2.3 TableLayout(表格布局)
2.2.4 FrameLayout(帧布局)
2.2.5 GridLayout(网格布局)
2.2.6 AbsoluteLayout(绝对布局)
2.3.1 TextView(文本框)详解
2.3.2 EditText(输入框)详解
2.3.3 Button(按钮)与ImageButton(图像按钮)
2.3.4 ImageView(图像视图)
2.3.5.RadioButton(单选按钮)&Checkbox(复选框)
2.3.6 开关按钮ToggleButton和开关Switch
2.3.7 ProgressBar(进度条)
2.3.8 SeekBar(拖动条)
2.3.9 RatingBar(星级评分条)
2.4.1 ScrollView(滚动条)
2.4.2 Date & Time组件(上)
2.4.3 Date & Time组件(下)
2.4.4 Adapter基础讲解
2.4.5 ListView简单实用
2.4.6 BaseAdapter优化
2.4.7ListView的焦点问题
2.4.8 ListView之checkbox错位问题解决
2.4.9 ListView的数据更新问题
2.5.0 构建一个可复用的自定义BaseAdapter
2.5.1 ListView Item多布局的实现
2.5.2 GridView(网格视图)的基本使用
2.5.3 Spinner(列表选项框)的基本使用
2.5.4 AutoCompleteTextView(自动完成文本框)的基本使用
2.5.5 ExpandableListView(可折叠列表)的基本使用
2.5.6 ViewFlipper(翻转视图)的基本使用
2.5.7 Toast(吐司)的基本使用
2.5.8 Notification(状态栏通知)详解
2.5.9 AlertDialog(对话框)详解
2.6.0 其他几种常用对话框基本使用
2.6.1 PopupWindow(悬浮框)的基本使用
2.6.2 菜单(Menu)
2.6.3 ViewPager的简单使用
2.6.4 DrawerLayout(官方侧滑菜单)的简单使用
控件列表

 

基本上用法都很相似,

    1. 给控件定义一个 id,
    2. 再指定下控件的宽度和高度,
    3. 然后再适当加入些控件特有的属性就差不多了

 

button点击事件触发

给button添加监听事件,所以参数就是个监听器的类,并重写了其中的onClick方法。

以上是匿名类方法,或者使用activity的接口实现方法,也就是重写activty中的onClick方法,并需判断传来的是该activity下的哪个button。

 

EditText默认提醒文字

android:hint="Type something here"

 

获取控件对象的两种方式

1.
private EditText editText; String inputText
= editText.getText().toString();
2. editText
= (EditText) findViewById(R.id.edit_text);

 

AlertDialog小窗口提醒

AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle     ("This is Dialog");
dialog.setMessage   ("Something important.");
dialog.setCancelable(false);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialog, int which) {
  ...   } });
dialog.setNegativeButton(
"Cancel", new DialogInterface.OnClickListener() {   @Override   public void onClick(DialogInterface dialog, int which) {
  ...   } }); dialog.show();

  

四种基本布局

Ref: Android 基础:常用布局 介绍 & 使用

框架布局 继承    线性布局

约束布局 优于 相对布局

绝对布局 不适合手机类型多样化

网格布局GridLayout 优于 tablelayout,详见:Android 4.0新增的网格布局GridLayout

 

 

一些建议学习

a. 再也不要使用ListView了,改成RecycleView吧
b. 再也不要寻找第三方下拉刷新控件了,SwipeRefreshLayout肯定符合你的要求。

Goto:一篇博客理解Recyclerview的使用【有预览图】

Goto:RecyclerView使用完全指南,是时候体验新控件了

以及,上述两者的结合,构成列表拖动刷新:使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载【有代码】


c. 再也不要使用第三方侧滑栏了,DrawerLayout能满足你!

Ref: DrawerLayout和NavigationView使用详解


d. 再也不要使用ViewPagerTabStripe这一类的第三方Tab控件了,请使用TabLayout!

Ref: Design库-TabLayout属性详解


e. 再也不用找圆形头像控件,圆角控件了,其他的Univeral Image Loader /Picasso也不用看了,直接上Fresco | Fresco 中文说明吧,它都有!不如用省下的时间看看Fresco的源码。

Goto: 专门为ANDROID加载图片

 

 

 

 

Material Design

 

Ref: https://material.io/guidelines/

Ref: Material Design 中文版 

Ref: Material Design 是一种什么样的设计风格?

 

1. ActionBar (Default) ----> Toolbar

Action Bar取代了传统的tittle bar和menu,在程序运行中一直置于顶部,对于Android平板设备来说屏幕更大它的标题使用Action Bar来设计可以展示更多丰富的内容,方便操控。

不过ActionBar由于其设计的原因,被限定只能位于活动的顶部,从而不能实现一些Material Design的效果,因此官方现在已经不再建议使用ActionBar了。 

Toolbar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件来完成一些Material Design的效果。

 

AndroidManifest.xml文件

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ...
</application> 

res/values/styles.xml文件

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

 

指定一个不带ActionBar的主题,通常有两种主题可选。

    • Theme.AppCompat.NoActionBar        表示深色主题,它会将界面的主体颜色设成深色,陪衬颜色设成淡色。
    • Theme.AppCompat.Light.NoActionBar       表示淡色主题,它会将界面的主体颜色设成淡色,陪衬颜色设成深色。  ----> as following

 

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

 

 

已经将ActionBar隐藏起来了,那么接下来看一看如何使用Toolbar来替代ActionBar。

Toolbar的调用:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
}

 

Toolbar的定义:

 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:app="http://schemas.android.com/apk/res-auto"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <android.support.v7.widget.Toolbar
 7         android:id            = "@+id/toolbar"
 8         android:layout_width  = "match_parent"
 9         android:layout_height = "?attr/actionBarSize"
10         android:background    = "?attr/colorPrimary"
11         android:theme         = "@style/ThemeOverlay.AppCompat.Dark.ActionBar"
12         app:popupTheme        = "@style/ThemeOverlay.AppCompat.Light" />
13 
14 </FrameLayout>

 

 

第2行,这里使用xmlns:app 指定了一个新的命名空间。

思考一下,正是由于每个布局文件都会使用xmlns:android 来指定一个命名空间,因此我们才能一直使用android:id 、android:layout_width 等写法,

那么这里指定了xmlns:app ,也就是说现在可以使用app:attribute 这样的写法了。

但是为什么这里要指定一个xmlns:app 的命名空间呢?

这是由于Material Design是在Android 5.0系统中才出现的,而很多的Material属性在5.0之前的系统中并不存在,那么为了能够兼容之前的老系统,我们就不能使用android:attribute 这样的写法了,而是应该使用app:attribute 

 

第6行,定义了一个Toolbar控件,这个控件是由appcompat-v7库提供的。

这里我们给Toolbar指定了一个id,将它的宽度设置为match_parent ,高度设置为actionBar的高度,背景色设置为colorPrimary。

不过下面的部分就稍微有点难理解了,由于我们刚才在styles.xml中将程序的主题指定成了淡色主题,因此Toolbar现在也是淡色主题,而Toolbar上面的各种元素就会自动使用深色系,这是为了和主体颜色区别开。但是这个效果看起来就会很差,之前使用ActionBar时文字都是白色的,现在变成黑色的会很难看。那么为了能让Toolbar单独使用深色主题,这里我们使用android:theme 属性,将Toolbar的主题指定成了ThemeOverlay.AppCompat.Dark.ActionBar。

但是这样指定完了之后又会出现新的问题,如果Toolbar中有菜单按钮(我们在2.2.5小节中学过),那么弹出的菜单项也会变成深色主题,这样就再次变得十分难看,于是这里使用了app:popupTheme 属性单独将弹出的菜单项指定成了淡色主题。

之所以使用app:popupTheme ,是因为popupTheme 这个属性是在Android 5.0系统中新增的,我们使用app:popupTheme 的话就可以兼容Android 5.0以下的系统了。

 

如此,我们便有了一个material design风格的title bar。

 

 

2. 滑动侧边栏 + NavigationView

参见本篇上述的 DrawerLayout 。

 

 

FloatingActionButton 是Design Support库中提供的一个控件,这个控件可以帮助我们比较轻松地实现悬浮按钮的效果。它默认会使用colorAccent来作为按钮的颜色,我们还可以通过给按钮指定一个图标。 

activity_main.xml 文件:

<android.support.v4.widget.DrawerLayout
    xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app     = "http://schemas.android.com/apk/res-auto"
    android:id            = "@+id/drawer_layout"
    android:layout_width  = "match_parent"
    android:layout_height = "match_parent">

    <FrameLayout
        android:layout_width  = "match_parent"
        android:layout_height = "match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.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" />
    </FrameLayout>

    ...
</android.support.v4.widget.DrawerLayout>

设置点击事件:

public class MainActivity extends AppCompatActivity {

    private DrawerLayout mDrawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
FloatingActionButton fab
= (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "FAB clicked", Toast.LENGTH_SHORT).show(); } }); } ... }

 

 

4. Snackbar

首先要明确,Snackbar并不是Toast的替代品,它们两者之间有着不同的应用场景。

    • Toast的作用是告诉用户现在发生了什么事情,但同时用户只能被动接收这个事情,因为没有什么办法能让用户进行选择。
    • Snackbar则在这方面进行了扩展,它允许在提示当中加入一个可交互按钮,当用户点击按钮的时候可以执行一些额外的逻辑操作。

  打个比方,如果我们在执行删除操作的时候只弹出一个Toast提示,那么用户要是误删了某个重要数据的话肯定会十分抓狂吧,

  但是如果我们增加一个Undo按钮,就相当于给用户提供了一种弥补措施,从而大大降低了事故发生的概率,提升了用户体验。

 

<android.support.design.widget.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"
    app:elevation="8dp" />

 

设置点击事件:

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ... ...
FloatingActionButton fab
= (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Data deleted", Snackbar.LENGTH_SHORT) .setAction("Undo", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "Data restored",Toast.LENGTH_SHORT).show(); } }) .show(); } }); } ... }

 

 

5. CoordinatorLayout 自动将悬浮按钮上移

加强版的FrameLayout,这个布局也是由Design Support库提供。

CoordinatorLayout可以监听其所有子控件的各种事件,然后自动帮助我们做出最为合理的响应。例如:

如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,那么它会自动将内部的FloatingActionButton向上偏移,从而确保不会被Snackbar遮挡到。

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.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.support.design.widget.CoordinatorLayout>

 

 

其他,卡片式布局,下拉刷新等,暂略。

基本上,material design在Android系统上就表现为一些专门设计的优美控件。

 

posted @ 2017-12-19 09:04  郝壹贰叁  阅读(232)  评论(0)    收藏  举报