Android设计模式——Material Design学习(一)

Material Design(原质化设计)是谷歌2014年推出的新的设计模式,但是发现自己在项目中使用的还是比较少,所以这里来做一个学习总结。

Material Design主要强调的是统一的安卓应用风格,但是它的普及程度却并不理想(用起来真的好费力)。于是在2015年谷歌发布了Design Support库,让程序员可以在不了解Material Design的情况下轻松使用。

下面不多说,为了达到更加详细的目的,我将从头开始介绍(包括之前文章中我介绍过的snackbar,toolbar,drawerlayout等控件)。

首先我们创建一个新的项目,在选择界面中,我们选择

Android设计模式——Material Design学习(一)

这个界面,会发现Android Studio为我们自动生成了许多代码,从这里我们开始一一解析。

首先是打开项目列表

Android设计模式——Material Design学习(一)

会发现自动生成了三个(drawable排除在外)xml文件。

我们首先打开activity_main文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <include layout="@layout/content_main" />

    <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="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

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

发现这么多没有用过或者没有见过的控件,咱们先不要慌,首先仔细看代码,发现其实就是Coordinatorlayout中添加了toolbar和FloatingActionButton两个控件而已,至于conten_main,便是我们主页面中的那个TextView

这么分析之后,我们再去看看MainActivity中的代码:

package com.example.administrator.myapplication;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.ContextMenu;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;

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

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Snackbar.make(v, "hahahaha", Snackbar.LENGTH_SHORT).setAction("", null).show();
                            }
                        }).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Snackbar.make(toolbar,"hahahah",Snackbar.LENGTH_SHORT).show();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

仅仅是初始化toolBar和FlButton而已,设置SnackBar弹出提示框,从这里就来开始简介一下,为什么这里会使用toolbar,我们传统的使用的都是ActionBar(没听说过?)

Android设计模式——Material Design学习(一)

那上面蓝色的这部分你见过吧?当我们没有在Apptheam中设置Noactionbar的时候,这里就是ActionBar,现在,我们将stylrs中的这个找到:

Android设计模式——Material Design学习(一)

然后我们将DarkActionBar改成NoActionBar,就可以自动隐藏掉标题了。之所以我们要隐藏掉ActionBar,第一是因为它占用了太多屏幕与空间,第二是它不可以与其他控件进行互动,第三是我们不能对它进行功能上的编辑。

然后toolBar的出现完全解决了这个问题。

然后我们再看代码,下面出现的

toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

这两行,我们将toolBar初始化之后,使用setSupportActionBar方法,将toolbar改变成我们新的标题栏。

然后往下,设置button的点击事件,这里使用到的新的弹窗提示方式:SnackBar,用于替换传统的Toast,Toast的缺陷在于,它无法与用户进行交互,并且展示的位置永远都是不变的,而SnackBar,则刚好可以解决替补这些缺陷,make方法中,我们需要传入三个参数view,text,还有int,view表示SnackBar展示信息是所在的控件位置(这里必须要强调一下,在Coordinatorlayout中,系统会根据你传入的View,选择当前布局中最优的位置展示),text不用说,和Toast一样,int也是和Toast一样的显示时间,LONG和SHORT,在这里,当写完之后,如果我们直接在后面.show,那么SnackBar就会以传统Toast的方式,只是作为一个信息提示框出现,如果我们加入setAction,就可以进行与用户的交互(在提示框中加入点击事件),setAction含有两个参数,第一个是text,表示你将要点击的内容,第二个就是onclicklistener,如果你传入的onclicklistener为null,那么默认不会出现可点击内容,而是直接展示信息。

然后之前的menu_main我们发现在

onCreateOptionsMenu(Menu menu)

方法中被使用了,这个方法是activity中用于创建菜单的方法,我们使用

getMenuInflater().inflate(R.menu.menu_main, menu);


方法将manu_main的布局文件初始化。在这里深入看看menu_main中的内容:

<menu 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"
    tools:context="com.example.administrator.myapplication.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="withText"
        android:icon="@drawable/ic_launcher_background"/>
    <item
        android:id="@+id/action_hello"
        android:orderInCategory="90"
        android:title="hello"
        app:showAsAction="never" />
</menu>

会发现菜单文件中有我们加入了item,这里每一个item便是一个菜单中的选项,再看看看这里的order属性,这个属性中的值用于表示菜单项的位置,值越大,位置就越靠后,然后便是icon属性,这个属性和showAsAction属性息息相关,我们现在介绍showAsAction属性,它用于表示菜单的基于ActionBar的显示位置,这里设置never表示不会与出现在ActionBar之内(如果空间足够的话),第二个属性为withText,这个属性是将图片与文字一起展示在ActionBar之内(如果空间足够的话),第三个属性为inRoom,直显示图片在ActionBar之内,而icon属性,则就是设置展示的图片。


然后,在onCreatOptionMenu中我们在这里不单单是使用menu文件来,还可以使用menu.add的方法来加入选项;

add方法中包含了四个参数:groupid,itemid,order,和title。groupid是所在的菜单表的id,itemid是自己本身的id(和下方的onOptionsItemSelected方法中的id对应),order是刚才所介绍的order属性,title则是item的中的文字,这个方法之后可以在后面加入.icon方法设置图片,加入setshowAsAction设置显示方式。是不是很简单?

然后,现在来看onOptionItemSelected方法中,是用于设置刚才所设置的菜单的点击事件

onOptionsItemSelected(MenuItem item)


如何拿到特定的item呢?这里便可以使用item.getItemID方法,拿到id,这个id可以使你再menu文件中设置的id,也可以是你再add方法中设定的itemid,然后我们再每个点击事件只有返回true,就可以了。