跳到主要內容

Material Design - Navigation Drawer & Toolbar

Creating a Navigation Drawer

在您決定在應用程序中使用導航抽屜之前,您應該了解導航欄設計指南中定義的用例和設計原則。

DrawerLayout 用來做從左到右拉出來的抽屜效果。
NavigationView 用來在拉出來的畫面上,顯示用戶資料和導覽選單。

安裝

Android Design Support Library 可通過 Gradle 來安裝:
dependencies {
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'
}

準備

AndroidManifest.xml 設定主題使用 android:theme @sytle/MyAppTheme。
res/values/style.xml 新增 MyAppTheme Style
<style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#d90505</item>
        <item name="colorPrimaryDark">@color/colorAccent</item>
        <item name="android:windowActionBar">false</item>
        <!--ActionMode可以覆蓋在Toolbar上面 -->
        <item name="android:windowActionModeOverlay">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <!--statusBarColor設置為透明是因為我們不再需要係統的狀態欄-->
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

設定Layout 

使用DrawerLayout,裡面包著兩個view,第一個是顯示主要內容,會以LinearLayout
加上Toolbar (替代ActionBar) 和 EditText、Button 來呈現。
第二個是導覽選單,使用NavigationView 分成上下兩部份,上面的是headerLayout,
下面為menu部份,會載入 res/menu下的menu

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>

<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"

    android:fitsSystemWindows="true">

    <!--The main content view-->

    <LinearLayout

        android:id="@+id/main_LinearLayout"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical">

        <android.support.v7.widget.Toolbar

            android:id="@+id/toolbar"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="?attr/colorPrimary"

            android:minHeight="?attr/actionBarSize"

            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

        <EditText

            android:id="@+id/editText"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:ems="10"

            android:inputType="textPersonName"

            android:text=""/>

        <Button

            android:id="@+id/button"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="Button"/>

    </LinearLayout>

    <!--The navigation drawer-->

    <android.support.design.widget.NavigationView

        android:id="@+id/navigation_view"

        android:layout_width="wrap_content"

        android:layout_height="match_parent"

        android:layout_gravity = "start"

        app:headerLayout="@layout/drawer_header"

        app:menu="@menu/drawer_menu">

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

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


NavigationView 中的 headerLayout 指向 res/layout/drawer_header.xml
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="190dp"

    android:background="#d11013">

    <TextView

        android:id="@+id/textHeader"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Header"

        android:textSize="14sp"

        android:textColor="#fff"

        android:textStyle="bold"

        android:paddingBottom="8dp"

        android:layout_marginStart="24dp"

        android:layout_alignParentBottom="true"/>

</RelativeLayout>


設定 menu /res/menu/drawer.xml
<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

 <group android:checkableBehavior="single">

     <item

         android:id="@+id/navigation_item_1"

         android:checked="true"

         android:icon="@drawable/ic_star_black_24dp"

         android:title="Navigation Items 1"/>

     <item

         android:id="@+id/navigation_item_2"

         android:icon="@drawable/ic_star_black_24dp"

         android:title="Navigation Items 2"/>

     <item

         android:id="@+id/navigation_item_3"

         android:icon="@drawable/ic_star_black_24dp"

         android:title="Navigation Items 3"/>

 </group>

</menu>


Configuration Change

有沒有發覺旋轉螢幕後 menu 和 contentView 會被重設?這是因為旋轉螢幕等於
Configuration Change 後 Activity 會被消滅然後重生,等於執行了 onDestory() 後再 onCreate()。除非有特別處理,否則所有 variable 都會被 reset。
要如何記著剛才按了的menu ?這便要用 onSaveInstanceState() 。
MainActivity.java
public class MainActivity extends AppCompatActivity {

    DrawerLayout mDrawerLayout;

    Toolbar toolbar;

    NavigationView navigationView;

    TextView contentTextView;

    EditText editText;

    Button btnOk;


    //在Toolbar上加上「三」圖示

    ActionBarDrawerToggle drawerToggle;

    private static final String NAV_ITEM_ID = "nav_index";

    //用來儲存點擊了的 menuItem id,必免旋轉螢幕後 menu 和 contentTextView 會被重設

    private int navItemId;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initView();

        initHandler();

        if (null != savedInstanceState){

            navItemId = savedInstanceState.getInt(NAV_ITEM_ID, R.id.navigation_item_1);

        } else {

            navItemId = R.id.navigation_item_1;

        }

        navigateTo(navigationView.getMenu().findItem(navItemId));

    }

    private void initView() {

        // Set a Toolbar to replace the ActionBar.

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

        setSupportActionBar(toolbar);

        // The main content view

        contentTextView = (TextView)findViewById(R.id.content_TextView);

        editText = (EditText)findViewById(R.id.content_Edit);

        btnOk = (Button)findViewById(R.id.btnOk);

        //The navigation drawer

        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);

        navigationView = (NavigationView)findViewById(R.id.navigation_view);

    }

    private void initHandler() {

        /**
         * 因為不是使用 onCreateOptionsMenu() 來載入導覽菜單,
         * 不能用 onOptionsItemSelected() 來設定反應,
         * 要加上 OnNavigationItemSelectedListener 來操作。
         */

        navigationView.setNavigationItemSelectedListener(

                new NavigationView.OnNavigationItemSelectedListener() {

            @Override

            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

                Toast.makeText(MainActivity.this, menuItem.getTitle() + "pressed",

                        Toast.LENGTH_SHORT).show();

                navigateTo(menuItem);

                mDrawerLayout.closeDrawers();

                return true;

            }

        });


        //在Toolbar上加上「三」圖示

        drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar,

                R.string.drawer_open,  R.string.drawer_close){

            @Override

            public void onDrawerOpened(View drawerView) {

                super.onDrawerOpened(drawerView);

            }

            @Override

            public void onDrawerClosed(View drawerView) {

                super.onDrawerClosed(drawerView);

            }

        };

        mDrawerLayout.addDrawerListener(drawerToggle);

        drawerToggle.syncState();

    }

    /**

     * Configuration Change

     *

     */

    private void navigateTo(MenuItem menuItem) {

        contentTextView.setText(menuItem.getTitle());

        navItemId = menuItem.getItemId();

        menuItem.setCheckable(true);

    }

    @Override

    protected void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);

        outState.putInt(NAV_ITEM_ID, navItemId);

    }

}


References




留言

這個網誌中的熱門文章

SQLite - RecyclerView and SearchView

設計資料庫表格 建立資料庫表格使用SQL的「CREATE TABLE」指令,這個指令需要指定表格的名稱, 還有這個表格用來儲存每一筆資料的欄位(Column)。 這些需要的表格欄位可以對應到主要類別中的欄位變數, 不過SQLite資料庫的資料型態只有下面這幾種,使用它們來決定表格欄位可以儲存的資料型態: INTEGER – 整數,對應Java 的byte、short、int 和long。 REAL – 小數,對應Java 的float 和double。 TEXT – 字串,對應Java 的String。 一個SQLite表格建議一定要包含一個可以自動為資料編號的欄位,欄位名稱固定為「 _id 」,型態為「INTEGER」。 後面加上「 PRIMARY KEY AUTOINCREMENT 」的設定,就可以讓SQLite自動為每一筆資料編號。 建立SQLiteOpenHelper類別 Android 提供許多方便與簡單的資料庫API,可以簡化應用程式處理資料庫的工作。 這些API都在「android.database.sqlite」套件,它們可以用來執行資料庫的管理和查詢的工作。 這個套件中的「 SQLiteOpenHelper 」類別,可以在應用程式中執行 建立資料庫與表格 的工作,應用程式第一次在裝置執行的時候,由它負責建立應用程式需要的資料庫與表格, 後續執行的時候開啟已經建立好的資料庫讓應用程式使用。 還有應用程式在運作一段時間以後,如果增加或修改功能,資料庫的表格也增加或修改了 ,它也可以為應用程式執行資料庫的修改工作,讓新的應用程式可以正常的運作。 Create New Java Class public class MyDBHelper extends SQLiteOpenHelper{ //資料庫名稱 public static final String DATABASE_NAME = "mydata.db"; //資料庫版本,資料結構改變的時後要更改這個數字,通常是加一 public static final int VERSION = 1; //資料庫物件,固定的欄位變數 private static SQLiteDatabase

Android using BottomNavigationView

Creating Navigation Menu menu_navigation.xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_home" android:icon="@drawable/ic_home" android:title="@string/action_home"/> <item android:id="@+id/action_profile" android:icon="@drawable/ic_person" android:title="@string/action_profile"/> <item android:id="@+id/action_settings" android:icon="@drawable/ic_settings" android:title="@string/action_settings"/> </menu> Creating Layout main_activity.xml <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://

Material Design - Card View and Recycler View

build.gradle (Module.app) 添加CardView,RecyclerView和Glide依賴關係。  RecyclerView用於以網格方式顯示相冊。  CardView用於顯示單個專輯項目。  Glide用於顯示專輯封面圖片。 dependencies {      //CardView     compile 'com.android.support:cardview-v7:25.3.1'     //RecyclerView     compile 'com.android.support:recyclerview-v7:25.3.1'     //Glide ImageLoader....     compile 'com.github.bumptech.glide:glide:3.7.0' } 將以下字符串,顏色和調整資源添加到strings.xml,colors.xml和dimensions.xml文件。 string.xml <resources> <string name="app_name">Card View</string> <string name="action_settings">Settings</string> <string name="action_add_favourite">Add to Favourites</string> <string name="action_play_next">Play Next</string> <string name="backdrop_title">LOVE MUSIC</string> <string name="backdrop_subtitle">This season top 20 albums</string> </resources>