在保持 N 级或多级可展开列表视图的折叠/展开状态后,某些子组不会显示
Posted
技术标签:
【中文标题】在保持 N 级或多级可展开列表视图的折叠/展开状态后,某些子组不会显示【英文标题】:After maintaining collapse/expand state for N-level or Multilevel expandablelistview some subgroups are not displayed 【发布时间】:2015-12-19 06:09:04 【问题描述】:我做了很多工作来创建 **N 级可扩展列表视图。我可以达到任何级别,但我的要求是即使在滚动后也能保持打开的组的状态。我尝试了多种方法,但仍然不成功。
此可扩展列表视图满足除此问题之外的所有公司要求。
*这是我尝试过的一种方法。我能够保存对象中的状态,但很少有子组没有显示。 *
我尝试使用 onMeasure(width,height) 方法在动态生成列表时保持高度,但仍然未能获得完美的列表。
我也浏览了许多相同的文章。
我的工作应用程序的附加屏幕截图..
这是我的代码。
public class ParentLevelAdapter extends BaseExpandableListAdapter
private Context context;
private View convertView;
Account account;
private ArrayList<Model_Departments> list_departments;
public ParentLevelAdapter (Context context,
ArrayList<Model_Departments> list_departments, Account account)
this.context = context;
this.list_departments = list_departments;
this.account = account;
public void updateList(Context context,
ArrayList<Model_Departments> list_departments, Account account)
notifyDataSetChanged();
@Override
public Object getChild(int arg0, int arg1)
return this.getChild(arg0, arg1);
@Override
public long getChildId(int groupPosition, int childPosition)
return childPosition;
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
final SecondLevelExpandableListView subGroupListView;
SecondListView employeeLisView = null;
if (convertView == null)
if (list_departments.get(groupPosition).hasSubGroups())
subGroupListView = new SecondLevelExpandableListView(
context);
subGroupListView.setGroupIndicator(null);
adap = new ParentLevelAdapter (context,
list_departments.get(groupPosition).subgroups,
account);
subGroupListView.setAdapter(adap);
return subGroupListView;
else
employeeLisView = new SecondListView(context);
employeeLisView.setAdapter(new EmployeeAdapter(context,
list_departments.get
(groupPosition).employee, account));
return employeeLisView;
else
if (list_departments.get(groupPosition).hasSubGroups())
if (convertView instanceof SecondLevelExpandableListView)
subGroupListView = (SecondLevelExpandableListView) convertView;
subGroupListView.onMeasure(10000, 999999);
subGroupListView.setGroupIndicator(null);
adap = new ParentLevelAdapter (context,
list_departments.get(groupPosition).subgroups,
account);
subGroupListView.setAdapter(adap);
return subGroupListView;
else
subGroupListView = new SecondLevelExpandableListView(
context);
subGroupListView.setGroupIndicator(null);
adap = new ParentLevelAdapter (context,
list_departments.get(groupPosition).subgroups,
account);
subGroupListView.setAdapter(adap);
return subGroupListView;
else
if (convertView instanceof SecondListView)
employeeLisView = (SecondListView) convertView;
employeeLisView.setAdapter(new EmployeeAdapter(context,
list_departments.get(groupPosition).employee,
account));
return employeeLisView;
else
employeeLisView = new SecondListView(context);
employeeLisView.setAdapter(new EmployeeAdapter(context,
list_departments.get(groupPosition).employee,
account));
return employeeLisView;
@Override
public int getChildrenCount(int groupPosition)
// return list_departments.get(groupPosition).subgroups.size();
return 1;
@Override
public Object getGroup(int groupPosition)
return list_departments.get(groupPosition);
@Override
public int getGroupCount()
return list_departments.size();
@Override
public long getGroupId(int groupPosition)
return groupPosition;
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertV, ViewGroup parent)
convertView = convertV;
// Log.v("ParentAdapter GroupView ",list_departments.get(groupPosition).name);
if (convertView == null)
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.layout_icon_node, null);
TextView text = (TextView) convertView
.findViewById(R.id.node_value);
// text.setText("SECOND LEVEL");
text.setText(list_departments.get(groupPosition).name);
else
TextView text = (TextView) convertView
.findViewById(R.id.node_value);
text.setText(list_departments.get(groupPosition).name);
if (list_departments.get(groupPosition).isExpanded())
Log.i("Group Position=", groupPosition + " NAme="
+ list_departments.get(groupPosition).name);
((SecondLevelExpandableListView) parent)
.expandGroup(groupPosition);
/* code to save state for Group expand and collapse for individual objects*/
((SecondLevelExpandableListView) parent)
.setOnGroupExpandListener(new OnGroupExpandListener()
@Override
public void onGroupExpand(int groupPosition)
// TODO Auto-generated method stub
list_departments.get(groupPosition).setExpanded(
true);
Log.i("Group", "Expand groupposition="
+ groupPosition);
Log.i("Group",
"Expand"
+ list_departments
.get(groupPosition).name);
);
((SecondLevelExpandableListView) parent)
.setOnGroupCollapseListener(new OnGroupCollapseListener()
@Override
public void onGroupCollapse(int groupPosition)
// TODO Auto-generated method stub
list_departments.get(groupPosition).setExpanded(
false);
Log.i("Group", "Collapse groupposition="
+ groupPosition);
Log.i("Group",
"Collapse"
+ list_departments
.get(groupPosition).name);
);
return convertView;
@Override
public boolean hasStableIds()
return true;
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
return true;
我的 Pojo_Object:
public class Model_Departments implements Comparable<Model_Departments>
public String name;
protected long parent_id;
private boolean isexpanded;
public boolean isExpanded()
return isexpanded;
public void setExpanded(boolean isexpanded)
this.isexpanded = isexpanded;
public ArrayList<Model_Departments> subgroups = new ArrayList<>();
public ArrayList<Model_Employees> employee = new ArrayList<>();
public Model_Departments(String department_name, long parent_id)
this.name = department_name;
this.parent_id = parent_id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public long getParent_id()
return parent_id;
public void setParent_id(long parent_id)
this.parent_id = parent_id;
public ArrayList<Model_Departments> getSubgroups()
return subgroups;
public void setSubgroups(ArrayList<Model_Departments> subgroups)
this.subgroups = subgroups;
public ArrayList<Model_Employees> getEmployee()
return employee;
public void setEmployee(ArrayList<Model_Employees> employee)
this.employee = employee;
public boolean hasEmployees()
if (employee != null && employee.size() > 0)
return true;
else
return false;
public boolean hasSubGroups()
if (subgroups != null && subgroups.size() > 0)
return true;
else
return false;
@Override
public int compareTo(Model_Departments another)
if(this.hasSubGroups())
Collections.sort(this.subgroups);
return this.getName().compareTo(another.getName());
Model_Employee.java
public class Model_Employees implements Comparable<Model_Employees>
public String name;
public Model_Employees(String name, String location)
super();
this.name = name;
public Model_Employees()
// TODO Auto-generated constructor stub
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public int compareTo(Model_Employees another)
return this.getName().compareTo(another.getName());
提前致谢。
【问题讨论】:
各位请帮我们解决这个问题很长时间 我使用 isexpanded 变量来保存任何级别的每个组的状态。最初它是错误的,ongroupexpand listener 我正在使它成为 true,而 oncollapselistener 我正在使它成为 false。它正在工作,但是在 scrool 期间加载时它隐藏了一些组。单击另一个子组后,它会显示出来。 也许使用 TreeView 库会更好 - github.com/bmelnychuk/androidTreeView 感谢 Alexandra,我已经尝试过使用该库。由于这不是列表视图驱动的,因此在列表中进行了一些修改后,我无法使用 notifydatasetchanged。 【参考方案1】:我之前在使用 N 级可扩展列表视图时也遇到过同样的问题,我使用了一种只显示一个扩展项的技巧。虽然它看起来不是最适合您的解决方案,但希望对您有所帮助!
// display only one expand item
mExpandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener()
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition)
if (groupPosition != previousGroup)
mExpandableListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
);
secondLevelExpListView
也一样
更新:
您可以尝试以下另一种方式(连同上面的setOnGroupExpandListener
):
public class CustomExpListView extends ExpandableListView
public CustomExpListView(Context context)
super(context);
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(2000, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
然后在你的ParentLevelAdapter
中调用这个:
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
final CustomExpListView secondLevelExpListView = new CustomExpListView(this.mContext);
String parentNode = (String) getGroup(groupPosition);
secondLevelExpListView.setAdapter(new SecondLevelAdapter(this.mContext, mListData_SecondLevel_Map.get(parentNode), mListData_ThirdLevel_Map));
secondLevelExpListView.setGroupIndicator(null);
secondLevelExpListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener()
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition)
if (groupPosition != previousGroup)
secondLevelExpListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
);
return secondLevelExpListView;
如果你不想使用setOnGroupExpandListener
,那么你应该像这样增加heightMeasureSpec
heightMeasureSpec = MeasureSpec.makeMeasureSpec(20000, MeasureSpec.AT_MOST);
请注意,我只测试了 3 级可扩展列表视图,您可以在以下问题的回答中阅读更多信息:
How to add Three Level ListView in ExpandableListView in android
我已将我的完整项目发布到GitHub
【讨论】:
以上是关于在保持 N 级或多级可展开列表视图的折叠/展开状态后,某些子组不会显示的主要内容,如果未能解决你的问题,请参考以下文章
Unity实用小工具或脚本——可折叠伸缩的多级(至少三级)内容列表(类似于Unity的Hierarchy视图中的折叠效果)
Material-UI 中的多个展开/折叠 TableRow 组件
游戏开发解答Unity使用lua将table转为树结构,以多级折叠内容列表的UI形式展现(树结构 | UGUI | 折叠展开 | lua)