Reputation: 11608
I have an ExpandableListView
, the count of child groups
can vary since they are dynamically created. I need the first 3 child groups
to be always expanded by default. When the user clicks on a main group
, the rest of the child groups
will be expanded (I attached a figure illustrating the default state of an ExpandableListView
I need to achieve). I haven't found any methods for the ExpandableListView
which would allow to achieve that.
Any suggestions?
Upvotes: 0
Views: 598
Reputation: 44118
I've had a similar idea as @Pr38y but didn't find the time to code it (until now). Still kudos to him/her. This ExpandableList prevents full collapse of a group. It's done by only switching the childCount for each group, based on a boolean (isGroupExpanded
).
Demo myClass:
public class myClass {
int id;
String name;
public myClass(int id, String str) {
this.id = id;
this.name = str;
}
}
Activity (sorry for the humongous HashMap initialization):
package com.example.explvhack;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by Simon on 2014 Jul 8.
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandableListView expList = (ExpandableListView) findViewById(R.id.expList);
// Create the adapter with 3 groups
final List<String> groups = new ArrayList<String>() {{add("Group1"); add("Group2"); add("Group3");}};
final ExpLvAdapter expAdapter = new ExpLvAdapter(getBaseContext(), groups);
// If group is not "expanded" it displays 3 children, else displays all
// This listener, forces it to toggle between fake expanded and collapse states
expList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView dad, View v, int grpPosition, long id) {
expAdapter.isGroupExpanded[grpPosition] = !expAdapter.isGroupExpanded[grpPosition];
expAdapter.notifyDataSetChanged();
return true;
}
});
expList.setAdapter(expAdapter);
// Populate the groups
HashMap<String, List<myClass>> newData =
new HashMap<String, List<myClass>>() {
{
put(groups.get(0), new ArrayList<myClass>() {
{
add(new myClass(0, "Grp1Child1"));
add(new myClass(1, "Grp1Child2"));
add(new myClass(2, "Grp1Child3"));
add(new myClass(3, "Grp1Child4"));
add(new myClass(4, "Grp1Child5"));
add(new myClass(5, "Grp1Child6"));
add(new myClass(6, "Grp1Child7"));
add(new myClass(7, "Grp1Child8"));
}
});
put(groups.get(1), new ArrayList<myClass>() {
{
add(new myClass(0, "Grp2Child1"));
add(new myClass(1, "Grp2Child2"));
add(new myClass(2, "Grp2Child3"));
add(new myClass(3, "Grp2Child4"));
}
});
put(groups.get(2), new ArrayList<myClass>() {
{
add(new myClass(0, "Grp3Child1"));
add(new myClass(1, "Grp3Child2"));
add(new myClass(2, "Grp3Child3"));
}
});
}
};
expAdapter.putAll(newData);
expAdapter.notifyDataSetChanged();
// Keep the groups opened
expList.expandGroup(0);
expList.expandGroup(1);
expList.expandGroup(2);
}
}
And the custom adapter:
package com.example.explvhack;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
/**
* Created by Simon on 2014 Jul 8.
*/
public class ExpLvAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> groups;
private HashMap<String, List<myClass>> children = new HashMap<String, List<myClass>>();
public boolean[] isGroupExpanded = new boolean[] {false, false, false};
public ExpLvAdapter(Context context, final List<String> groups) {
this.context = context;
this.groups = groups;
}
public void putAll(HashMap<String, List<myClass>> newData) {
children.putAll(newData);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = new TextView(context);
// (Re)Use the convertView
TextView textView = (TextView) convertView;
textView.setPadding(60, 0, 30, 0);
textView.setText(children.get(groups.get(groupPosition)).get(childPosition).name);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
int childrenCount = (children.size() == 0) ? 0 : children.get(groups.get(groupPosition)).size();
if (isGroupExpanded[groupPosition])
return childrenCount;
else
return Math.min(3, childrenCount);
}
@Override
public Object getGroup(int groupPosition) {
return groupPosition;
}
@Override
public int getGroupCount() {
return 3;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null)
convertView = new TextView(context);
// (Re)Use the convertView
TextView textView = (TextView) convertView;
textView.setText(groups.get(groupPosition));
return textView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition){
return true;
}
@Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
@Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
}
By the way I also removed the group indicator so there would be no confusion if it's open or not. I used android:groupIndicator="@null"
in my <ExpandableListView .../>
Upvotes: 2
Reputation: 1565
Using normal linearlayout with listview could be a better approach. on click of title in the linearlayout you can fully pouplate the list of the listview adapter and call notifyDataSetChanged
and on next tap you can reduce the list to 3 elements.
Using ExpandableListView
for the first time you can return 3 from getChildCount()
and next time the size of the entire list. You can achieve this effect by either from onGroupExpandListener
or from the adapter
itself.
Upvotes: 1
Reputation: 9625
duplicate your special child items as top-level items, styled to appear like child items. then when a top-level item is expanded for real, set the height of the fake child items to zero.
Upvotes: 2