NavigationDrawer using only Android Support Library

17,388

Solution 1

First you need to extend ActionBarActivity instead of FragmentActivity

Second change your App Theme to @style/Theme.AppCompat or @style/Theme.AppCompat.Light

Third change every call to getActionBar() for getSupportActionBar() and invalidateOptionsMenu() for supportInvalidateOptionsMenu()

That should do, here is the google example using AppCompat-v7 i did to test it, I also used a custom adapter for the listview just ignore that :)

https://github.com/BradleyRL/NavDrawerExampleAppCompat-v7

Solution 2

all you have to do is just import the v4 support library in your project and you can just follow the example in the docs that you linked.

its the same thing for any version of android 2.2 and up, just substitute any fragment use with support fragment usage from the library

Share:
17,388
user1518451
Author by

user1518451

Updated on June 13, 2022

Comments

  • user1518451
    user1518451 almost 2 years

    is there any example project which use only Android Support Library (revision 18) to implement Navigation Drawer on Android +2.2 without using any additional library (ABS etc.) ? Here is the example which use ASL but it's work only on API +14 : http://developer.android.com/training/implementing-navigation/nav-drawer.html .

    Here is my MainActivity:

    package com.example.android.navigationdrawerexample;
    
    import java.util.Locale;
    
    import android.app.Activity;
    //import android.app.Fragment;
    //import android.app.FragmentManager;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    
    import android.app.SearchManager;
    import android.content.Intent;
    import android.content.res.Configuration;
    import android.os.Bundle;
    import android.support.v4.app.ActionBarDrawerToggle;
    import android.support.v4.view.GravityCompat;
    import android.support.v4.widget.DrawerLayout;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.Toast;
    
    public class MainActivity extends FragmentActivity {
        private DrawerLayout mDrawerLayout;
        private ListView mDrawerList;
        private ActionBarDrawerToggle mDrawerToggle;
    
        private CharSequence mDrawerTitle;
        private CharSequence mTitle;
        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);
    
            // set a custom shadow that overlays the main content when the drawer opens
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
            // set up the drawer's list view with items and click listener
            mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                    R.layout.drawer_list_item, mPlanetTitles));
            mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    
            // enable ActionBar app icon to behave as action to toggle nav drawer
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
    
            /* ActionBarDrawerToggle ties together the the proper interactions
            between the sliding drawer and the action bar app icon */
            mDrawerToggle = new ActionBarDrawerToggle(
                    this,                  /* host Activity */
                    mDrawerLayout,         /* DrawerLayout object */
                    R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                    R.string.drawer_open,  /* "open drawer" description for accessibility */
                    R.string.drawer_close  /* "close drawer" description for accessibility */
                    ) {
                public void onDrawerClosed(View view) {
                    getActionBar().setTitle(mTitle);
                    invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                }
    
                public void onDrawerOpened(View drawerView) {
                    getActionBar().setTitle(mDrawerTitle);
                    invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            if (savedInstanceState == null) {
                selectItem(0);
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.main, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        /* 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);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
             // The action bar home/up action should open or close the drawer.
             // ActionBarDrawerToggle will take care of this.
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle action buttons
            switch(item.getItemId()) {
            case R.id.action_websearch:
                // create intent to perform web search for this planet
                Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
                intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
                // catch event that there's no activity to handle intent
                if (intent.resolveActivity(getPackageManager()) != null) {
                    startActivity(intent);
                } else {
                    Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }
    
        /* The click listner for ListView in the navigation drawer */
        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
            Fragment fragment = new PlanetFragment();
            Bundle args = new Bundle();
            args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
            fragment.setArguments(args);
    
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
    
            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
    
        @Override
        public void setTitle(CharSequence title) {
            mTitle = title;
            getActionBar().setTitle(mTitle);
        }
    
        /**
         * When using the ActionBarDrawerToggle, you must call it during
         * onPostCreate() and onConfigurationChanged()...
         */
    
        @Override
        protected void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            // Sync the toggle state after onRestoreInstanceState has occurred.
            mDrawerToggle.syncState();
        }
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            // Pass any configuration change to the drawer toggls
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    
        /**
         * Fragment that appears in the "content_frame", shows a planet
         */
        public static class PlanetFragment extends Fragment {
            public static final String ARG_PLANET_NUMBER = "planet_number";
    
            public PlanetFragment() {
                // Empty constructor required for fragment subclasses
            }
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
                int i = getArguments().getInt(ARG_PLANET_NUMBER);
                String planet = getResources().getStringArray(R.array.planets_array)[i];
    
                int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
                                "drawable", getActivity().getPackageName());
                ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
                getActivity().setTitle(planet);
                return rootView;
            }
        }
    }
    

    and of course i change minSdk to 8 but it still doesn't work.

  • tyczj
    tyczj over 10 years
    it only works on SDK 14 and up because that is what the sample project is set for. make your own project setting the min sdk to 8 and follow the tutorial. What is the problem you are having when running the example?
  • tyczj
    tyczj over 10 years
    it still does not tell me what is the problem you are having. Do what I said, create a new example project using what you want, import the library and follow the tutorial and dont use the code from the demo project
  • Ridcully
    Ridcully over 10 years
    Instead of posting all your code, try to explain what exactly does not work as expected. Nobody will read such a bunch of code.
  • user1518451
    user1518451 over 10 years
    Thanks, i import your project but i have bug in res/layout/drawer_list_item.xml and activity_main.xml: Failed to find style 'textViewStyle' in current theme android.content.res.Resources$NotFoundException "?attr/listPreferredItemHeightSmall" in attribute "minHeight" is not a valid format.
  • BradR
    BradR over 10 years
    Did you export the whole project? and have the library AppCompat-v7 on eclipse?
  • user1518451
    user1518451 over 10 years
    Yes I import whole project and add android-support-v7-appcompat.jar to libs. Any other suggestion ?
  • BradR
    BradR over 10 years
    You dont have to add the android-support-v7-appcompat.jar to libs directory :S you better read how to set up the library from the google site developer.android.com/tools/support-library/setup.html especially the "Adding libraries with resources" section
  • user1518451
    user1518451 over 10 years
    Now I have an error: The container Android Dependencies' references non existing library '/home/jack/Android/adt-bundle-linux-x86-20130522/sdk/extras‌​/android/support/v7/‌​appcompat/bin/androi‌​d-support-v7-appcomp‌​at.jar Ant other suggestion ?