Adding Home/Profile fragments to the menu drawer


Hook the new fragments into MenuActivity and the drawer menu

Back to 014a: create the fragments drawer

Create the fragments (Android Studio UI)

Create two blank fragments via the Android Studio wizard. Do not diff the generated files here, just make sure these are present:

  • app/src/main/java/com/example/tictacmenu/shell/HomeFragment.java
  • app/src/main/java/com/example/tictacmenu/shell/ProfileFragment.java
  • app/src/main/res/layout/fragment_home.xml
  • app/src/main/res/layout/fragment_profile.xml
  • The wizard-added hello_blank_fragment string in app/src/main/res/values/strings.xml
מה באמת קורה כאשר בוחרים פריט במגירה?

NavigationView אינו מחליף מסך בעצמו. הוא מוסר ל־MenuActivity את ה־MenuItem שנבחר. ה־Activity בודקת את ה־id, יוצרת את ה־Fragment המתאים ומבצעת FragmentTransaction.replace. בפעולת replace ה־View של ה־Fragment הקודם יוצא מן ה־container וה־View של החדש נכנס אליו; סרגל הכלים והמגירה שייכים ל־Activity ולכן נשארים על המסך.

אם לא קוראים ל־addToBackStack, לחיצה על Back אינה חוזרת אוטומטית ל־Fragment הקודם. זו בחירה סבירה במגירה, שבה כל פריט הוא יעד ראשי. במסך אשף או בתהליך רב־שלבי ייתכן שנרצה דווקא להוסיף את העסקה ל־back stack.

Update the drawer menu items

res/menu/menu_drawer.xml gets new items for Home and Profile, and the local game item gets a clearer id.

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

        <item
+            android:id="@+id/nav_home"
+            android:title="@string/menu_home" />

+        <item
+            android:id="@+id/nav_local_game"
            android:title="@string/menu_local_game" />

+        <item
+            android:id="@+id/nav_profile"
+            android:title="@string/menu_profile" />

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

        <item

-            android:id="@+id/nav_main"
            android:title="@string/menu_local_game" />

    </menu>
    

Add the new menu labels

res/values/strings.xml adds labels for the new menu items and removes the old placeholder hint string.

    <resources>
        <string name="app_name">TicTacMenu</string>
        <string name="drawer_open">Open navigation drawer</string>
        <string name="drawer_close">Close navigation drawer</string>
+        <string name="menu_home">Home</string>
        <string name="menu_local_game">Local Game</string>
+        <string name="menu_profile">Profile</string>
        <!-- TODO: Remove or change this placeholder text -->
        <string name="hello_blank_fragment">Hello blank fragment</string>
    </resources>
    
    <resources>
        <string name="app_name">TicTacMenu</string>
        <string name="drawer_open">Open navigation drawer</string>
        <string name="drawer_close">Close navigation drawer</string>
        <string name="menu_local_game">Local Game</string>

-        <string name="menu_hint">Use the menu to start a game.</string>
        <!-- TODO: Remove or change this placeholder text -->
        <string name="hello_blank_fragment">Hello blank fragment</string>
    </resources>
    

Remove the placeholder hint view

With fragments hosting the content, the old hint TextView is removed from res/layout/activity_menu.xml.

        <FrameLayout
            android:id="@+id/content_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
+            android:layout_weight="1" />
    
        <FrameLayout
            android:id="@+id/content_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"

-            android:layout_weight="1">

-            <TextView
-                android:id="@+id/menu_hint"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:text="@string/menu_hint" />
-        </FrameLayout>
    

Wire the drawer selections to fragments

In app/src/main/java/com/example/tictacmenu/shell/MenuActivity.java, add the Fragment import, route menu items to fragments, set a default fragment on first load, and add a helper to replace the content container.

    import androidx.core.view.GravityCompat;
    import androidx.drawerlayout.widget.DrawerLayout;
+ import androidx.fragment.app.Fragment;
    
    import androidx.core.view.GravityCompat;
    import androidx.drawerlayout.widget.DrawerLayout;
    
            NavigationView navigationView = findViewById(R.id.navigation_view);
            navigationView.setNavigationItemSelectedListener(item -> {
+                if (item.getItemId() == R.id.nav_home) {
+                    showFragment(new HomeFragment());
+                } else if (item.getItemId() == R.id.nav_local_game) {
+                    startActivity(new Intent(this, MainActivity.class));
+                } else if (item.getItemId() == R.id.nav_profile) {
+                    showFragment(new ProfileFragment());
+                }
                drawerLayout.closeDrawer(GravityCompat.START);
                return true;
            });

+            if (savedInstanceState == null) {
+                showFragment(new HomeFragment());
+                navigationView.setCheckedItem(R.id.nav_home);
+            }
        }

        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
            if (drawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }

+        private void showFragment(Fragment fragment) {
+            getSupportFragmentManager()
+                    .beginTransaction()
+                    .replace(R.id.content_container, fragment)
+                    .commit();
+        }
    }
    
            NavigationView navigationView = findViewById(R.id.navigation_view);
            navigationView.setNavigationItemSelectedListener(item -> {

-                if (item.getItemId() == R.id.nav_main) {
-                    startActivity(new Intent(this, MainActivity.class));
-                }
                drawerLayout.closeDrawer(GravityCompat.START);
                return true;
            });
        }

        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
            if (drawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }
    

Quick visual check in the Home fragment (optional)

To make it obvious that the fragment is swapping, change the placeholder text in res/layout/fragment_home.xml.

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
+            android:text="TESTHOME" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"

-            android:text="@string/hello_blank_fragment" />
    

Continue

מורה־עזר ב־Gemini

פתחו את Gem: מורה דרך: מסכים ותפריט TicTacMenu כדי לקבל רמזים, שאלות אבחון והסברים המתאימים לשלב שבו אתם נמצאים.