I am new to android, and I want to implement a ListView like the image below. It seems expandableListView may meet my request, but what I want is only Item 4 has children and can be expanded, 'Item 1' is just an option user can click, and can't be expanded. I read the document of Expandable List View, and it's not clear enough how to implement this. Can anyone gave some suggestion on implementing this? Thank you so much
but what I want is only Item 4 has children and can be expanded
If Item doesn't have children, it won't be exanded. You can image that like:
public class Item {
private String title;
private List<Option> children; // if size = 0 won't be expanded
}
It's native behaviour of ExpandableListView so if any Item doesn't have children, implicitly won't be expanded but you need to set OnClickListener for both groups (Items) and children (Options):
public boolean onChildClick(ExpandableListView parent, View row,
int groupPosition, int childPosition, long id) {
// callback method after click for Options
return false;
}
public boolean onGroupClick(ExpandableListView parent, View row,
int groupPosition, long id) {
/** if you are using BaseAdapter subclass implementation **/
adapter.getGroup(groupPosition)).getChildren() == null) {
// item doesn't have children
}
else {
// has children
}
Generally if you want to get more control over your ListView i pretty recommend you to implement own subclass of ListAdapter in your case you can use BaseExpandableListAdapter.
And an appearance of List is only issue about proper styled layouts for example removing group indicator with
android:groupIndicator="#null"
Update:
Issue mentioned by #Roberto Lombardini:
A little problem with this solution is that the little grey triangle
indicating the state of the groupview (expanded or not) will appear
even if group has no children. Am i wrong?
If you want to have gray triangle only for Items with children, you need to fix it in your custom adapter in getGroupView() method:
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// inflating View etc.
Item item = items.get(groupPosition);
if (item != null) {
// if Item has children
if (item.getChildren() != null && !item.getChildren().isEmpty()) {
// set children indicator to VISIBLE
imageView.setVisibility(ImageView.VISIBLE);
}
// if Item doesn't have children
else {
// set children indicator to GONE
imageView.setVisibility(ImageView.GONE);
}
}
}
Try to implement some custom Adapter, I think could be the better way to do what you need
lv.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int position, long id) {
switch (position) {
case 0: return true;
case 2: return true; // returning true wont expand
default:
return false;// if you return false then only that position will be expanded
}
}
}
);
just return false on the which parent position you want to expand and in which you dont want to expand you can return true.
Related
I am using Custom ExpandableListview for first time. I have custom expandable listview which contains 10 groups in which some groups have child and some groups don't have child.
I want child when the child item is clicked. (in case of groups having child)
I want group when the group item is clicked. (in case of groups don't have child)
I am getting child by using OnChildClickListener(first case) , but I didn't getting group. (second case)
Is there any way to get both at a time. If group have child then return clicked child otherwise return clicked group.
Please help me
First set OnChildClickListener to list
Next set OnGroupExpandListener to list
exList.setOnChildClickListener(this);
exList.setOnGroupExpandListener(this);
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Group gr = ds_list.get(groupPosition);
//here you can get child from group
return true;
}
#Override
public void onGroupExpand(int i) {
if(group don't have child) {
//get group by using group position(i)
}
}
You can add OnGroupCollapseListener also
Don't use OnChildClickListener and OnGroupExpandListener together because group items are not expandable behaves like a normal ListView
You can use this method to get the index of parent view, and check whether the parent in that position contains a child or not.
expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
//here you can check whether your parent contains a child or not by getting the parent position.
return false;
}
});
I am beginner to android I need some Help about List and Extended List in one Drawer
I know that this question is posted here several Time but I am unable to understand that Actually I want to make a list like:
Please Help me Step by Step
thak you!...
It's native behavior of ExpandableListView so if any Item doesn't have children, implicitly won't be expanded but you need to set OnClickListener for both groups (Items) and children (Options):
public boolean onChildClick(ExpandableListView parent, View row,
int groupPosition, int childPosition, long id) {
// callback method after click for Options
return false;
}
public boolean onGroupClick(ExpandableListView parent, View row,
int groupPosition, long id) {
/** if you are using BaseAdapter subclass implementation **/
if(adapter.getGroup(groupPosition).getChildren() == null) {
// item doesn't have children
return true;
}
else {
// has children
return false;
}
}
I'm looking for an API like isExpanded() or isCollapsed() that tells me if a group is expanded or collapsed.
You can use isGroupExpanded .
expListViewObj.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
if(parent.isGroupExpanded(groupPosition))
{
// Do your Staff
}
else{
// Expanded ,Do your Staff
}
return false;
}
});
For more details you can visit Here
http://developer.android.com/reference/android/widget/ExpandableListView.html#setOnGroupClickListener(android.widget.ExpandableListView.OnGroupClickListener)
As #George D wrote there is ExpandableListView .isGroupExpanded(int groupPosition) method. Well you could add the code to get expanded group position or -1
public int getExpandedGroupPosition() {
for (int i = 0; i < listView.getExpandableListAdapter().getGroupCount(); i++) {
if ( listView.isGroupExpanded(i) ) {
return i;
}
}
return -1;
}
If u use BaseExpandableListAdapter class you have getGroupView() override method.
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
// Here is your expand list view parent id
// b specify that parent expand or not.
.............
if(b){
imdDownArrow.setVisibility(View.GONE);
imdUpArrow.setVisibility(View.VISIBLE);
}else{
imdDownArrow.setVisibility(View.VISIBLE);
imdUpArrow.setVisibility(View.GONE);
}
...............
return view;
}
so using this simple code you can show arrow up or down
There is a parameter in getGroupView() on your ExpandableListAdapter, a boolean that represents wheter the group is expanded or not.
From (http://developer.android.com/reference/android/widget/ExpandableListAdapter.html#getGroupView(int, boolean, android.view.View, android.view.ViewGroup)
Gets a View that displays the given group. This View is only for the group--the Views for the group's children will be fetched using getChildView(int, int, boolean, View, ViewGroup)).
Parameters
groupPosition the position of the group for which the View is returned
isExpanded whether the group is expanded or collapsed
convertView the old view to reuse, if possible. You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. It is not guaranteed that the convertView will have been previously created by getGroupView(int, boolean, View, ViewGroup).
parent the parent that this view will eventually be attached to
I want to create a ListView with a header view that can be expanded and retractet just as in a ExpandableListView (but just the header view, all other views just be normal list items).
I'm using an ExpandableListView with a BaseExpandableListAdapter and treat all the other items in the list as groups that have no children.
This is cumbersome and error-prone and has unwanted sideeffects.
I also tried using a normal ListView and a view for the header where I setVisivility(View.VISIBLE) to the expanded part of the view when the header view is clicked, but this doesn't seem to have any effect:
private View getHeaderView() {
final View v = layoutInflater.inflate(R.layout.headertest, null);
View v1 = v.findViewById(R.id.view1);
final View v2 = v.findViewById(R.id.view2);
v1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("head", "click");
v2.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
return v;
}
When v1 is clicked, the visibility of v2 is not changed, although the clickListener is called. I also tried .invalidate() on all kinds of views, to no avail.
Any ideas on how to solve this one or the other way?
You can do it with the expandable list view. First disable the indicators (open/close icons) on your ListView:
mExpList.setIndicator(null);
Next, your header (first group) will have to be a special type of group which has an image (an indicator) in its layout. Basically you want to have 2 types of group views:
#Override
public int getGroupTypeCount() {
return 2;
}
#Override
public int getGroupType(int groupPosition) {
if (groupPosition == headerPosition) {
return 1;
} else {
return 0;
}
}
You will also need to Override onGroupExpanded and onGroupCollapsed to change the image of your header (if a header was clicked of course).
Lastly you'll need to override the ListView's OnGroupClickListener:
mExpList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if (groupPosition == header) {
// Click was not handled
return false;
} else {
// Do some normal stuff with items
// Click was handled group won't be (or tried to be) expanded
return true;
}
}
});
Also a good idea would be to override adapters getChildCount to return 0 when it's not a header.
Hope this helps. Good luck!
I want to make an ExpandableListView which should always be showing its children elements
even after clicking the header, and it should not collapse. How could I implement this concept?
you can expand all groups one by one as below as mentioned in this post
ExpandableListView explst;
explst.expandGroup(0);
explst.expandGroup(1);
for disabling collapse you can define a OnGroupClickListener which returns true, like so: (as mentioned in this post)
explst.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return true; // This way the expander cannot be collapsed
}
});