0

Я показываю ежедневные события. Количество событий/день является переменной. Каждый элемент в RecView - это День, который должен содержать столько просмотров, сколько количество событий.Динамическое добавление компонентов в RecyclerView

Вот макет одного элемента:

<?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 отображаются первое, события отображаются корректно, но после прокрутки некоторых событий отображаются несколько раз. Я знаю, что проблема связана с вызовом addLayouts(...) в onBindViewHolder(...), но я не знаю, как создать правильное количество просмотров для каждого дня.

UPDATE: 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); 
     } 
    } 

Duplicated views

+0

Проблема заключается в том, что элементы просмотра повторного использования повторно используются. Поэтому, если первый элемент имеет 10 событий, а 100-й элемент имеет 1 событие. 100-й элемент может по-прежнему отображать 10 событий, когда представление перерабатывается. Поэтому попробуйте: call viewHolder.llDay.removeAllViews() перед циклом for. –

+0

Я пробовал, но это не помогает. Только один день раздувается. Другое решение может проверить, что llDays содержит представление, которое мы хотим добавить, но я не знаю, как их сравнивать. – Alex

+0

Можете ли вы опубликовать код viewHolder. –

ответ

5

Ok, наконец, понял это. Во-первых изменить свое расположение к:

<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); 

Также до петли для петли Добавить

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

Я действительно, очень ценю вашу помощь. Большое спасибо! – Alex