简体   繁体   English

RecyclerView 将最后一个 ArrayList 项数据设置为第一项

[英]RecyclerView set the last ArrayList item data to the first item

I have a RecyclerView and an adapter which has an ArrayList of Person model.我有一个 RecyclerView 和一个具有 Person 模型的 ArrayList 的适配器。 When the app starts I type the names in the EditText and press the button:当应用程序启动时,我在 EditText 中输入名称并按下按钮:

1) 1) 在此处输入图片说明

2) 2) 在此处输入图片说明

3) 3) 在此处输入图片说明

4) 4) 在此处输入图片说明

But when I log personList data in the activity, the result is:但是当我在活动中记录 personList 数据时,结果是:

personList: Item 0 -----> Alireza
personList: Item 1 -----> Tohid
personList: Item 2 -----> Alireza

First item is removed and last item is repeated in the first one.第一个项目被删除,最后一个项目在第一个项目中重复。 (My adapter is more complex, but I have reduced the code and views to focus on the main problem) (我的适配器更复杂,但我减少了代码和视图以专注于主要问题)

Adapter Layout:适配器布局:

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

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

<EditText
    android:id="@+id/et_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name" />

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Add" />

</LinearLayout>

Adapter Class:适配器类:

public class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private ArrayList<Person> mList;
private View.OnClickListener listener;

public TestAdapter(ArrayList<Person> mList, View.OnClickListener listener) {
    this.mList = mList;
    this.listener = listener;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_adapter_item, parent, false);

    if (viewType == Person.State.FIRST.getValue()) {
        return new FirstViewHolder(itemView);
    } else { // if (viewType == Person.State.SECOND.getValue())
        return new SecondViewHolder(itemView);
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    final int pos = holder.getAdapterPosition();
    final Person person = mList.get(pos);

    if (holder instanceof FirstViewHolder) {

        final FirstViewHolder h = (FirstViewHolder) holder;
        h.tvName.setVisibility(View.GONE);
        h.etName.setVisibility(View.VISIBLE);
        h.etName.setText("");
        h.etName.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                person.setFirstName(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        h.btnAccept.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                person.setState(Person.State.SECOND);
                notifyItemChanged(pos);

                listener.onClick(v);
            }
        });

    } else { // if (holder instanceof SecondViewHolder)

        final SecondViewHolder h = (SecondViewHolder) holder;
        h.tvName.setVisibility(View.VISIBLE);
        h.tvName.setText(person.getFirstName());
        h.etName.setVisibility(View.GONE);
        h.btnAccept.setVisibility(View.GONE);
    }
}

private static class FirstViewHolder extends RecyclerView.ViewHolder {

    private TextView tvName;
    private EditText etName;
    private Button btnAccept;

    private FirstViewHolder(@NonNull View itemView) {
        super(itemView);

        tvName = itemView.findViewById(R.id.tv_name);
        etName = itemView.findViewById(R.id.et_name);
        btnAccept = itemView.findViewById(R.id.button);
    }
}

private static class SecondViewHolder extends RecyclerView.ViewHolder {

    private TextView tvName;
    private EditText etName;
    private Button btnAccept;

    SecondViewHolder(@NonNull View itemView) {
        super(itemView);

        tvName = itemView.findViewById(R.id.tv_name);
        etName = itemView.findViewById(R.id.et_name);
        btnAccept = itemView.findViewById(R.id.button);
    }
}

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

@Override
public int getItemViewType(int position) {
    return mList.get(position).getState().getValue();
}
}

Related Part of Activity:活动的相关部分:

ArrayList<Person> personList = new ArrayList<>();
personList.add(new Person("", Person.State.FIRST));
adapter = new TestAdapter(personList, new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (personList.size() < 3) {
                personList.add(new Person("", Person.State.FIRST));
                adapter.notifyItemInserted(personList.size());
            } else {
                for (int i = 0; i < personList.size(); i++) {
                    Log.i("personList", "Item " + i + " -----> " + personList.get(i).getName());
                }
            }
        }
    });

RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

What's the problem?有什么问题? And how can I achieve correct and real ArrayList Data?我怎样才能获得正确和真实的 ArrayList 数据?

your problem lies with addTextChangedListener, when new items are added in recycler view old TextChangedListeners arent removed.您的问题在于 addTextChangedListener,当在回收器视图中添加新项目时,旧的 TextChangedListeners 不会被删除。 and they keep changing your list items values.他们会不断更改您的列表项值。 you should remove those listeners when state is changed to SECOND state(which is surprisingly tricky look at this How to remove all listeners added with addTextChangedListener ).当状态更改为 SECOND 状态时,您应该删除这些侦听器(查看如何删除使用 addTextChangedListener 添加的所有侦听器非常棘手)。 or you should add this validation when onTextChanged is triggered.或者您应该在触发 onTextChanged 时添加此验证。 if (person.getState() == Person.State.FIRST) person.setFirstName(s.toString());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM