不同组的不同子布局 ExpandableListView

2023-11-24

我在尝试执行此操作时遇到了问题。我似乎无法做到这一点,我想控制每个父母+该父母的孩子。 ExpandableListView一直让我头疼。 包评论;

public class CommentsExpandableListAdapter extends BaseExpandableListAdapter {

private Activity context;
private Map<String, List<String>> comments_feed_collection;
private List<String> group_list;



private boolean a_comment = false;
public CommentsExpandableListAdapter(Activity context, List<String> group_list,
                             Map<String, List<String>> comments_feed_collection) {
    this.context = context;
    this.comments_feed_collection = comments_feed_collection;
    this.group_list = group_list;
}


public Object getChild(int groupPosition, int childPosition) {
    return comments_feed_collection.get(group_list.get(groupPosition)).get(childPosition);
}

public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

public View getChildView(final int groupPosition, final int childPosition,
                         boolean isLastChild, View convertView, ViewGroup parent) {
    final String incoming_text = (String) getChild(groupPosition, childPosition);
    LayoutInflater inflater = context.getLayoutInflater();


    if (convertView == null) {
        //first view
        if(childPosition==0 && groupPosition==0) {
            convertView = inflater.inflate(R.layout.description_of_ads_expandable_list, null);
            TextView description_child = (TextView) convertView.findViewById(R.id.description_of_ads_expandable_list_child_text_view);
            description_child.setText(incoming_text);
        }else if(childPosition==0 && groupPosition==1){
            //second view view
            convertView = inflater.inflate(R.layout.comments_create_comment, null);
        }else if(childPosition>=1 && groupPosition>=1){
            //thrid view
            convertView = inflater.inflate(R.layout.comments_expandable_list_child, null);
        }
    }
    return convertView;
}

public int getChildrenCount(int groupPosition) {
    return comments_feed_collection.get(group_list.get(groupPosition)).size();
}

public Object getGroup(int groupPosition) {
    return group_list.get(groupPosition);
}
public int getGroupCount() {
    return group_list.size();
}

public long getGroupId(int groupPosition) {
    return groupPosition;
}


public View getGroupView(int groupPosition, boolean isExpanded,
                         View convertView, ViewGroup parent) {
    String incoming_text = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.expandable_list_single_item,
                null);
    }
    TextView item = (TextView) convertView.findViewById(R.id.expandable_list_single_item_text_view_group);
    item.setTypeface(null, Typeface.BOLD);
    item.setText(incoming_text);
    return convertView;
}


public boolean hasStableIds() {
    return true;
}


public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}


@Override
public int getChildTypeCount() {
    return 3;
}

@Override
public int getGroupType(int groupPosition) {
    return super.getGroupType(groupPosition);
}

@Override
public int getGroupTypeCount() {
    return 3;
}
}

我认为你的主要错误在于public View getChildView(...) :

  • 条件if (convertView == null)实际上只到达一次,那就是当您加载标记为第一个视图的那个时。所以你正在夸大第一个布局R.layout.description_of_ads_expandable_list并将其重复用于列表中的所有其他行。
  • 检查要加载的子视图类型的方式是危险的,因为它是不完整的。如果你认为会发生什么childPosition==1 && groupPosition==0?繁荣!如果您的数据源在第一组中还有一个元素,则出现 NullPointerException。

所以首先要做的事情;你应该全面实施异构可扩展列表接口如果您想对 ExpandableListView 的不同组/子项使用不同的布局。

然后使用该接口来确定应加载布局的条件。

最后解决重用视图问题public View getChildView(...).

由于我是一个好人,这里的一个片段应该可以帮助您(基于您发布的适配器):

public class CommentsExpandableListAdapter extends BaseExpandableListAdapter {

    // 4 Child types
    private static final int CHILD_TYPE_1 = 0;
    private static final int CHILD_TYPE_2 = 1;
    private static final int CHILD_TYPE_3 = 2;
    private static final int CHILD_TYPE_UNDEFINED = 3;

    // 3 Group types
    private static final int GROUP_TYPE_1 = 0;
    private static final int GROUP_TYPE_2 = 1;
    private static final int  GROUP_TYPE_3 = 2;

    private Activity context;
    private Map<String, List<String>> comments_feed_collection;
    private List<String> group_list;

    public CommentsExpandableListAdapter(Activity context, List<String> group_list,
                                         Map<String, List<String>> comments_feed_collection) {
        this.context = context;
        this.comments_feed_collection = comments_feed_collection;
        this.group_list = group_list;
    }

    public Object getChild(int groupPosition, int childPosition) {
        return comments_feed_collection.get(group_list.get(groupPosition)).get(childPosition);
    }

    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final String incoming_text = (String) getChild(groupPosition, childPosition);
        LayoutInflater inflater = context.getLayoutInflater();

        int childType = getChildType(groupPosition, childPosition);

        // We need to create a new "cell container"
        if (convertView == null || convertView.getTag() != childType) {
            switch (childType) {
                case CHILD_TYPE_1:
                    convertView = inflater.inflate(R.layout.description_of_ads_expandable_list, null);
                    convertView.setTag(childType);
                    break;
                case CHILD_TYPE_2:
                    convertView = inflater.inflate(R.layout.comments_create_comment, null);
                    convertView.setTag(childType);
                    break;
                case CHILD_TYPE_3:
                    convertView = inflater.inflate(R.layout.comments_expandable_list_child, null);
                    convertView.setTag(childType);
                    break;
                case CHILD_TYPE_UNDEFINED:
                    convertView = inflater.inflate(R.layout.comments_undefined, null);
                    convertView.setTag(childType);
                    break;
                default:
                    // Maybe we should implement a default behaviour but it should be ok we know there are 4 child types right?
                    break;
            }
        }
        // We'll reuse the existing one
        else {
            // There is nothing to do here really we just need to set the content of view which we do in both cases
        }

        switch (childType) {
            case CHILD_TYPE_1:
                TextView description_child = (TextView) convertView.findViewById(R.id.description_of_ads_expandable_list_child_text_view);
                description_child.setText(incoming_text);
                break;
            case CHILD_TYPE_2:
                //Define how to render the data on the CHILD_TYPE_2 layout
                break;
            case CHILD_TYPE_3:
                //Define how to render the data on the CHILD_TYPE_3 layout
                break;
            case CHILD_TYPE_UNDEFINED:
                //Define how to render the data on the CHILD_TYPE_UNDEFINED layout
                break;
        }

        return convertView;
    }

    public int getChildrenCount(int groupPosition) {
        String groupName = group_list.get(groupPosition);
        List<String> groupContent = comments_feed_collection.get(groupName);
        return groupContent.size();
    }

    public Object getGroup(int groupPosition) {
        return group_list.get(groupPosition);
    }
    public int getGroupCount() {
        return group_list.size();
    }

    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        final String incoming_text = (String) getGroup(groupPosition);

        int groupType = getGroupType(groupPosition);

        // We need to create a new "cell container"
        if (convertView == null || convertView.getTag() != groupType) {
            switch (groupType) {
                case GROUP_TYPE_1 :
                    convertView = inflater.inflate(R.layout.expandable_list_single_item, null);
                    break;
                case GROUP_TYPE_2:
                    // Am using the same layout cause am lasy and don't wanna create other ones but theses should be different
                    // or the group type shouldnt exist
                    convertView = inflater.inflate(R.layout.expandable_list_single_item, null);
                    break;
                case GROUP_TYPE_3:
                    // Am using the same layout cause am lasy and don't wanna create other ones but theses should be different
                    // or the group type shouldnt exist
                    convertView = inflater.inflate(R.layout.expandable_list_single_item, null);
                    break;
                default:
                    // Maybe we should implement a default behaviour but it should be ok we know there are 3 group types right?
                    break;
            }
        }
        // We'll reuse the existing one
        else {
            // There is nothing to do here really we just need to set the content of view which we do in both cases
        }

        switch (groupType) {
            case GROUP_TYPE_1 :
                TextView item = (TextView) convertView.findViewById(R.id.expandable_list_single_item_text_view_group);
                item.setTypeface(null, Typeface.BOLD);
                item.setText(incoming_text);
                break;
            case GROUP_TYPE_2:
                //TODO: Define how to render the data on the GROUPE_TYPE_2 layout
                // Since i use the same layout as GROUPE_TYPE_1 i could do the same thing as above but i choose to do nothing
                break;
            case GROUP_TYPE_3:
                //TODO: Define how to render the data on the GROUPE_TYPE_3 layout
                // Since i use the same layout as GROUPE_TYPE_1 i could do the same thing as above but i choose to do nothing
                break;
            default:
                // Maybe we should implement a default behaviour but it should be ok we know there are 3 group types right?
                break;
        }

        return convertView;
    }


    public boolean hasStableIds() {
        return true;
    }


    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }


    @Override
    public int getChildTypeCount() {
        return 4; // I defined 4 child types (CHILD_TYPE_1, CHILD_TYPE_2, CHILD_TYPE_3, CHILD_TYPE_UNDEFINED)
    }

    @Override
    public int getGroupTypeCount() {
        return 3; // I defined 3 groups types (GROUP_TYPE_1, GROUP_TYPE_2, GROUP_TYPE_3)
    }

    @Override
    public int getGroupType(int groupPosition) {
        switch (groupPosition) {
            case 0:
                return GROUP_TYPE_1;
            case 1:
                return GROUP_TYPE_1;
            case 2:
                return GROUP_TYPE_2;
            default:
                return GROUP_TYPE_3;
        }
    }

    @Override
    public int getChildType(int groupPosition, int childPosition) {
        switch (groupPosition) {
            case 0:
                switch (childPosition) {
                    case 0:
                        return CHILD_TYPE_1;
                    case 1:
                        return CHILD_TYPE_UNDEFINED;
                    case 2:
                        return CHILD_TYPE_UNDEFINED;
                }
                break;
            case 1:
                switch (childPosition) {
                    case 0:
                        return CHILD_TYPE_2;
                    case 1:
                        return CHILD_TYPE_3;
                    case 2:
                        return CHILD_TYPE_3;
                }
                break;
            default:
                return CHILD_TYPE_UNDEFINED;
        }

        return CHILD_TYPE_UNDEFINED;
    }
}

它是这样的:

CommentsExpandableListAdapter implementation result

希望这有帮助,如果有/没有,请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不同组的不同子布局 ExpandableListView 的相关文章

随机推荐

  • Java ObjectInputStream 挂起

    我现在感觉真的很愚蠢 伙计们 基本上我是通过本地计算机上的 TCP 连接的 当我尝试在客户端创建输入 输出流时 它不会通过创建对象输入流 是什么赋予了 这在打印 2 后停止 没有异常或任何东西 这不是我第一次使用这个类 这部分是我感到困惑的
  • XSLT 将同名兄弟节点的值合并/连接到单个节点

    输入XML
  • 实体管理器是否创建与数据库的连接?

    在我的项目中 我忘记关闭每个操作的实体管理器 一段时间后 由于与 mysql 服务器的连接过多 我遇到了异常 这是否意味着每个实体管理器都建立连接 当我们忘记关闭连接时会发生什么 我只使用了一个实体管理器工厂 假设您正在使用应用程序管理的实
  • 根据“grid_location”方法,按钮有自己的坐标系吗?

    我正在尝试使用grid location方法 从网格几何管理器 在 Tkinter 中 但似乎我做错了什么 这是我的代码 from tkinter import root Tk b Button root text 00 b grid ro
  • 如何确保我的 git 存储库代码是安全的?

    如果我们的组织要从像 subversion 这样的中央服务器 VCS 切换到像 git 这样的分布式 VCS 我如何确保我的所有代码都不会出现硬件故障 使用中央服务器 VCS 我只需要每天备份存储库 如果我们使用 DVCS 那么所有开发人员
  • iOS 7 自定义后退按钮

    我想使用自定义后退按钮 在 iOS 6 中 一切都很完美 但是iOS 7很奇怪 UIBarButtonItem appearance setBackButtonBackgroundImage UIImage imageNamed back
  • org.openqa.selenium.InvalidCookieDomainException:使用 Selenium 和 WebDriver 文档不支持 cookie

    我正在尝试将 cookie 推送到从上一个会话存储的 selenium firefox webdriver 但出现错误 org openqa selenium InvalidCookieDomainException Document is
  • UIPanGestureRecognizer 起点已关闭

    我有一个 UIView 它附加了一个 UIPanGestureRecognizer 手势工作正常 只是起点不是平移第一次开始的位置 它通常在 x 和 y 坐标中偏离 5 到 15 个像素 不幸的是 方差不是一致并且似乎与平移运动发生的速度有
  • 使用 php 向后读取文件行(fgets)

    我有一个txt文件 我想向后阅读 目前我正在使用这个 fh fopen myfile txt r while line fgets fh echo line br 这将输出我文件中的所有行 我想从下到上阅读这些行 有办法做到吗 第一种方式
  • C# 服务:如何获取用户配置文件文件夹路径

    我需要从 C windows 服务中获取用户目录 比如 C Users myusername 理想情况下 我希望有漫游路径 就像 C Users myusername AppData Roaming 当我在控制台程序中使用以下内容时 我得到
  • 匹配结束 HTML 标签的正则表达式

    我正在编写一个小型 Python 脚本来清理 HTML 文档 它的工作原理是接受要保留的标签列表 然后解析 HTML 代码 丢弃不在列表中的标签我一直在使用正则表达式来做到这一点 并且我已经能够匹配开始标签和自关闭标签但不关闭标签 我一直在
  • 如何自动生成日期属性为 Date 而不是 NSDate 的 NSManagedObject 子类?

    我目前正在将我的项目更新到 Swift 3 并将所有 NSDate 方法和扩展移至 Date 以便在应用程序中保持标准 问题是我使用 Xcode 自动生成 NSManagedObject 子类 并且它生成日期属性为 NSDate 而不是 D
  • Spring:如何在运行时更改接口实现

    作为一名 Java 开发人员 我经常需要在接口的不同实现之间进行选择 有时这种选择是可以做到的once 而有时我需要不同的实现来响应我的程序收到的不同输入 换句话说 我需要能够change运行时执行 这可以通过帮助程序对象轻松实现 该对象将
  • 根据行数据更新 DatagridView 单元格背景颜色

    您好 我有一个 DatagridView 我希望它根据每行中的数据更改背景颜色 Ex 人 1 人 2 人 3 100 200 150 300 100 50 在第一行中 我希望它使 100 具有红色背景颜色和 200 绿色 或者 最低值 红色
  • Python 中连接字符串的最有效方法

    在问这个问题时 我正在使用Python 3 8 当我说高效时 我只是指字符串连接的速度 或者用更专业的术语来说 我问的是时间复杂度 而不是考虑空间复杂度 目前我能想到的唯一方法是以下 3 种 a start b end Method 1 r
  • 如何从 .cab 文件安装 mscomct2.ocx 文件(Excel 用户表单和 VBA)

    我有一个 Excel 电子表格 其中包含使用日历控件的用户表单 它在我的机器上运行良好 但其他人无法使用它 因为他们缺少 mscomct2 ocx 文件 我找到了下载地址 http support microsoft com kb 2973
  • Angular2将数据映射为特定对象类型

    我根据 Angular2 教程创建了一个非常简单的应用程序 首先 我有一个非常简单的 Book 模型 book model export class Book public data constructor param id param t
  • 沿二维图像切片进行插值

    我有一套100相同大小的二维图像切片 我使用 MATLAB 将它们堆叠起来以创建体积数据 虽然二维切片的大小为 480x488 像素 但图像堆叠的方向不够宽 无法在投影时以不同方向可视化体积 我需要沿着切片进行插值以增加可视化的大小 有人可
  • Pandas 将具有 unix 时间戳(以毫秒为单位)的行转换为日期时间

    我需要处理大量 CSV 文件 其中时间戳始终是表示 UNIX 时间戳 以毫秒为单位 的字符串 我还找不到有效修改这些列的方法 这是我想到的 但是这当然只复制了列 我必须以某种方式将它放回原始数据集 我确信在创建时可以完成DataFrame
  • 不同组的不同子布局 ExpandableListView

    我在尝试执行此操作时遇到了问题 我似乎无法做到这一点 我想控制每个父母 该父母的孩子 ExpandableListView一直让我头疼 包评论 public class CommentsExpandableListAdapter exten