Showing posts with label ExpandableListView. Show all posts
Showing posts with label ExpandableListView. Show all posts

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, October 16, 2013

Android: Highlighting the selected item in the ExpandableListView



Steps to Highlight the selected item in the ExpandableListView

1.    In our ExpandableListView add android:choiceMode and android:listSelector attributes.
To use setItemChecked  we need to Set the checked state of the specified position. The is only valid if the choice mode has been set to CHOICE_MODE_SINGLE or CHOICE_MODE_MULTIPLE.
listSelector is used to indicate the currently selected item in the list. 

2.    Get the position of child using getPackedPositionForChild

3.    Get flat list position using getFlatListPosition.

4.    setItemChecked with the list position we get in step 2.

5.    Create row_highlighter.xml file.
xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@android:color/holo_orange_dark" android:state_activated="true"/>
<item android:drawable="@android:color/transparent"/>

</selector>

6.    Add android:background="@drawable/row_highlighter" attribute to child.xml of expandableListView.

7.    Source Code:
expandableListView.setOnChildClickListener(new OnChildClickListener() {

public boolean onChildClick(ExpandableListView parent, View v,
                                                int groupPosition, int childPosition, long id) {

int index = parent.getFlatListPosition(ExpandableListView
                   .getPackedPositionForChild(groupPosition, childPosition));
parent.setItemChecked(index, true);
                                     
return false;
}
});

output:


Improvements :-bd

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

If you have any other quick hints that you think people will find useful, feel free to leave a comment.

Friday, September 20, 2013

Android: ExpandableListView using CursorTreeAdapter with in fragment, Content Provider, LoaderCallbacks and CursorLoader



Sample application using Single-pane and Multi-pane Layouts with ExpandableListView using CursorTreeAdapter with in fragment, Content Provider, LoaderCallbacks & CursorLoader.

MULTI-PANE LAYOUTS
On a tablet, you want to take advantage of all the space. Get rid of line lengths that stretch the whole screen. Multi-pane layouts allow you to resolve than. Panes should represent content in an ordered manner; from left-to-right... content becomes more detailed.

Rule is to maintain functional parity in all screen orientations. We have a few strategies to solve this. You can use all or some. You can either: stretch, stack, expand/collapse, or show/ hide different UI panes, depending on the screen orientation. Some figures demonstrate these designs.

Implementation should be done with Fragments. A fragment is "a fragment of an activity". It's a unit that can be reused across activities. It's something smaller than an activity that shares lifecycle patterns, but is focused on a sub-layout that's separated in your codebase.


Ref: AndroidUIs





Figure: Implementing Android UI's for Handset and Tablets
 


On a tablet-sized screen, the Activity A layout contains both Fragment A and Fragment B.
On a handset-sized screen, the Activity A layout contains only Fragment A (the list view). In order to show the details in Fragment B, Activity B must open.

In Expandable List, Child Query is fetched from CursorLoader, We may get doubt, Why we should go for Cursor Loader and what are their adv.?

A CursorLoader automatically re-runs the query when data associated with the query changes. It runs an asynchronous query in the background against a ContentProvider, and returns the results to the Activity or FragmentActivity from which it was called. This allows the Activity or FragmentActivity to continue to interact with the user while the query is ongoing.

Loading Data in the Background

Querying a ContentProvider for data you want to display takes time. If you run the query directly from an Activity, it may get blocked and cause the system to issue an "Application Not Responding" message. Even if it doesn't, users will see an annoying delay in the UI. To avoid these problems, you should initiate a query on a separate thread, wait for it to finish, and then display the results.
You can do this in a straightforward way by using an object that runs a query asynchronously in the background and reconnects to your Activity when it's finished. This object is aCursorLoader. Besides doing the initial background query, aCursorLoader automatically re-runs the query when data associated with the query changes.
This class describes how to use a CursorLoader to run a background query. Examples in this class use the v4 Support Library versions of classes, which support platforms starting with Android 1.6.

Running a Query with a CursorLoader

A CursorLoader runs an asynchronous query in the background against a ContentProvider, and returns the results to the Activity or FragmentActivity from which it was called.

Source Code: Here

Thanks for reading :)
If you have any other quick thoughts/hints that you think people will find useful, feel free to leave a comment.