【问题标题】:Adding components dynamically to RecyclerView动态添加组件到 RecyclerView
【发布时间】:2015-12-29 19:45:53
【问题描述】:

我正在显示每日事件。每天的事件数量是可变的。 RecView 中的每个项目都是一个 Day,它应该包含与事件数一样多的视图。

这是一个项目的布局:

<?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="match_parent"
    android:id="@+id/llDay">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvDay"
        android:text="TODAY"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="15dp"
        android:textSize="25sp"
        android:textStyle="bold" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvNothing"
        android:text="No events"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:textSize="18sp"
        android:textStyle="italic"
        android:visibility="gone"/>

</LinearLayout>

我想动态地向 llDay 添加视图。 这是我的适配器:

public class DiaryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    ArrayList<ArrayList<Displayable>> diaryEvents = new ArrayList<>(); 
    Context context;

    public DiaryAdapter(ArrayList<ArrayList<Displayable>> diaryEvents, Context context) {
        this.diaryEvents = diaryEvents;
        this.context = context;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_day_diary, parent, false);
        DiaryDayViewHolder viewHolder = new DiaryDayViewHolder(viewGroup);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        DiaryDayViewHolder viewHolder = (DiaryDayViewHolder) holder;
        ArrayList<Displayable> events = diaryEvents.get(position);

        if (events.size() > 0){
            addLayouts(events, viewHolder);
        }
        else{
            viewHolder.tvNothing.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public int getItemCount() {
        return diaryEvents.size();
    }

    private void addLayouts(ArrayList<Displayable> events, DiaryDayViewHolder viewHolder) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

        for (Displayable event : events) {
            switch (event.getEventType()){
                case Types.TYPE_TEACHING:
                    TeachingDiaryLayout teachingDiaryLayout = new TeachingDiaryLayout(context);
                    teachingDiaryLayout.setLayoutParams(params);
                    teachingDiaryLayout.setViews((Teaching) event);
                    viewHolder.llDay.addView(teachingDiaryLayout);
                    viewHolder.tvDay.setText("DAY"); // TODO: day + date

                    break;
                case Types.TYPE_TASK: // TODO
                    break;
                case Types.TYPE_EXAM: // TODO
                    break;
            }
        }
    }
}

RecyclerView第一次显示时,事件显示正确,但滚动后某些事件显示多次。我知道问题是通过在onBindViewHolder(...) 中调用addLayouts(...) 引起的,但我不知道如何为每天创建正确数量的视图。

更新:添加了 ViewHolder:

public static class DiaryDayViewHolder extends RecyclerView.ViewHolder {
        LinearLayout llDay;
        TextView tvDay;
        TextView tvNothing;

        public DiaryDayViewHolder(View itemView) {
            super(itemView);

            llDay = (LinearLayout) itemView.findViewById(R.id.llDay);
            tvDay = (TextView) itemView.findViewById(R.id.tvDay);
            tvNothing = (TextView) itemView.findViewById(R.id.tvNothing);
        }
    }

【问题讨论】:

  • 问题是因为recycler view items被重用了。所以如果第一个项目有 10 个事件,第 100 个项目有 1 个事件。当视图被回收时,第 100 项可能仍会显示 10 个事件。所以试试这个:在 for 循环之前调用 viewHolder.llDay.removeAllViews()。
  • 我试过了,但没有帮助。只显示一天。另一种解决方案可以检查 llDays 是否包含我们要添加的视图,但我不知道如何比较它们。
  • 你能发布viewHolder代码吗?
  • 我已经添加了 ViewHolder

标签: android android-custom-view android-recyclerview


【解决方案1】:

好吧,终于明白了。 首先将您的布局更改为:

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/llDay">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvDay"
        android:text="TODAY"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="15dp"
        android:textSize="25sp"
        android:textStyle="bold" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvNothing"
        android:text="No events"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:textSize="18sp"
        android:textStyle="italic"
        android:visibility="gone"/>
 <LinearLayout 
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/llDay1"/>
</LinearLayout>

现在在您的视图持有者中添加另一个 LinearLayout 参数:

LinearLayout llDay,llday1;

并在 addLayouts 方法内部更改:

 viewHolder.llDay.addView(teachingDiaryLayout);

 viewHolder.llDay1.addView(teachingDiaryLayout);

也在for循环之前添加

     viewHolder.llDay1.removeAllViews();
for (Displayable event : events)

【讨论】:

  • 我真的非常感谢您的帮助。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多