Search code examples
androidmenuimageviewsidebar

Setup an imageview to open sidebar/menu android


Instead of using actionbar and setting up an icon, I could not use actionbar here. What I really want to do is to setup an imageview, which responds to user's click. When it is clicked, sidebar/menu will open or close, just like clicking on physical button at the button of android phone.
Is there any easy way to do so? (all the items in the sidebar are already done and work fine. I checked it by clicking on physical menu button on my phone)


Solution

  • Felt worthwhile to put the code for this example up on GitHub, as it was getting quite long:

    Just set an OnClickListener to your ImageView, in the same way you would a Button.

    ImageView imageView = (ImageView) findViewById(R.id.image_view);
    imageView.setOnClickListener(this);
    //...
    @Override
    public void onClick(View v) {
        if(!mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
            mDrawerLayout.openDrawer(GravityCompat.START);
        } else {
            mDrawerLayout.closeDrawer(GravityCompat.START);
        } 
    }
    

    You may want to add android:clickable = "true" to the xml for your ImageView, and android:background="?android:attr/selectableItemBackground" to gain feedback when the item is clicked.

    This assumes you've set up your DrawerLayout somewhat like the following:

    public class MainActivity extends AppCompatActivity {
    
        private DrawerLayout mDrawerLayout = null;
        private ActionBarDrawerToggle mActionBarDrawerToggle = null;
        private RecyclerView mRecyclerView = null;
        private NavMenuAdapter adapter = null;
    
        private ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mActionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
            mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
    
            mRecyclerView = (RecyclerView) findViewById(R.id.navigation_menu_recycler);
    
            adapter = new NavMenuAdapter();
            mRecyclerView.setAdapter(adapter);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    
            imageView = (ImageView) findViewById(R.id.image_view);
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                        mDrawerLayout.openDrawer(GravityCompat.START);
                    } else {
                        mDrawerLayout.closeDrawer(GravityCompat.START);
                    }
                }
            });
    
        }
    
        @Override
        protected void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            mActionBarDrawerToggle.syncState();
        }
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            mActionBarDrawerToggle.onConfigurationChanged(newConfig);
        }
    

    Edit: If you would like more control, you can define various states for your ImageView with a state list drawable, and use it in android:background instead of the above suggestion. Create a new xml file in your drawable folder (i.e. custom_selector.xml) with the following template:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/image_pressed"
              android:state_pressed="true" />
        <item android:drawable="@drawable/image_focused"
              android:state_focused="true" />
        <item android:drawable="@drawable/image_normal" />
    </selector>
    

    And define relevant images for pressed, focused/hover and normal states. Apply it with:

    android:background="@drawable/custom_selector"