如何将一个列表嵌套的列表映射到RecyclerView?

9

我正在尝试在Android中将一个List<List<Object>>映射到RecyclerView上,但结果完全混乱。
例如,我有一个像这样的列表(只是为了说明,并不是我的真实情况):

List<List<String>> list = {{a, b, c}, {d, e}, {f, g, h, i}};

RecyclerView应该显示为(第一行包含三个子行,第二行有两个,最后一个有四个):

|----a-----|  
|----b-----|  
|----c-----|  
|=======|  
|----d-----|  
|----e-----|  
|=======|  
|----f-----|  
|----g-----|  
|----h-----|  
|----i-----|  

但是结果并不完全像上面的顺序。一些元素会被重复,有些则会消失。例如:
|----d-----|  
|----e-----|  
|----c-----|  
|=======|  
|----d-----|  
|----e-----|  
|=======|  
|----f-----|  
|----a-----|  

这里是我的一段代码:

    @Override
public void onBindViewHolder(ViewHolder holder, int position) {
    List<Event> list = eventList.get(position);
    if (holder.rows < list.size()) {
        holder.rowViewGroup.removeAllViews();
        holder.rows = 0;
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        TextView startView = new TextView(context);
        startView.setLayoutParams(layoutParams);
        Event headEvent = list.get(0);
        Calendar startCal = headEvent.getStartCal();
        startView.setText(String.format("%tD", startCal));
        holder.rowViewGroup.addView(startView);

    for (final Event event : list) {
        View element = LayoutInflater.from(context).inflate(R.layout.element, null);
        //start time view
        TextView startTimeView = (TextView)element.findViewById(R.id.eventStartTimeInElement);
        Calendar startTimeCal = event.getStartCal();
        startTimeView.setText(String.format("%tl:%tM %tp", startTimeCal, startTimeCal, startTimeCal));
        //end date time view
        TextView endView = (TextView)element.findViewById(R.id.eventEndTimeInElement);
        Calendar endCal = event.getEndCal();
        endView.setText(String.format("%tD  %tl:%tM %tp", endCal, endCal, endCal, endCal));
        //title view
        TextView title = (TextView)element.findViewById(R.id.eventTitleInElement);
        title.setText(event.getTitle());
        //member name

        Drawable divider = context.getResources().getDrawable(R.drawable.divider);
        ImageView dividerView = new ImageView(context);
        dividerView.setImageDrawable(divider);
        holder.rowViewGroup.addView(dividerView);
        holder.rowViewGroup.addView(element);
        holder.rows++;
        }
    }
} 

这是我的row.xml:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/recycleViewRow">

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="0dp"
        card_view:cardElevation="2sp"
        card_view:cardUseCompatPadding="true"
        >

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/rowView"
            android:paddingLeft="20dp"
            android:paddingRight="20dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/eventStartTimeInRow"
                />

            </LinearLayout>

    </android.support.v7.widget.CardView>   

以及element.xml(包含在row.xml中):

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">



    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="Small Text"
            android:id="@+id/eventStartTimeInElement"
            android:layout_weight="2" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="Small Text"
            android:id="@+id/eventEndTimeInElement"
            android:gravity="end"
            android:layout_weight="1"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="left">

        <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"                            
            android:textAppearance="?android:attr/textAppearanceMedium"                            
            android:text="Medium Text"
            android:id="@+id/eventTitleInElement"/>

            </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right">

            <android.support.v7.widget.CardView
                xmlns:card_view="http://schemas.android.com/apk/res-auto"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                card_view:cardCornerRadius="2dp"
                card_view:cardElevation="2sp"
                card_view:cardUseCompatPadding="true">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="Small Text"
                android:id="@+id/memberNameInElement"
                android:gravity="end"
                />
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

</LinearLayout>   

我知道这不是一个真正好的实现方法,所以有没有人能告诉我更好的实现方法?谢谢...

1个回答

0

我认为你最好的选择是将你的列表嵌套结构展开成一个列表。

这只是为了ListView的目的。你的适配器将会像所有的列表都被串成一个长列表一样运作。

首先,为你嵌套列表中的所有项目创建一个单一列表索引。

例如:

    List<List<String>> listOfLists = ... // your original data
    List<String> listForView = new ArrayList<String>();

    for (List<String> innerList : listOfLists) {
        for (String str : innerList) {
            listForView.add(str);
        }
        listForView.add("---"); // e.g. marker value for divider
    }

现在在您的适配器的getItem()中,只需要返回listForView.get(position)

每当嵌套列表结构发生更改时,您都需要重新进行此展平操作并调用notifyDataSetChanged()

如果您必须根据位置确定项目位于哪个列表,则情况会变得有些棘手,但您始终可以以类似的方式索引内部列表。


但我真的想使用CardView来分隔每个组。如果我使用一个扁平列表,有什么更好的方法来实现这一点呢? - CrackThisRay
小光 - 我想做类似的事情。你有取得任何进展吗? - Al Lelopath
AI L-- 我使用不同类型的行来解决这个问题。你可以尝试一下。只需覆盖 getItemType() 方法并创建许多不同的行即可。对于我的情况,我使用子列表的大小来表示 itemType,并使用循环添加不同大小的子行。也许会对你有所帮助。 - CrackThisRay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接