44
votes

I am working on an android project and I'm trying to integrate the new Navigation Drawer using the example from http://developer.android.com/training/implementing-navigation/nav-drawer.html.

Its mostly working except for one thing, the action bar up button doesn't display the menu, but if I swipe my finger over the main activity screen from the edge, then the menu appears, so I know there's nothing wrong with the actual menu, its just the action bar button.

Below is the code

public class MainActivity extends Activity {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;
    private String[] mPlanetTitles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);

        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList = (ListView)findViewById(R.id.left_drawer);


        MenuItemAdapter menuAdapter = new MenuItemAdapter(this);

        menuAdapter.add(new MenuItem("Hello"));
        menuAdapter.add(new MenuItem("World"));
        menuAdapter.add(new MenuItem("Parsnips"));
        menuAdapter.add(new MenuItem("Turnips"));

        mDrawerList.setAdapter(menuAdapter);

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        mDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                R.drawable.ic_drawer, 
                R.string.drawer_open,
                R.string.drawer_closed)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);
        if (savedInstanceState ==  null)
        {
            selectItem(0);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    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) {
        // update the main content by replacing fragments

        android.app.Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
        args.putInt(PlanetFragment.ARGS_PLANET_NUMBER, position);
        fragment.setArguments(args);

        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    public static class PlanetFragment extends android.app.Fragment
    {
        public static final String ARGS_PLANET_NUMBER = "planet_number";

        public PlanetFragment()
        {

        }

        @Override
        public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflator.inflate(R.layout.fragment_planet, container, false);
            int i = getArguments().getInt(ARGS_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];

            //((TextView)rootView.findViewById(R.id.fragment_text_view)).setText(planet);
            getActivity().setTitle("Planet: " + planet);
            return rootView;
        }
    }

    private class MenuItem
    {
        public String menuName;

        public MenuItem(String menuName)
        {
            this.menuName = menuName;
        }
    }

    public class MenuItemAdapter extends ArrayAdapter<MenuItem>
    {
        public MenuItemAdapter (Context context)
        {
            super(context,0);
        }

        public View getView (int position, View convertView, ViewGroup parent)
        {
            convertView = null;
            if (convertView == null)
            {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_menu_item, null);
            }

            /*TextView title = (TextView)convertView.findViewById(R.id.row_title);
            title.setText(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);*/

            EditText title = (EditText)convertView.findViewById(R.id.row_edittext);
            title.setHint(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);

            return convertView;
        }
    }
}

Thanks for any help you can provide.

4

4 Answers

162
votes

You forgot to implement onOptionsItemSelected

This is where the magic happens:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }
6
votes

For those who are still having trouble, you may be missing this method (which OP has but I had deleted):

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}
2
votes

Its work for me.

drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mDrawer.openDrawer(GravityCompat.START);
        }
    });
0
votes

Here i will tell you the SIMPLE AND EASY way to create drawer navigation in android without using of android studio.I have just used an ADT to create navigation drawer. Here is the code take a look

activity_main.xml

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout 
        android:id="@+id/mainContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
     <TextView 
        android:id="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="swipe content"/>
     <Button 
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text = "Click to open d"/>
   </RelativeLayout>
   <RelativeLayout 
        android:id="@+id/drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity = "start"
        android:background="#FFFFFF">
    <TextView 
         android:id="@+id/txt2"
         android:layout_width="200dp"
         android:layout_height="wrap_content"
         android:text="drawer content are here arr"/>
    <Button 
         android:id="@+id/bt2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text = "Click to open d"/>
   </RelativeLayout>

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

MainActivity.java

package com.example.drawer1;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener; 
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private DrawerLayout drawerLayout;
    private View drawerView;
    Button bt1,bt2;
    private DrawerListener myDrawerListner;
    private ActionBarDrawerToggle mDrawerTogle;
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout) findViewById(R.id.dr_layout);
        drawerView = (View) findViewById(R.id.drawer);
        drawerLayout.setDrawerListener(myDrawerListner);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        mDrawerTogle =new ActionBarDrawerToggle(this, drawerLayout,  
        R.drawable.ic_drawer,R.string.open_drawer,R.string.close_drawer){
            public void onDrawerOpened(View drawerView) {
            // TODO Auto-generated method stub
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle("SpeakEng");
            }
            public void onDrawerClosed(View view) {
            // TODO Auto-generated method stub
                super.onDrawerClosed(view);
                getActionBar().setTitle("SpeakEng");
            }
        };
        drawerLayout.setDrawerListener(mDrawerTogle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        bt2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.closeDrawer(drawerView);
            }
        });

        bt1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.openDrawer(drawerView);

            }
        });
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        mDrawerTogle.onConfigurationChanged(newConfig);
    }
    public boolean onOptionsItemSelected(MenuItem item){
        if (mDrawerTogle.onOptionsItemSelected(item)){
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState){
        super.onPostCreate(savedInstanceState);
        //Sync the toogle state after onRestoreInstanceState has occured.
        mDrawerTogle.syncState();
    }
   }

You can open the drawer 1)by clicking on button,2)pulling from left,3)on clicking drawer icon on action bar.as you want you can open it.I gave you three option.

note: drawerLayout must be root element as shown in code. and keep onConfigurationChanged(),onOptionsItemSelected(),onPostCreate(). this three methods are very important to create a navigation drawer.

Best of luck!.