【问题标题】:Nested ExpandableListView Only Works Every Other Child嵌套的 ExpandableListView 仅适用于其他所有子项
【发布时间】:2015-05-08 16:11:11
【问题描述】:

我有一个嵌套的 ExpandableListViews 系统,它可以持续几代(树型布局)用于 cmets。每个顶级评论都可以在这些 cmets 上有带有子级的 cmets。为此,我有一个主 ExpandableListView 来存储所有顶级 cmets,并且每个“评论”XML 都包含一个可用于任何子 cmets 的 ExpandableListView。我的 ExpandableListView 的适配器如下

public class ExpandableCommentAdapter extends BaseExpandableListAdapter {

    private static final class ViewHolder {
        TextView textLabel;
    }

    private final List<CommentNode> itemList;
    private final LayoutInflater inflater;
    private Context main;

    public ExpandableCommentAdapter(Context context, List<CommentNode> itemList) {
        this.inflater = LayoutInflater.from(context);
        this.itemList = itemList;
        main = context;


    }

    @Override
    public CommentNode getChild(int groupPosition, int childPosition) {

        CommentNode n = itemList.get(groupPosition);
        ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
        for (CommentNode node : n.walkTree(TraversalMethod.BREADTH_FIRST)) {
            if (node.getParent().getComment().getId() == n.getComment().getId()) {
                comments.add(node);
            }

        }
        Log.v("RedditSlide", "COMMENT CHILD SIZE:" + comments.size());
        return comments.get(childPosition);
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        CommentNode n = itemList.get(groupPosition);
        ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
        CommentNode comment = n;
        for (CommentNode node : comment.walkTree(TraversalMethod.BREADTH_FIRST)) {
            if (node.getParent().getComment().getId() == comment.getComment().getId()) {
                comments.add(node);
            }

        }
        return comments.size();
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                             final ViewGroup parent) {

        final CommentNode user = getChild(groupPosition, childPosition);
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment, parent, false);
        }
        TextView author = (TextView) convertView.findViewById(R.id.author);
        TextView comm = (TextView) convertView.findViewById(R.id.commentLine);
        TextView upvote = (TextView) convertView.findViewById(R.id.upvotePost);

        author.setText(user.getComment().getAuthor());
        comm.setText(user.getComment().getBody());
        upvote.setText(user.getComment().getScore() + "");


        ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
        CommentNode comment = user;
        for (CommentNode node : comment.walkTree(TraversalMethod.BREADTH_FIRST)) {
            if (node.getParent().getComment().getId() == comment.getComment().getId()) {
                comments.add(node);
            }

        }

        ExpandableCommentAdapter adapter = new ExpandableCommentAdapter(convertView.getContext(), comments);
        ExpandableListView listView = (ExpandableListView) convertView.findViewById(R.id.commentsListUnder);
        listView.setAdapter(adapter);


        return convertView;
    }

    @Override
    public CommentNode getGroup(int groupPosition) {
        return itemList.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return itemList.size();
    }

    @Override
    public long getGroupId(final int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

        final CommentNode user = itemList.get(groupPosition);
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment, parent, false);
        }
        TextView author = (TextView) convertView.findViewById(R.id.author);
        TextView comm = (TextView) convertView.findViewById(R.id.commentLine);
        TextView upvote = (TextView) convertView.findViewById(R.id.upvotePost);

        author.setText(user.getComment().getAuthor());
        comm.setText(user.getComment().getBody());
        upvote.setText(user.getComment().getScore() + "");

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

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


}

我的评论XML如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="-20dp"
    android:layout_marginRight="-20dp"

    android:background="#ff2b2b2b"
    android:orientation="vertical"
    android:padding="20dp"
    android:paddingBottom="0dp"
    android:paddingEnd="0dp"
    android:scrollbars="none">

    <TextView
        android:id="@+id/author"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ccrama"
        android:textSize="12dp" />

    <TextView
        android:id="@+id/commentLine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="COMMENT"
        android:textSize="14dp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="-10dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/upvote"
            android:layout_width="20dp"
            android:layout_height="20dp"

            android:layout_gravity="center_vertical"
            android:layout_margin="10dp"
            android:background="@drawable/roundbutton"
            android:onClick="upvote"
            android:padding="5dp"

            android:scaleType="fitCenter"
            android:src="@drawable/iconupvote"

            />

        <ImageView
            android:id="@+id/downvote"
            android:layout_width="20dp"

            android:layout_height="20dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="-7dp"
            android:background="@drawable/roundbutton"

            android:onClick="downvote"

            android:padding="5dp"
            android:scaleType="fitCenter"
            android:src="@drawable/icondownvote"

            />

        <TextView
            android:id="@+id/upvotePost"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"

            android:layout_marginLeft="7dp"
            android:text="30"
            android:textSize="14dp" />

    </LinearLayout>

    <ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/commentsListUnder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="-20dp"
        android:layout_marginLeft="-5dp"
        android:layout_marginRight="-20dp"
        android:background="#ff2b2b2b"
        android:orientation="vertical" />
</LinearLayout>

我遇到的问题是子 cmets 的“可扩展性”似乎跳过了一代。 Level 1, Level 3 等都有展开,他们的孩子可见,但是Level 2 不能展开,只有一个孩子可见。其他孩子(4、5、6...)不可见,第 3 级有一个展开图标,但点击时不显示任何孩子。

我的布局/系统有什么问题? 谢谢!

【问题讨论】:

标签: android expandablelistview


【解决方案1】:

你的问题是两件事。您正在尝试嵌套沿相同方向滚动的可滚动视图。 Android 无法正确处理这种情况,你会得到各种疯狂的行为。试图“破解”这些问题只会让人头疼。

第二个问题是您将适配器嵌入到适配器中。虽然这“可能”工作,但确实不推荐。无法保证为相同的位置编号调用 getChildViewgetParentView 多少次。有时是一次。有时是两次。哎呀,可能是4次。每次您要重新创建一个新适配器时,该适配器又会在每个位置多次调用它的 getChildViewgetParentView 方法。简而言之,这是一个主要的性能问题。

您最好的解决方案是重新设计不需要嵌入 ExpandableListViews 和适配器的 UX 设计。

【讨论】:

  • 是的,我发现我的方法存在问题。在我的情况下你会怎么做?
  • 很难。如果您抛开扩展能力部分,那么您可以使用普通列表视图一次渲染所有内容。或者只允许一个级别的折叠,并将所有子 cmets 显示为子项的一部分。否则,如果您想显示子 cmets 的扩展和折叠,您需要采取一些技巧。因此,选择子项实际上会在子 cmets 中加载为新数据……就好像您扩展了子视图一样。然后,您需要跟踪子项是否是具有更多子项的评论,以便使用此技巧。希望这是有道理的。
  • 是的,我明白你的意思。我正在考虑可能一次加载每条评论,然后在左侧添加一个边距以缩进它所在的每个级别(级别 2 20dp、级别 3 30dp 等)。该方法的唯一问题是扩展能力,这可能更难实现。不过,为此,我可能会创建一种方法来获取子 cmets 的 id(每个评论都有一个特定的 id)并从 ListView 中隐藏该 ID 的 cmets,我最终可能会这样做。只要用户看到它们是嵌套的,我就可以接受它们确实不是嵌套的事实。
猜你喜欢
  • 1970-01-01
  • 2010-11-30
  • 2014-08-30
  • 2023-03-16
  • 2013-08-08
  • 1970-01-01
  • 2016-05-12
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多