1. 程式人生 > >第一行程式碼----Material Design(1-3)

第一行程式碼----Material Design(1-3)

今天看完了第一行程式碼的第十二章,順手寫篇部落格就當是複習總結吧,大家有什麼想法也可以提出來一起討論討論,能一起進步當然是最好的哈!

本章節共分為8個小節,個別小節又有不止一個知識點,所以總體來說這章的內容蠻多的呢,需要我們認真對待哦!

1.什麼是Material Design

簡單來說,Material Design就是一套由谷歌推出的出色的、全新的的介面設計語言,沒了

2.Toolbar

一個Material控制元件,繼承ActionBar(標題欄)但是更加的靈活好用,現在常用來代替ActionBar。 它要怎麼替代預設的ActionBar呢?首先隱藏原生的標題欄,修改res->values->styles.xml檔案裡的parent屬性,有兩種選擇:Theme.AppCompat.Light.NoActionBar

Theme.AppCompat.NoActionBar。前者是淺色主題,後者深色主題,這裡我選擇前者淺色主題。styles.xml檔案可以修改一些item屬性,不過我試了試,textColorPrimary、windowBackground和navigationBarColor都沒效果,我也沒深究,不知道是什麼原因? 然後,修改activity_main.xml中的程式碼:

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
	<android.support.v7.widget.Toolbar
    android:id="@+id/toolbars"
    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"/>

其中xmlns:app是為了相容5.0版本前的老系統;android:theme是為了讓Toolbar使用深色主題;app:popupTheme是為了讓彈出的選單項使用淺色主題。 最後,修改MainActivity,加入兩行程式碼即可:

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

只有一個標題太單調,下面來新增一些按鈕圖示 圖示圖片放到drawable-xxhdpi目錄下,然後在res目錄下新建一個menu檔案下,並在其下再建一個toolbar.xml檔案,程式碼如下:

 <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/backup"
            android:icon="@drawable/ic_backup"
            android:title="Backup"
            app:showAsAction="always"/>
        <item
            android:id="@+id/delete"
            android:icon="@drawable/ic_delete"
            android:title="Delete"
            app:showAsAction="ifRoom"/>
        <item
            android:id="@+id/setting"
            android:icon="@drawable/ic_settings"
            android:title="Setting"
            app:showAsAction="never"/>
</menu>

要說明的只有app:showAsAction,它是用來指定按鈕的顯示位置,其中always表示永遠顯示在Toolbar裡,空間不夠則不顯示;ifRoom表示螢幕空間足夠就顯示在Toolbar裡,不夠就顯示在選單裡;never表示永遠顯示在選單裡。 最後,修改MainActivity:

    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.backup:
                Toast.makeText(this,"You clicked Backup",Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
                break;
            case R.id.setting:
                Toast.makeText(this,"You clicked setting",Toast.LENGTH_SHORT).show();
                break;
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                break;
            default:
        }
        return true;
    }

其中onCreateOptionsMenu()方法里加載了toolbar.xml選單檔案,然後在onOptionsItemSelected()裡處理了各個按鈕的點選事件。

3.滑動選單

滑動選單即隱藏一部分選單,節省螢幕空間,通過滑動可以顯示出來。 滑動選單主要通過 DrawerLayout 控制元件實現,該控制元件其實是一個佈局,有兩個直接子控制元件,第一個子控制元件用來顯示主螢幕內容,第二個子控制元件用來顯示滑動選單裡的內容。

<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
  		內容不變
    </FrameLayout>
    <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="start"/>
    </android.support.v4.widget.DrawerLayout>

其中TextView中的android:layout_gravity="start"指定滑動選單在哪邊取決於系統語言是從哪到哪的,當然也可以直接指定leftright接下來,加入一個導航按鈕,實現點選該按鈕也能展示滑動選單的功能,依然是先放圖示圖片到drawable-xxhdpi目錄下,接著修改MainActivity程式碼,在oncrete()中加入程式碼:

  private DrawerLayout mDrawerLayout;
  mDrawerLayout=(DrawerLayout)findViewById(R.id.drawer_layout);
  ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);//顯示導航按鈕,預設為返回箭頭
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);//把返回箭頭換成menu圖示
        }

再在onOptionsItemSelected()里加入程式碼:

//HomeAsUp的id永遠都是android.R.id.home
case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                break;

此部分完成 但滑動選單並不美觀,我們需要繼續修改,使用 NavigationView 控制元件非常方便 首先新增依賴關係,開啟app/build.gradle檔案,加入:

compile 'com.android.support:design:27.+'
compile 'de.hdodenhof:circleimageview:2.1.0'

注意要跟自己的sdk版本保持一致,確定不了就用 “+” 來泛指。第二個依賴是一個開源專案,用來實現圖片圓形化的功能。 接下來要準備一個menu和headerLayout頭部佈局,先準備menu,依然是先放圖表圖片到drawable-xxhdpi目錄下,然後在menu下新建一個nav_menu檔案:

  <menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_call"
            android:icon="@drawable/nav_call"
            android:title="Call"/>
        <item
            android:id="@+id/nav_friends"
            android:icon="@drawable/nav_friends"
            android:title="Friends"/>
        <item
            android:id="@+id/nav_location"
            android:icon="@drawable/nav_location"
            android:title="Location"/>
        <item
            android:id="@+id/nav_mail"
            android:icon="@drawable/nav_mail"
            android:title="Mail"/>
        <item
            android:id="@+id/nav_task"
            android:icon="@drawable/nav_task"
            android:title="Task"/>
    </group>
</menu>

menu中巢狀一個group標籤,表示一個組,**android:checkableBehavior=“single”**指定組中所有項只能單選。 接著在layout裡新建一個Layout resource file檔案,名為nav_header.xml,程式碼如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="180dp"
    android:padding="10dp"  android:background="?attr/colorPrimary">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon_image"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/nav_icon"
        android:layout_centerInParent="true"/>
    <TextView
        android:id="@+id/mail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="[email protected]"
        android:textColor="#FFF"
        android:textSize="14sp"/>
    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/mail"
        android:text="Tony Green"
        android:textColor="#FFF"
        android:textSize="14sp"/>

</RelativeLayout>

這裡只說一下padding,它意味著該屬性所在的主控制元件中內部佈局(子控制元件)的邊距;而margin恰恰相反,margin意味著該屬性所在的主控制元件中外部佈局(父佈局)的邊距。 最後, 修改activity_main.xml程式碼,用下面的程式碼替換掉原來的TextView:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"/>

再修改MainActivity裡的程式碼,在onCreate()里加入:

NavigationView navView=(NavigationView)findViewById(R.id.nav_view);
navView.setCheckedItem(R.id.nav_call);//預設選中項
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                mDrawerLayout.closeDrawers();
                return true;
            }
        });