在保持 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,那么你应该像这样增加heightMeasureSpecheightMeasureSpec = MeasureSpec.makeMeasureSpec(20000, MeasureSpec.AT_MOST);

请注意,我只测试了 3 级可扩展列表视图,您可以在以下问题的回答中阅读更多信息:

How to add Three Level ListView in ExpandableListView in android

我已将我的完整项目发布到GitHub

【讨论】:

以上是关于在保持 N 级或多级可展开列表视图的折叠/展开状态后,某些子组不会显示的主要内容,如果未能解决你的问题,请参考以下文章

Unity实用小工具或脚本——可折叠伸缩的多级(至少三级)内容列表(类似于Unity的Hierarchy视图中的折叠效果)

Flutter折叠展开列表的使用

Flutter折叠展开列表的使用

Flutter折叠展开列表的使用

Material-UI 中的多个展开/折叠 TableRow 组件

游戏开发解答Unity使用lua将table转为树结构,以多级折叠内容列表的UI形式展现(树结构 | UGUI | 折叠展开 | lua)