gpt4 book ai didi

java - 从嵌套的 RecyclerView 中删除项目

转载 作者:行者123 更新时间:2023-12-01 16:18:41 28 4
gpt4 key购买 nike

我已经和这个问题斗争了好几个小时了。我有一个嵌套的 RecyclerView (即包含内部 Recycler View 的 RecyclerView)。父回收器 View 和子回收器 View 都是动态的。我遇到的问题是,当发生 CRUD(特别是删除)时,我无法找到正确通知子(内部)回收器 View 的方法。起初它工作正常,但后来我从“你必须是直接下降 View ”或 getAdapterPosition 返回 -1 或只是不正确的位置中得到各种随机错误。我认为我的实现非常标准,所以我问通知内部回收器 View 的正确方法是什么。

我非常接近回到以前的实现,其中涉及一系列 fragment ,每个 fragment 都包含一个回收 View ,但我对这种设计的性能提出疑问。我的代码如下:

父RecyclerView

public class RecipeRecyclerAdapter extends RecyclerView.Adapter<RecipeRecyclerAdapter.ViewHolder>
{
public interface OnRecipeRecyclerListener
{
//--------------------------- Proxy methods for OnDishRecyclerListener -----------------

void renameDish(int DishPosition, int RecipePosition);

void deleteDish(int DishPosition, int RecipePosition);


//--------------------------- OnRecipeRecyclerListener methods ----------------------------

void deleteRecipe(int RecipePosition);

void renameRecipe(int RecipePosition);

}

//Recycler Pool and tools
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();

//Recycler Parameters
private ArrayList<Recipe> allRecipes;
private Context context;


//Listener
@Setter
private OnRecipeRecyclerListener onRecipeRecyclerListener;


public RecipeRecyclerAdapter(Context context, ArrayList<Recipe> allRecipes)
{
this.allRecipes = allRecipes;
this.context = context;
}

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

return new RecipeRecyclerAdapter.ViewHolder(view, onRecipeRecyclerListener, context);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
Recipe Recipe = allRecipes.get(position);

holder.RecipeName.setText(Utils.colourFirstLetter(context, Recipe.getRecipeName(), R.color.progressFxBar));
holder.RecipeDate.setText(Utils.getDate(Recipe.getTimestamp()));

// Create layout manager with initial prefetch item count
LinearLayoutManager layoutManager = new LinearLayoutManager(
holder.DishsRecycler.getContext(),
LinearLayoutManager.VERTICAL,
false
);
layoutManager.setInitialPrefetchItemCount(Recipe.getDishs().size());

DishRecyclerAdapter DishsRecyclerAdapter = new DishRecyclerAdapter(Recipe.getDishs(), holder, context);

holder.DishsRecycler.setLayoutManager(layoutManager);
holder.DishsRecycler.setAdapter(DishsRecyclerAdapter);
holder.DishsRecycler.setRecycledViewPool(viewPool);
}


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

static class ViewHolder extends RecyclerView.ViewHolder implements DishRecyclerAdapter.OnDishRecyclerListener
private OnRecipeRecyclerListener onRecipeRecyclerListener;
private Context context;

TextView RecipeName, RecipeDate;
ImageView addDish;

//The Dishs Recycler
RecyclerView DishsRecycler;

public ViewHolder(@NonNull View itemView, OnRecipeRecyclerListener onRecipeRecyclerListener, Context context)
{
super(itemView);

this.onRecipeRecyclerListener = onRecipeRecyclerListener;
this.context = context;

RecipeName = itemView.findViewById(R.id.RecipeName);
RecipeDate = itemView.findViewById(R.id.RecipeDate);
addDish = itemView.findViewById(R.id.addDish);

DishsRecycler = itemView.findViewById(R.id.DishsRecyclerView);

loadListeners(itemView);
}

private void loadListeners(@NonNull View initView)
{
RecipeName.setOnClickListener(v ->
{
PopupMenu popup = new PopupMenu(context, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.Recipe_floating_menu, popup.getMenu());
popup.show();

popup.setOnMenuItemClickListener(item ->
{
switch (item.getItemId())
{
case R.id.menuDeleteRecipe:
onRecipeRecyclerListener.deleteRecipe(getAdapterPosition());

return true;
case R.id.menuRenameRecipe:
onRecipeRecyclerListener.renameRecipe(getAdapterPosition());

return true;
case R.id.menuRecipeProps:
onRecipeRecyclerListener.RecipeProps(getAdapterPosition());

return true;
default:
return false;
}
});
});

addDish.setOnClickListener(v ->
{
onRecipeRecyclerListener.addDish(getAdapterPosition());
});

}


//******************************* OnDishRecyclerListener *******************************

@Override
public void renameDish(int position)
{
onRecipeRecyclerListener.renameDish(position, getAdapterPosition());
}

@Override
public void deleteDish(int position)
{
onRecipeRecyclerListener.deleteDish(position, getAdapterPosition());
}
}
}

子(内部)RecyclerView

public class DishRecyclerAdapter extends RecyclerView.Adapter<DishRecyclerAdapter.ViewHolder>
{
public interface OnDishRecyclerListener
{
void renameDish(int position);

void deleteDish(int position);
}

private OnDishRecyclerListener onDishRecyclerListener;

private ArrayList<Dish> allDishs;
private Context context;

public DishRecyclerAdapter(ArrayList<Dish> allDishs, OnDishRecyclerListener onDishRecyclerListener, Context context)
{
this.onDishRecyclerListener = onDishRecyclerListener;
this.allDishs = allDishs;
this.context = context;
}

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

return new ViewHolder(context, view, onDishRecyclerListener);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
Dish Dish = allDishs.get(position);

holder.DishName.setText(Dish.getDishName());
}


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

public class ViewHolder extends RecyclerView.ViewHolder
{
private Context context;
TextView DishName; //plus a bunch of other Views I just removed for the sake of simplicity

OnDishRecyclerListener onDishRecyclerListener;

public ViewHolder(Context context, @NonNull View itemView, OnDishRecyclerListener onDishRecyclerListener)
{
super(itemView);
this.context = context;

DishName = itemView.findViewById(R.id.DishName);

this.onDishRecyclerListener = onDishRecyclerListener;

loadListeners(itemView);
}

private void loadListeners(@NonNull View v)
{
//Rename an Dish
DishName.setOnClickListener(view ->
{
PopupMenu popup = new PopupMenu(context, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.Dish_floating_menu, popup.getMenu());
popup.show();

popup.setOnMenuItemClickListener(item ->
{
switch (item.getItemId())
{
case R.id.menuDeleteDish:
onDishRecyclerListener.deleteDish(getAdapterPosition());

return true;
case R.id.menuRenameDish:
onDishRecyclerListener.renameDish(getAdapterPosition());

return true;
case R.id.menuDishProps:

return true;
default:
return false;
}
});
});
}
}
}

调用父回收器 View 的 fragment 的提取:

   @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_Recipe_panel, container, false);

recyclerRecipe = view.findViewById(R.id.RecipeRecyclerView);

SimpleItemAnimator simpleItemAnimator = (SimpleItemAnimator) recyclerRecipe.getItemAnimator();

if(simpleItemAnimator !=null)
{
simpleItemAnimator.setSupportsChangeAnimations(true);
}

RecipeAdapter = new RecipeRecyclerAdapter(getContext(), allRecipes);
RecipeAdapter.setOnRecipeRecyclerListener(this);

//recyclerRecipe.setHasFixedSize(true);
recyclerRecipe.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerRecipe.setAdapter(RecipeAdapter);

return view;
}

public void createRecipe(String RecipeName)
{
Recipe Recipe = new Recipe(RecipeName, getContext());
allRecipes.add(0,Recipe);
RecipeAdapter.notifyItemInserted(0);
}

@Override
public void deleteRecipe(int RecipePosition)
{
allRecipes.remove(RecipePosition);
RecipeAdapter.notifyItemRemoved(RecipePosition);
}


@Override
public void addDish(int RecipePosition)
{

allRecipes.get(RecipePosition).getDishs().add(new Dish(DishName));
RecipeAdapter.notifyItemChanged(RecipePosition);

}

@Override
public void deleteDish(int DishPosition, int RecipePosition)
{
Recipe Recipe = allRecipes.get(RecipePosition);
Dish Dish = Recipe.getDishs().get(DishPosition);

Dish.getTimer().destroyTimer();
Recipe.getDishs().remove(DishPosition);
RecipeAdapter.notifyItemChanged(RecipePosition);
}

最佳答案

我弄清楚了问题所在(经过几个小时之后)。我需要首先通知父回收商,然后按顺序通知子回收商。

//adding an item to the inner list
recipeAdapter.notifyItemChanged(recipePosition);
dishsRecycler.getAdapter().notifyItemInserted(recipe.getDishs().size()-1);

//deleting an inner list item
recipeAdapter.notifyItemChanged(recipePosition);
dishsRecycler.getAdapter().notifyItemRemoved()

然而,最大的罪魁祸首是所有内部回收器 View 都有一个共同的回收器池,因此从代码中删除了这一行

//REMOVED THESE LINES
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
holder.DishsRecycler.setRecycledViewPool(viewPool);

另外,我没有使用notifyDataSet(),因为由于某种原因会抛出NO_POSITION (-1)。

关于java - 从嵌套的 RecyclerView 中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62333024/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com