如何在ViewlerView中保持ViewHolder的状态

时间:2015-05-12 08:11:45

标签: android android-cardview android-recyclerview

我有一个包含几个网格单元的RecyclerView。 CLICK ME按钮上方有一个TextView。我将展示一些例子,单击按钮时TextView上的名称。对我来说问题是TextView中的文本不是持久的。

以下是我在MainActivity中的代码:

private void initializeData(){
    persons = new ArrayList<>();
    persons.add(new Person("Name 1", "23 years old", R.drawable.a));
    persons.add(new Person("Name 2", "25 years old", R.drawable.b));
    persons.add(new Person("Name 3", "35 years old", R.drawable.c));
    persons.add(new Person("Name 4", "35 years old", R.drawable.c));
    persons.add(new Person("Name 5", "35 years old", R.drawable.c));
    persons.add(new Person("Name 6", "35 years old", R.drawable.c));
    persons.add(new Person("Name 7", "35 years old", R.drawable.c));
    persons.add(new Person("Name 8", "35 years old", R.drawable.c));
    persons.add(new Person("Name 9", "35 years old", R.drawable.c));
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView  = (RecyclerView)findViewById(R.id.my_recycler_view);
    recyclerView.setHasFixedSize(true);

    layoutManager = new GridLayoutManager(this, 1, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());

    persons = new ArrayList<>();
    initializeData();

    RVAdapter adapter = new RVAdapter(persons);
    recyclerView.setAdapter(adapter);

    adapter.notifyDataSetChanged();
}

我的适配器中的代码:

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{

List<Person> persons;

RVAdapter(List<Person> persons){
    this.persons = persons;
}

@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cards_layout, viewGroup, false);
    PersonViewHolder pvh = new PersonViewHolder(v);
    return pvh;
}

@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
    personViewHolder.personName.setText(persons.get(i).name);
    personViewHolder.personAge.setText(persons.get(i).age);
    personViewHolder.personPhoto.setImageResource(persons.get(i).photoId);

    final PersonViewHolder vh = personViewHolder;
    personViewHolder.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            vh.textView.setText(vh.personName.getText().toString());
        }
    });
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

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

public static class PersonViewHolder extends RecyclerView.ViewHolder {
    CardView cv;
    public TextView personName;
    public TextView personAge;
    ImageView personPhoto;
    public TextView textView;
    public Button button;

    PersonViewHolder(View itemView) {
        super(itemView);
        cv = (CardView)itemView.findViewById(R.id.cv);
        personName = (TextView)itemView.findViewById(R.id.person_name);
        personAge = (TextView)itemView.findViewById(R.id.person_age);
        personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
        textView = (TextView)itemView.findViewById(R.id.text);
        button = (Button)itemView.findViewById(R.id.button);
    }
}
}

我认为原因是重新创建了ViewHolder。如何应对这种情况?感谢。

enter image description here

2 个答案:

答案 0 :(得分:0)

将boolean字段添加到与每个单元格对应的对象,并在用户单击按钮时将此值设置为true,然后将逻辑添加到onBindViewHolder()方法:

if (clicked) {
    showText();
} else {
    hideText();
}

同样在OnClickListener中将vh.textView.setText(vh.personName.getText().toString());更改为personViewHolder.personName.setText(persons.get(i).name); - 您必须仅使用List<Person> persons来保留和请求数据,而不是来自ViewHolder,因为适配器会重复使用视图以及何时使用从ViewHolder请求数据,您将获得先前膨胀的数据视图

答案 1 :(得分:0)

您可以为模型isShowName添加布尔Person,然后使用onBindViewHolder()方法:

...
personViewHolder.button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        vh.textView.setText(vh.personName.getText().toString());
        persons.get(i).setIsShowName(true); // don't forget!
    }
});

if (persons.get(i).isShowName()) {
    vh.textView.setText(vh.personName.getText().toString());
} else {
    vh.textView.setText("");
}