这是我QuestionHolder
:
private class QuestionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private JSONObject question;
private CheckBox checkBox;
private TextView question_txt;
public QuestionHolder(final LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.question_item, parent, false));
checkBox = (CheckBox) itemView.findViewById(R.id.question_checkbox);
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//try {
//Toast.makeText(getActivity(), "ID: " + question.get("_id"), Toast.LENGTH_SHORT).show();
//} catch (JSONException e) { }
// TODO: If this was checked then add the question's id to the answered list
}
});
question_txt = (TextView) itemView.findViewById(R.id.question);
itemView.setOnClickListener(this);
}
在这里我绑定questiontxt
:
public void bind(JSONObject question) {
this.question = question;
try {
question_txt.setText(question.getString("_question"));
} catch (JSONException je) { }
}
@Override
public void onClick(View v) {
// TODO: If this was checked then add the question's id to the answered list
}
}
这是我的适配器,它扩展了QuestionHolder
:
private class QuestionAdapter extends RecyclerView.Adapter<QuestionHolder> {
private JSONArray questions;
public QuestionAdapter(JSONArray questions) {
this.questions = questions;
}
@Override
public QuestionHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
return new QuestionHolder(LayoutInflater.from(getActivity()), parent);
}
这是onBindViewHolder
:
@Override
public void onBindViewHolder(QuestionHolder holder, int position) {
try {
final JSONObject question = questions.getJSONObject(position);
holder.bind(question);
} catch (JSONException je) { }
}
@Override
public int getItemCount() {
return questions.length();
}
}
这是QuestionHolder
:
private class QuestionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private JSONObject question;
private CheckBox checkBox;
private TextView question_txt;
public QuestionHolder(final LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.question_item, parent, false));
checkBox = (CheckBox) itemView.findViewById(R.id.question_checkbox);
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//try {
//Toast.makeText(getActivity(), "ID: " + question.get("_id"), Toast.LENGTH_SHORT).show();
//} catch (JSONException e) { }
// TODO: If this was checked then add the question's id to the answered list
}
});
question_txt = (TextView) itemView.findViewById(R.id.question);
itemView.setOnClickListener(this);
}
public void bind(JSONObject question) {
this.question = question;
try {
question_txt.setText(question.getString("_question"));
} catch (JSONException je) { }
}
@Override
public void onClick(View v) {
// TODO: If this was checked then add the question's id to the answered list
}
}
这是因为您的ViewHolder
在滚动时被回收。因此,您需要为每个项目位置保留复选框的状态。您可以使用 SparseBooleanArray 来处理此问题。
你可以做这样的事情:
private class QuestionAdapter extends RecyclerView.Adapter<QuestionHolder> {
SparseBooleanArray checkedItems = new SparseBooleanArray();
...
@Override
public void onBindViewHolder(QuestionHolder holder, int position) {
try {
final JSONObject question = questions.getJSONObject(position);
// Remember to change access modifier of checkBox in your ViewHolder
// Get the state from checkedItems. If no previous value, it will return false.
holder.checkBox.setChecked(checkedItems.get(position));
// This is a sample. Do not use create listener here.
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// save the check state
checkedItems.put(position, true);
}
holder.bind(question);
} catch (JSONException je) { }
}
...
}
RecyclerView 在滚动时从布局中删除(回收(不可见的视图,这是 recyclerView 的基本行为,以减少内存使用。
因此,当带有复选框的视图被"回收"时,选中的复选框将被取消选中,如果它有侦听器,则会调用侦听器。
回收侦听器时,可以从视图中删除侦听器。只需覆盖 onViewRecycling 方法即可。
@Override
public void onViewRecycled(@NonNull MyViewHolder holder) {
if (holder.checkBox != null) {
holder.checkBox.setOnClickListener(null);
}
super.onViewRecycled(holder);
}
当再次构建视图时,在滚动时,您的侦听器也将再次添加。
在对这个复杂问题进行一些研究之后
我为我的货币转换器项目做了这样的事情:
以下是步骤:
- 创建了一个带有内部视图持有人的自定义适配器
- 创建了选择的干扰更改并通知Adaper in MainActivty
- 已创建模型类 为"我的列表"创建了布局
编码:
适配器和视图支架
class Adapter extends RecyclerView.Adapter<Adapter.VH> {
ArrayList<Currency> list, checkedCurrencies = new ArrayList<>();
CurrencySelectionChangelistener listener;
public Adapter(@NonNull ArrayList<Currency> list, CurrencySelectionChangelistener listener) {
this.list = list;
this.listener = listener;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new VH(LayoutInflater.from(getContext()).inflate(R.layout.layout_list_of_all_items, parent, false));
}
@Override
public void onBindViewHolder(@NonNull VH holder, @SuppressLint("RecyclerView") int position) {
Currency currentCurrency = list.get(position);
holder.checkBox.setChecked(currentCurrency.isChecked());
holder.mDis.setText(currentCurrency.getDescription());
//ignore below line it's just for sorting the string to set On TextView and with another purpose
String name = currentCurrency.getName().toLowerCase().replace(" ", "");
holder.mName.setText(name.toUpperCase());
holder.mLogo.setImageResource(currentCurrency.getLogo(name));
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (holder.checkBox.isChecked()) {
list.get(position).setChecked(true);
checkedCurrencies.add(currentCurrency);
} else if (!holder.checkBox.isChecked()) {
list.get(position).setChecked(false);
checkedCurrencies.remove(currentCurrency);
}
//calling the interference's function
onSelection(checkedCurrencies);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
class VH extends RecyclerView.ViewHolder {
TextView mName, mDis;
ImageView mLogo;
CheckBox checkBox;
public VH(@NonNull View itemView) {
super(itemView);
checkBox = itemView.findViewById(R.id.checkboxAllItems);
mLogo = itemView.findViewById(R.id.ImageViewAllItemLogo);
mName = itemView.findViewById(R.id.textViewAllItemCName);
mDis = itemView.findViewById(R.id.textViewAllItemCDis);
}
}
}
接口
public interface CurrencySelectionChangelistener {
public void onSelection(ArrayList<Currency> currencies);}
我正在使用回收器视图的片段
public class AddMoreCurrencyFragment extends Fragment implements CurrencySelectionChangelistener {
FragmentAddNewCurrencyBinding binding;
ArrayList<Currency> currencies;
Adapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentAddNewCurrencyBinding.inflate(inflater);
CurrencyContainerActivity.title.setVisibility(View.VISIBLE);
CurrencyContainerActivity.title.setText("Add Currency");
CurrencyContainerActivity.backBtn.setVisibility(View.VISIBLE);
currencies = new ArrayList<>();
for (Currency c : CurrencyContainerActivity.listOfCurrencies) {
currencies.add(new Currency(c.getName(), c.getDescription(), false));
}
adapter = new Adapter(currencies, this);
binding.recView.setAdapter(adapter);
binding.done.setOnClickListener(view -> {
});
return binding.getRoot();
}
@Override
public void onSelection(ArrayList<Currency> currencies) {
CurrencyContainerActivity.listToAdd.addAll(currencies);
Toast.makeText(getContext(), currencies.toString(), Toast.LENGTH_LONG).show();
adapter.notifyDataSetChanged();
}
}
每个项目的 XML 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/white"
android:orientation="vertical"
android:weightSum="3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="59dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="3">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.89"
app:cardCornerRadius="16dp">
<ImageView
android:id="@+id/ImageViewAllItemLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/flag" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/textViewAllItemCName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="19dp"
android:layout_weight=".75"
android:fontFamily="@font/poppins"
android:text="@string/pkr"
android:textAlignment="center"
android:textAllCaps="true"
android:textColor="@color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/textViewAllItemCDis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="0.47"
android:fontFamily="@font/poppins"
android:text="@string/pkr"
android:textAlignment="textStart"
android:textColor="@color/black"
android:textSize="13sp" />
<CheckBox
android:id="@+id/checkboxAllItems"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_weight="0.90"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#3F000000" />
</LinearLayout>
模型类
public class Currency {
private String Name, Description;
private int logo;
boolean isChecked;
public Currency(String name, String description, boolean isChecked) {
Name = name;
Description = description;
this.isChecked = isChecked;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
}
如果我错过了什么,可以。谢谢