[英]RecyclerView Adapter inserting rows in weird positions
我的MainActivity
內部有一個Fragment
,其中包含由RecyclerView
填充的RecyclerView.Adapter
。 RecyclerView
使row_layout.xml
文件膨脹,該文件具有一個EditText
和一個ImageButton
,如下所示:
該按鈕最初加載有“添加”圖像。 單擊后,我的適配器將執行以下操作:
package com.fragments.homework04;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
public static int positionAdapter;
private ArrayList<ItemData> itemsData;
AdapterButtonInterface mListener;
public MyAdapter(ArrayList<ItemData> itemsData, AdapterButtonInterface adapterButtonInterface) {
this.itemsData = itemsData;
try{
mListener = adapterButtonInterface;
}
catch(ClassCastException e){
throw new ClassCastException("Class does not implement interface!");
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public EditText txtIngredients;
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtIngredients = itemLayoutView.findViewById(R.id.etIngredientName);
imgViewIcon = itemLayoutView.findViewById(R.id.btnAddRemoveIngredient);
}
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, null);
Log.d("itemsSizeAdapter", String.valueOf(itemsData.size()));
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.imgViewIcon.setTag(itemsData.get(position).getTag());
viewHolder.imgViewIcon.setImageResource(itemsData.get(position).getImageUrl());
viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
positionAdapter = viewHolder.getAdapterPosition();
if(itemsData.get(position).getTag().contains("Add")){
if(getItemCount() < 5){
itemsData.get(position).setIngredientValue(viewHolder.txtIngredients.getText().toString());
mListener.addBtnClicked(positionAdapter, getItemCount(), itemsData.get(position).getIngredientValue());
}
}
else{
if(getItemCount() > 0){
Log.d("adapterPosition:", String.valueOf(position));
mListener.removeBtnClicked(positionAdapter, getItemCount());
}
}
}
});
}
// Return the size of your itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
return itemsData.size();
}
public interface AdapterButtonInterface{
void addBtnClicked(int position, int itemCount, String ingredientValue);
void removeBtnClicked(int position, int itemCount);
}
}
基本上在接口中調用該方法,該方法由我的片段實現。 在我的片段中,我正在這樣做:
ArrayList<ItemData> itemsData;
public void addBtnClicked(int position, int itemCount, String ingredientValue) {
if(itemCount == 4){
//Requirement that there can only be 5 rows at any time.
//Hence when itemCount == 4, we are adding the 5th row and it needs to be a remove instead of add
itemsData.add(position + 1, new ItemData("Remove" + itemCount, R.mipmap.remove_ing, ""));
}
else{
itemsData.add(position + 1, new ItemData("Add" + itemCount, R.mipmap.add_ing, ""));
}
//When the row is added, the EditText's value isn't stored anywhere
//So I am adding it to the arraylist I have
itemsData.get(position).setIngredientValue(ingredientValue);
itemsData.get(position).setImageUrl(R.mipmap.remove_ing);
itemsData.get(position).setTag("Remove");
mAdapter.notifyDataSetChanged();
}
@Override
public void removeBtnClicked(int position, int itemCount) {
Log.d("listenerPosition:", String.valueOf(position));
itemsData.remove(position);
if(itemCount == 5){
itemsData.get(3).setImageUrl(R.mipmap.add_ing);
itemsData.get(3).setTag("Add3");
}
mAdapter.notifyDataSetChanged();
}
其中很大一部分效果很好。 應用加載時,我看到一個EditText和一個ImageButton。 當我第一次單擊ImageButton時,它將在第二個EditText和第二個ImageButton的下面添加它。
但是,第二次單擊按鈕時出現了問題。 第三行插入在RecyclerView
的頂部而不是底部。 我已經存在的第一和第二行(與EditText的內容一起)被下推,而我新添加的行位於回收站的頂部。
當我單擊新插入的第一行上的“刪除”按鈕時,它甚至變得更奇怪。 它刪除一行(按預期方式),並清除我所有的EditTexts(WHY)。
如果有人可以看看並告訴我我在哪里犯錯,我將不勝感激。 如果需要,我可以提供更多代碼。
您可以在ViewHolder
指定該位置為final
位置,以便可以在onClick()
處理程序中引用該位置。 由於該變量是final
變量,因此無論ViewHolder
可能處於任何新位置,它都不會改變。 代替使用final
變量,請嘗試使用getAdapterPosition()
。
getAdapterPosition
int getAdapterPosition()
返回此ViewHolder表示的項目的Adapter位置。
這可能不是您的問題,但請嘗試一下。
在適配器中使用這兩種方法
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.