How to open a new fragment from the navigation drawer?
Asked Answered
H

2

14

I'm using developer.android.com guides to build an app. I choosed "Navigation: Navigation Drawer" when I made a new project in Android Studio. I have searched the internet for answers to my questions but I can't find any that works. Sorry about this, I'm new to programming.

  1. How do I make my app open a new fragment in the main view when clicking in the navigation drawer?
  2. Is it possible to open multiple swipeable fragments with tabs when clicking in the navigation drawer?
  3. How do I make a "title" expandable/collapsible?

http://developer.android.com/design/patterns/navigation-drawer.html http://developer.android.com/training/implementing-navigation/nav-drawer.html

This is how I want the layout to be like:

My layout

title_section* not section_title ;)

Hydromagnetics answered 30/11, 2013 at 17:25 Comment(1)
+1 for great Paint using skills...Orton
J
28

Navigation Drawer is a new and trending design these days. We use two layouts: main content layout and the drawer list layout while designing the xml.layout(layout) for the navigation drawer activity. Here I'm answering all your silly questions.

How do I make my app open a new fragment in the main view when clicking in the navigation drawer?

simply add clicklistener on the drawer list items and replace fragments in the main content depending upon the position of the list item clicked.

Sample code:

    // The click listener for ListView in the navigation drawer
    @SuppressWarnings("unused")
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {

        Fragment newFragment;
        FragmentTransaction transaction = getFragmentManager().beginTransaction();

        switch (position) {
        case 0:
            newFragment = new f1();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 1:
            newFragment = new f2();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 2:
            newFragment = new f3();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 3:
            newFragment = new f4();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;  


        }
        //DrawerList.setItemChecked(position, true);
        setTitle(ListTitles[position]);
        DrawerLayout.closeDrawer(DrawerList);   
    }

Here f1, f2. f3 and f4 are different fragments each having its own layout. you have to create separate java classes for them by inheriting the fragment class.

Is it possible to open multiple swipeable fragments with tabs when clicking in the navigation drawer?

In order implement tabs within a fragment you can use a tabhost inside that particular fragment. Suppose you want to add tabs in fragment f_main.

layout for F_main.xml

<TabHost 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

   <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:orientation="horizontal" />

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

</TabHost>

Then make other fragments f_tab1 and f_tab2 with their corresponding layouts and java classes. Layouts for the two tab fragments can be same or different. here I'm taking them same or a common layout.

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView android:id="@+id/google_map"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="MAP"/>

    </LinearLayout>

Code for F_tab1.java fragment

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class F_tab1 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.friends_list, container,false);


        return view;
    }

}

Code for another fragment. i.e F_tab2.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class F_tab2 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.friends_list, container,false);


        return view;
    }

}

Now simply use clicklistener in the drawer list as mentioned earlier to load F_main on item click in the drawer list which will further load the tabs in the F_main fragmnet in the main content view.

How do I make a "title" expandable/collapsible?

Well I don't know wheather the NV drawer provides this feature or not. But it provides a feature to toggle the action bar title depending upon the drawer item selected or the main content fragment loaded.

As discussed in the Navigation Drawer design guide, you should modify the contents of the action bar when the drawer is visible, such as to change the title and remove action items that are contextual to the main content. The following code shows how you can do so by overriding DrawerLayout.DrawerListener callback methods with an instance of the ActionBarDrawerToggle class as follows

 public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    ...

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

        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    }
Jay answered 3/12, 2013 at 17:32 Comment(6)
Awesome! That's a great answer! Thank you very much! :DHydromagnetics
That's a very detailed answer, awesome!Lifeanddeath
In this way if you click twice on the same navigation drawer item, then you will get the same fragment to be added twice to the back stack (i.e. if you press back button, you will see the same fragment, instead of the previous one).Ponderous
@Aman_devy, and how to open a specific fragment present in the drawer via another activity?Picayune
Every time you just create a new fragment by "newFragment = new f1();", is this a good practise? Do you think it will be better hold all fragments as member variables? So every time user click the menu item, just use "transaction.replace(R.id.content_frame, mFragment1);", no need to create a new fragment.Gallinaceous
how to handle the back pressedSzymanowski
G
0

I used this code:

NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
navController.navigate(R.id.my_new_navigation); 

nav_host_fragment_content_main is defined in content_main.xml

my_new_navigation is defined in file menu_drawer.xml

Gould answered 5/3, 2022 at 18:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.