Android RecyclerView - 当我更改第一个项目时,也是最后一个更改

时间:2017-03-26 08:05:36

标签: android

我为我的英语道歉,我是法国人。

我在RecyclerView中遇到列表问题。实际上,我想动态更改项目的TextView。但是,当我更改第一个项目的textView时,最后一个也改变了。我使用CardView来表示我的项目。

我不认为这是我的代码,而是RecyclerView的特殊性。

提前谢谢

我的适配器

public class CardAgendaAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements TimePickerDialog.OnTimeSetListener {

    private static final int LENGTH = 7;
    static private final int test[] = {1, 1, 1, 1, 1, 1, 1};
    private  int[][] dispo = new int[7][4];
    private Context context;
    private int startHour = -1;
    private int finishHour = -1;
    private int startMinute = -1;
    private int finishMinute = -1;
    private int pos = 0;
    private RecyclerView.ViewHolder holderr;

    public CardAgendaAdapter(Context context) {
        this.context = context;
        for (int i = 0; i < LENGTH; i++) {
            dispo[i][0] = -1;
            dispo[i][1] = -1;
            dispo[i][2] = -1;
            dispo[i][3] = -1;
        }
    }

    @Override
    public int getItemViewType(int position) {
        // Just as an example, return 0 or 2 depending on position
        // Note that unlike in ListView adapters, types don't have to be contiguous
        return test[position];
    }

    @Override
    public int getItemCount() {
        return LENGTH;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view1 = inflater.inflate(R.layout.agenda_modify_card, parent, false);
        View view2 = inflater.inflate(R.layout.agenda_card, parent, false);

        switch (viewType) {
            case 0: return new ViewHolder0(view1);
            case 1: return new ViewHolder2(view2);
        }
        return null;
    }

    static final  String days[] = {"Lundi", "Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"};

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        switch (getItemViewType(position)) {
            case 1 :
                ViewHolder2 v2 = (ViewHolder2) holder;
                v2.setDay(days[position]);
                v2.setImage(position);
                Log.d("item : ", String.valueOf(position));
                v2.add.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        pos = position;
                        holderr = holder;
                        TimePickerDialog timePickerDialog = new TimePickerDialog(context, listener, 0, 0, true);
                        timePickerDialog.show();
                    }
                });
                break;
            case 0:
                ViewHolder0 v0 = (ViewHolder0) holder;
                v0.setTextCard();
                v0.setDay(days[position]);
                v0.setImage(position);
                break;
        }
    }

    public String testText(int startHour, int startMinute, int finishHour, int finishMinute) {
        return String.valueOf(Html.fromHtml("Vous êtes disponnible de <b>" + String.valueOf(startHour) + "h" + String.valueOf(startMinute) +"</b> à <b> "+ String.valueOf(finishHour)+"h" +String.valueOf(finishMinute)+"</b>"));
    }

    public void setHour(int poistion, int startHour, int startMinute, int finishHour, int finishMinute, final RecyclerView.ViewHolder holder) {
        dispo[poistion][0] = startHour;
        dispo[poistion][1] = startMinute;
        dispo[poistion][2] = finishHour;
        dispo[poistion][3] = finishMinute;

        switch (getItemViewType(poistion)) {
            case 1:
                ViewHolder2 v2 = (ViewHolder2) holder;
                v2.setTextCard(startHour,startMinute,finishHour,finishMinute);
                //view.findViewById(R.id.button_add).setVisibility(View.INVISIBLE);
                //view.findViewById(R.id.button_modify).setVisibility(View.VISIBLE);
        }

        Log.d("Jour : " + poistion, String.valueOf(dispo[poistion][0]));
        Log.d("Jour : " + poistion, String.valueOf(dispo[poistion][1]));
        Log.d("Jour : " + poistion, String.valueOf(dispo[poistion][2]));
        Log.d("Jour : " + poistion, String.valueOf(dispo[poistion][3]));
    }

    private void reinitHour() {
        startHour = -1;
        startMinute = -1;
    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        TimePickerDialog timePickerDialog2;
        Log.d("Picker la", "AVANT");
        timePickerDialog2 = new TimePickerDialog(context, listener, 0, 0, true);
        Log.d("Picker la", "APRÈS");
        timePickerDialog2.show();
    }

    protected TimePickerDialog.OnTimeSetListener listener =
            new TimePickerDialog.OnTimeSetListener() {

                @Override
                public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfDay) {
                    if (startHour == -1 && startMinute == -1) {
                        startHour = hourOfDay;
                        startMinute = minuteOfDay;

                        TimePickerDialog timePickerDialog2;
                        timePickerDialog2 = new TimePickerDialog(context, listener, 0, 0, true);

                        timePickerDialog2.show();
                        Toast.makeText(view.getContext(), "Heure de depart : " + startHour + " minutes de départ : " + startMinute, Toast.LENGTH_LONG).show();
                    } else {
                        finishHour = hourOfDay;
                        finishMinute = minuteOfDay;
                        Log.d("ça passe la", "FINNNNNNNN");
                        Toast.makeText(view.getContext(), "Heure de fin : " + finishHour + " minutes de fin : " + finishMinute, Toast.LENGTH_LONG).show();

                        setHour(pos,startHour,startMinute,finishHour,finishMinute, holderr);
                        reinitHour();
                    }
                }
            };

    class ViewHolder2 extends RecyclerView.ViewHolder {
        TextView title;
        TextView disponibility;
        ImageView imageView;
        Button add;
        Button modify;

        public ViewHolder2(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.card_title);
            disponibility = (TextView) itemView.findViewById(R.id.card_text);
            imageView = (ImageView) itemView.findViewById(R.id.card_image);
            add = (Button) itemView.findViewById(R.id.button_add);
            modify = (Button) itemView.findViewById(R.id.button_modify);
        }

        public void setTextCard(int startHour, int startMinute, int finishHour, int finishMinute) {
            disponibility.setText(Html.fromHtml("Vous êtes disponnible de     <b>" + String.valueOf(startHour) + "h" + String.valueOf(startMinute) +"</b>     à <b> "+ String.valueOf(finishHour)+"h" +String.valueOf(finishMinute)+"    </b>"));  
        }

        public void setDay(String str) {
            if (title != null) {
                title.setText(str);
            }
        }

        public void setImage(int position) {
            if (imageView != null) {
                imageView.setImageResource(getId(position+1));
            }
        }

        private int getId(int position) {
            Context context = imageView.getContext();
            int id =     context.getResources().getIdentifier("tennis"+position, "drawable",     context.getPackageName());
            return id;
        }
    }

    class ViewHolder0 extends RecyclerView.ViewHolder {
        TextView textCard;
        TextView textTitle;
        ImageView imageView;
        public ViewHolder0(View itemView){
            super(itemView);
            textCard = (TextView) itemView.findViewById(R.id.card_text);
            textTitle = (TextView) itemView.findViewById(R.id.card_title);
            imageView = (ImageView) itemView.findViewById(R.id.card_image);
        }

        public void setDay(String str) {
            if (textTitle != null) {
                textTitle.setText(str);
            }
        }

        public void setTextCard() {
            textCard.setText(Html.fromHtml("Vous êtes disponnible de     <b>17h30</b> à <b>18h30</b>"));
        }

        public void setImage(int position) {
            if (imageView != null) {
                imageView.setImageResource(getId(position + 1));
            }
        }

        private int getId(int position) {
            Context context = imageView.getContext();
            int id =     context.getResources().getIdentifier("tennis"+position, "drawable",     context.getPackageName());
            return id;
        }
    }    
}

agenda_card.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView      xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="@dimen/card_height"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/md_keylines"
android:layout_marginLeft="@dimen/md_keylines"
android:layout_marginRight="@dimen/md_keylines"
app:elevation="0dp"
android:foreground="?attr/selectableItemBackground">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/card_image"
        android:layout_width="match_parent"
        android:layout_height="@dimen/card_image_height"
        android:scaleType="centerCrop"
        android:src="@drawable/tennis1" />

    <TextView
        android:id="@+id/card_title"
        android:layout_width="match_parent"
        android:layout_height="@dimen/card_title_height"
        android:text="Lundi"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textColor="@color/white"
        android:layout_above="@+id/card_text"
        android:layout_alignLeft="@+id/card_text"
        android:layout_alignStart="@+id/card_text"
        android:layout_marginLeft="5dp"
        android:gravity="center_vertical" />

    <TextView
        android:id="@+id/card_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Vous n'avez pas ajouté de disponibilité"
        android:ellipsize="end"
        android:singleLine="true"
        android:textColor="@color/dark_grey"
        android:textSize="@dimen/article_subheading"
        android:layout_below="@+id/card_image"
        android:layout_centerHorizontal="true"
        android:gravity="center_horizontal" />

    <Button
        android:id="@+id/button_add"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/borderlessButtonStyle"
        android:textColor="@color/green"
        android:text="AJOUTER"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
   </RelativeLayout>
</android.support.v7.widget.CardView>

1 个答案:

答案 0 :(得分:0)

它与您的绑定以及适配器的工作方式有关。

就像已经告诉你的名字一样,如果原来的位置不再显示,你的适配器的视图会被回收显示在另一个位置。但是ViewHolder2的代码不会更新视图持有者的所有数据。

ViewHolder2 v2 = (ViewHolder2) holder;
v2.setDay(days[position]);
v2.setImage(position);
Log.d("item : ", String.valueOf(position));
v2.add.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        pos = position;
        holderr = holder;
        TimePickerDialog timePickerDialog = new TimePickerDialog(context, listener, 0, 0, true);
        timePickerDialog.show();
    }
});

缺少对v2.setTextCard()的调用。因此,您需要确保disponibility设置正确。这通常适用于任何视图持有者的所有字段。

尝试将适配器更多一些。此外,在视图持有者上使用update()方法来处理更改也很方便。

作为旁注,您的onCreateViewHolder()方法可能会更有效率。目前你每次都在膨胀两个视图,即使你只使用一个。

LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
    case 0: return new ViewHolder0(inflater.inflate(R.layout.agenda_modify_card, parent, false));
    case 1: return new ViewHolder2(inflater.inflate(R.layout.agenda_card, parent, false));
    default: return null;
}