2016年12月4日 星期日

Navigation Drawer 側邊選單教學 (PartIV)


前提回顧:

Navigation Drawer 側邊選單教學 (PartIII)


這一篇教學要來做結尾了,此範例接著上一篇繼續做下去,會教您如何自定義Toolbar實作ActionBar取代內建的ActionBar


styles.xml更改成NoActionBar


<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">




















Layout右鍵新增navigation_actionbox.xml

File name=navigation_actionbox
Root element=android.support.v7.Toolbar

1.設立id:nav_action 高度wrap_content背景顏色@color/colorPrimary
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:orientation="vertical" android:layout_width="match_parent"
   
android:layout_height="wrap_content"
   
android:id="@+id/nav_action"
   
android:background="@color/colorPrimary"
   
android:theme="@style/Base.ThemeOverlay.AppCompat.Dark">

</android.support.v7.widget.Toolbar>

2.此時activity_main.xmlActionbox會不見所以在LinearLayout中加入<include>把剛剛建立自定義的ActionBox加入activity_main.xml
<include layout="@layout/navigation_actionbox"
   
android:layout_width="match_parent"
   
android:layout_height="wrap_content"/>

另外LinearLayoutorientation改成vertical垂直




















3.在自定義的navigation_actionbox.xml更改主題配色
android:theme="@style/Base.ThemeOverlay.AppCompat.Dark">




















●MainActivity.java撰寫程式

1.剛剛已經把Toolbar版面用出來了,接著在程式中建立Toolbar變數然後
setSupportActionBar( mToolbar )  Toolbar就能取代原本的ActionBar了

2.另外要讓清單選項觸發動作要實作implements NavigationView.OnNavigationItemSelectedListener 
並不是在onOptionsItemSelected()中去實作

MainActivity.java程式碼
package com.example.andy6804tw.navigationapp;


import
android.support.design.widget.NavigationView;
import
android.support.v4.widget.DrawerLayout;
import
android.support.v7.app.ActionBarDrawerToggle;
import
android.support.v7.app.AppCompatActivity;
import
android.os.Bundle;
import
android.support.v7.widget.Toolbar;
import
android.view.MenuItem;
import
android.widget.Toast;

public class
MainActivity  extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

   
private DrawerLayout mDrawerLayout;
    private
ActionBarDrawerToggle mToggle;//元件觸發

   
private Toolbar mToolboar;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);

       
mToolboar=(Toolbar)findViewById(R.id.nav_action);
       
setSupportActionBar(mToolboar);//Toolbar取代原本的ActionBar

       
mDrawerLayout=(DrawerLayout)findViewById(R.id.drawerLayout);
       
mToggle=new ActionBarDrawerToggle(this,mDrawerLayout,R.string.open,R.string.close);//必須用字串資源檔
       
mDrawerLayout.addDrawerListener(mToggle);//工具欄監聽事件

       
mToggle.syncState();
       
getSupportActionBar().setDisplayHomeAsUpEnabled(true);//隱藏顯示箭頭返回

       
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
       
navigationView.setNavigationItemSelectedListener(this);//清單觸發監聽事件

   
}
   
@Override
   
public boolean onNavigationItemSelected(MenuItem item) {//實作清單觸發
       
int id = item.getItemId();

        if
(id == R.id.nav_account) {
            Toast.makeText(
this,"account",Toast.LENGTH_SHORT).show();

       
}
       
else if (id == R.id.nav_settings)
        {
            Toast.makeText(
this,"settings",Toast.LENGTH_SHORT).show();

       
}
       
else if (id == R.id.nav_logout)
        {
            Toast.makeText(
this,"logout",Toast.LENGTH_SHORT).show();

       
}
       
return true;
   
}

   
@Override
   
public boolean onOptionsItemSelected(MenuItem item) {

       
if(mToggle.onOptionsItemSelected(item)){//當按下左上三條線或顯示工具列
           
return true;
       
}
       
return super.onOptionsItemSelected(item);
   
}

}

執行結果




8 則留言:

  1. 回覆
    1. 他是NavigationView哦是一個側邊工具欄的id=nav_view,請參考part1
      http://1010code.blogspot.tw/2016/12/navigation-drawer-part1.html

      刪除
  2. 看半天原來是要在layout的NavigationView中再自己加id~

    回覆刪除
  3. setNavigationItemSelectedListener

    用在哪兒了呢!?

    回覆刪除
    回覆
    1. 程式碼內有哦~
      如果同學你的問題是底下會出現紅底線
      可用Alt+Enter出現提示點選實作OnNavigationItemSelectedListener
      又或者自己加

      刪除
    2. 您好,謝謝您的回覆,有看見了

      另外我實作上發現了兩個問題,
      1. 開啟app時,選單預設是展開的
      2. 點擊Toolbar左上的<-符號,會出現crash,我嘗試了stackoverfollow的方式還是無法解決,不太確定問題是什麼,logcat如下:
      java.lang.IllegalArgumentException: No drawer view found with gravity LEFT
      at android.support.v4.widget.DrawerLayout.openDrawer(DrawerLayout.java:1651)
      at android.support.v4.widget.DrawerLayout.openDrawer(DrawerLayout.java:1637)
      at android.support.v7.app.ActionBarDrawerToggle.toggle(ActionBarDrawerToggle.java:294)
      at android.support.v7.app.ActionBarDrawerToggle$1.onClick(ActionBarDrawerToggle.java:203)
      at android.view.View.performClick(View.java:4785)
      at android.view.View$PerformClick.run(View.java:19858)
      at android.os.Handler.handleCallback(Handler.java:739)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:155)
      at android.app.ActivityThread.main(ActivityThread.java:5696)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:372)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

      刪除
  4. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 加入此段,就可以按back鍵返回主頁而不是退出程式

      @Override
      public void onBackPressed() {
      DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawerLayout);
      if (drawer.isDrawerOpen(GravityCompat.START)) {
      drawer.closeDrawer(GravityCompat.START);
      } else {
      super.onBackPressed();
      }
      }

      刪除