Navigatation Drawer

YH Lin
2 min readFeb 5, 2020

--

先載入dependency

dependencies {implementation 'com.google.android.material:material:1.0.0'}

設計activity_main.xml最外框是DrawerLayer,包覆著LinearLayout。LinearLayout 為 一 Action Bar + Fragment 要切換的區域

<androidx.drawerlayout.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">

<!-- This LinearLayout represents the contents of the screen -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- The ActionBar displayed at the top -->
<include
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- The main content view where fragments are loaded -->
<FrameLayout
android:id="@+id/flContent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- The navigation drawer that comes from the left -->
<!-- Note that `android:layout_gravity` needs to be set to 'start' -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nvView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@android:color/white"
app:headerLayout="@layout/nav_header"
app:menu="@menu/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout

透過app:headerLayout="@layout/nav_header" 來加入header圖像的部分在runtime 時期將會inflat為

NavigationView navigationView = (NavigationView) findViewById(R.id.nvView);
View headerLayout = navigationView.inflateHeaderView(R.layout.nav_header);
ImageView ivHeaderPhoto = headerLayout.findViewById(R.id.imageView);

app:menu="@menu/drawer_view" />來加入選單內容

設計ToolBar

<?xml version="1.0" encoding="utf-8"?><androidx.appcompat.widget.Toolbarxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/toolbar"android:layout_height="wrap_content"android:layout_width="match_parent"android:fitsSystemWindows="true"android:minHeight="?attr/actionBarSize"app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"android:background="?attr/colorPrimaryDark"></androidx.appcompat.widget.Toolbar>

在styles.xml 中調整ActionBar 為<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

如果忘了調整styles.xml , 會引發 error

java.lang.RuntimeException: Unable to start activity ComponentInfo{tw.com.ian.mydrawer/tw.com.ian.mydrawer.MainActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.

設計header

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="192dp"android:background="?attr/colorPrimaryDark"android:padding="16dp"android:theme="@style/ThemeOverlay.AppCompat.Dark"android:orientation="vertical"android:gravity="bottom"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/running"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="史艷文"android:textColor="@android:color/white"android:textAppearance="@style/TextAppearance.AppCompat.Body1"/></LinearLayout>

設計menu

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"><group android:checkableBehavior="single"><itemandroid:id="@+id/medical_fragment"android:icon="@drawable/ic_one"android:title="醫學院" /><itemandroid:id="@+id/chat_fragment"android:icon="@drawable/ic_two"android:title="聊天室" /><itemandroid:id="@+id/game_fragment"android:icon="@drawable/ic_three"android:title="遊戲室" /><item android:title="其他"><menu><group android:checkableBehavior="single"><itemandroid:title="設定" /><itemandroid:title="登入" /></group></menu></item></group></menu>

到此,layout 設計完成。接下來撰寫activity的內容

第4行的toolbar 就是之前設計的toolbar

10~16行綁定DrawerLayout 與Toolbar

19–58 行設定menu 被觸發時要執行的動作

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. toolbar = (Toolbar) findViewById(R.id.toolbar);
  5. setSupportActionBar(toolbar);
  6. // This will display an Up icon (<-), we will replace it with hamburger later
  7. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  8. // Find our drawer view
  9. drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
  10. toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
  11. toggle.setDrawerIndicatorEnabled(true);
  12. toggle.syncState();
  13. // Tie DrawerLayout events to the ActionBarToggle
  14. drawer.addDrawerListener(toggle);
  15. navigationView = (NavigationView) findViewById(R.id.nvView);
  16. navigationView.setNavigationItemSelectedListener(
  17. new NavigationView.OnNavigationItemSelectedListener() {
  18. @Override
  19. public boolean onNavigationItemSelected(MenuItem menuItem) {
  20. Fragment fragment = null;
  21. Class fragmentClass;
  22. switch(menuItem.getItemId()) {
  23. case R.id.medical_fragment:
  24. fragmentClass = MedicalFragment.class;
  25. break;
  26. case R.id.chat_fragment:
  27. fragmentClass = ChatFragment.class;
  28. break;
  29. case R.id.game_fragment:
  30. fragmentClass = GameFragment.class;
  31. break;
  32. default:
  33. fragmentClass = MedicalFragment.class;
  34. }
  35. try {
  36. fragment = (Fragment) fragmentClass.newInstance();
  37. } catch (Exception e) {
  38. e.printStackTrace();
  39. }
  40. // Insert the fragment by replacing any existing fragment
  41. FragmentManager fragmentManager = getSupportFragmentManager();
  42. fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
  43. // Highlight the selected item has been done by NavigationView
  44. menuItem.setChecked(true);
  45. // Set action bar title
  46. setTitle(menuItem.getTitle());
  47. // Close the navigation drawer
  48. drawer.closeDrawers();
  49. return true;
  50. }
  51. });
  52. }

--

--

No responses yet