Showing posts with label Navigation Drawer. Show all posts
Showing posts with label Navigation Drawer. Show all posts

Thursday, June 19, 2014

Navigation Drawer Icon in Action Bar without Using Drawer Layout

This post help us to get navigation drawer icon without android drawer layout in the Action Bar.

Enable action bar icon to support navigation drawer toggle.
// Set whether home should be displayed as an "up" affordance.
// Set this to true if selecting "home" returns up by a single level in your UI rather than back to the top level or front page.
getActionBar().setDisplayHomeAsUpEnabled(true);
//Enable or disable the "home" button in the corner of the action bar.
getActionBar().setHomeButtonEnabled(true);

We should be aware of navigation drawer before starting, navigation drawer helps user to bring the navigation drawer onto the screen by swiping from the left edge of the screen or by touching the application icon on the action bar.

On Tap of application icon, Navigation drawer opens by using DrawerLayout listeners, where ActionBarDrawerToggle supports us from toggling the drawer.

This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.

ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int drawerImageRes, int openDrawerContentDescRes, int closeDrawerContentDescRes)

Construct a new ActionBarDrawerToggle.
The given Activity will be linked to the specified DrawerLayout. The provided drawer indicator drawable will animate slightly off-screen as the drawer is opened, indicating that in the open state the drawer will move off-screen when pressed and in the closed state the drawer will move on-screen when pressed.
String resources must be provided to describe the open/close drawer actions for accessibility services.
Parameters

activity The Activity hosting the drawer
drawerLayout The DrawerLayout to link to the given Activity's ActionBar
drawerImageRes A Drawable resource to use as the drawer indicator
openDrawerContentDescRes A String resource to describe the "open drawer" action for accessibility
closeDrawerContentDescRes A String resource to describe the "close drawer" action for accessibility

The third parameter is the drawable which we are seeing beside the action bar icon.

Now the question, How can we update the navigation drawer icon without DrawerLayout?

Just call updateNavigationDrawerIcon method after enabling the action bar methods.

public void updateNavigationDrawerIcon(Drawable drawable) {
Method setHomeAsUpIndicator;
           try {
           setHomeAsUpIndicator = ActionBar.class.getDeclaredMethod("setHomeAsUpIndicator",            Drawable.class);
           setHomeAsUpIndicator.invoke(getActionBar(), drawable);
           } catch (NoSuchMethodException e) {
                      Log.e("CHECK", "No Such Method");
                      View home = findViewById(android.R.id.home);
                      ViewGroup parent = (ViewGroup) home.getParent();
                      int childCount = parent.getChildCount();
                      if (childCount == 2) {
                                final View first = parent.getChildAt(0);
                                final View second = parent.getChildAt(1);
                               final View up = first.getId() == android.R.id.home ? second : first;
                                 ((ImageView) up).setImageDrawable(drawable);
                      }
           } catch (Exception e) {
           e.printStackTrace();
           }
}

On click of app icon, we will be invoking onOptionsItemSelected method.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

           switch (item.getItemId()) {
           case android.R.id.home:
                      Log.d("CHECK", "Navigation Icon is selected");
                      // Use for slide from left to right
                      slide_me.toggleLeftDrawer();
                      break;
           }
           return super.onOptionsItemSelected(item);
}

Output:




Source Code
You can download the source code by Source Code Click Here.  This project is built using eclipse IDE. Unzip and import the project into Eclipse, it’s a good idea to use the Project by clean and rebuild from the project menu. It works in all API levels above 14.

Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments.

Sunday, May 25, 2014

Android Custom Navigation Drawer Using ExpandableListView with Highlight for selected item

This post is improvements to the previous posts discussed on customization of navigation drawer and highlighting specific row of expandable listview.

Since there are few comments regarding the highlight of expandable list view post, thought to show with new post using custom navigation drawer. But how can we see the highlight of the expandable list view in handset, let’s take navigation drawer and customize it to use expandable list view.

Before starting, I have faced few problems before starting expandablelistview and few questions are shown below. They are?
1.   How and why onchildclicklistener won’t respond but ongroupclicklistener responding?
2.   Whether we can have different background to the group view and child view?
3.   How to highlight the group row or child row on selecting?
4.   How to give the feedback on selection of other row when there is a highlight shown on the other row?

Let’s start knowing the solution for the questions faced.
1.   How to get respond for OnChildClickListener and where will be the problem?
Solution: return true in isChildSelectable method of custom adapter.
Reason: When we extend BaseExpandableListAdapter of ExpandableListView adapter, we will be forced to override few methods. In one of the abstract method, we have isChildSelectable(int groupPosition, int childPosition) which in turn returns false default when we implement. Since it is false, we are unable to get respond OnChildClickListener. Turn it true to solve the porblem.

2.   Whether we can have different backgrounds to group and child views?
Solution: Yes
Reason: use custom adapter for expandablelistview and override getGroupView and getChildView method, and use different inflater.inflate xml’s to achieve it.

Create 2 layouts, one for group view and other for child view, let say as custom_list_view.xml and custom_list_view_child.xml
Inflate the layouts in the respective methods of getGroupView and getChildView and add android:background=" " to the layout.

3.   How to highlight the respective rows?
Solution: By using drawable xml’s and ItemChecked method of ExpandableListView.
Reason: drawable xml specify which color has to be shown on active of row and ItemChecked method specify which row has to be highlighted.

4.   How to give feedback for other rows in the list view?
Solution: By adding state_pressed item in the drawable xml’s.
Reason: Since the drawable xml is mapped to the layout, the action of the row is handled by the drawable xml. So, by adding state_pressed in the xml, we can get feedback when user press on the other row of the xml.

Source Code
You can download the source code by clicking Here.  This project is built using eclipse IDE. Unzip and import the project into Eclipse, it’s a good idea to use the Project by clean and rebuild from the project menu. It works in all API levels above 14.

Output
We can see, all four question answered in the below image.
Customized Navigation Drawer
Background color's : White for Group View and Orange for Child Views.
Highlighted Color : Blue
Feedback Color : Green




Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments.

Wednesday, May 21, 2014

Android: Solution for Custom Navigation Drawer not responding to Click

This post is about to solve and share the issue of navigation drawer when there is no action of the items of the list view.

Why the navigation drawer is not responding to the click's ? :-?

First we should know few information of navigation drawer.
What is Navigation Drawer? How to customize it? and lot more…

What is Navigation Drawer?
The navigation drawer is a panel that displays the app’s main navigation options on the left edge of the screen. It is hidden most of the time, but is revealed when the user swipes a finger from the left edge of the screen or, while at the top level of the app, the user touches the app icon in the action bar.

To add a navigation drawer, declare your user interface with a DrawerLayout object as the root view of your layout. Inside the DrawerLayout, add one view that contains the main content for the screen (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer.

What is DrawerLayout?
DrawerLayout acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from the edge of the window.

How to customize the navigation drawer?

Since the drawer layout adds only two views, and one view contains content of the screen and other view contains the navigation drawer content. So, we can use only two views in customization also.

Foe Eg: android example looks like this.


    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
   
   
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
   
    android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>



Customization example follows as:


    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
   
   
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer →
<LinearLayout android:id="@+id/drawer_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_gravity="start"
              android:background="@android:color/white"
              android:orientation="vertical" >
                android:id="@+id/left_drawer"
                    android:layout_width="240dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="start"
                    android:choiceMode="singleChoice"
                    android:divider="@android:color/transparent"
                    android:dividerHeight="0dp"
                    android:background="#111"/>
</LinearLayout>



When we try to use the custom navigation drawer, there is scope where your navigation drawer linear layout change the view not being front, even the view is shown as front, we can call as Z ordering.

What is Z order?
The views are added in the group, should be order in the tree.

This scenario we can face in android 2.3 versions (gingerbread) when we scroll navigation drawer, then we won’t have action on list view of the navigation drawer. 

Finally we came to the issue what we are discussing about while start of the post, let’s look how to solve the issue below.

*-:)Issue is regarding the Z order of the view.

Then How to solve this Z order :?:

We should know about the bringToFront() method of View Class. Which solves our problem.

Know, we will use the above method in the scroll listener of list view, by calling the bringToFront() of the list and then requestLayout() of the drawer when the scroll states  is idle as shows

mDrawerList.setOnScrollListener(new OnScrollListener() {
           
            @Override
           public void onScrollStateChanged(AbsListView view, int scrollState) {
                       if (scrollState == SCROLL_STATE_IDLE) {
                                 mDrawerList.bringToFront();
                                    mDrawerLayout.requestLayout();
                        }               
            }
           
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      }
});

Issue is fixed...:-bd
Hope you have enjoyed by reading post...:smile: 


Improvements

If you want to see an example of customizing navigation drawer then, see Custom Navigation Drawer This example supports from API levels.

Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments.