我正在使用Big Nerd Ranch的ExpandableRecyclerView,就像这个example中的那个。问题是每当我尝试动态地向我的RecyclerView添加另一个子项时,这个新项目的空间占据了已经存在的项目的空间,有点像从屏幕上删除这个项目。我不知道如何更好地解释它,所以我附上了以下截图:
上图显示了添加新子项之前的列表。当我单击添加按钮时,我需要折叠子视图,然后再次展开它,使其显示如下:
New Item视图按下其他子视图,占用Item 2的空间。如果我尝试将新子项添加到最后一个父项,则会出现此错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dietando.gabriel.dietando, PID: 4037
java.lang.IndexOutOfBoundsException: Invalid index 8, size is 8
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.remove(ArrayList.java:403)
at com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter.expandParent(ExpandableRecyclerAdapter.java:319)
at com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter.onParentItemClickListener(ExpandableRecyclerAdapter.java:252)
at com.bignerdranch.expandablerecyclerview.ViewHolder.ParentViewHolder.onClick(ParentViewHolder.java:200)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
当我添加新子项时,我将新项添加到我的数组列表中,然后调用方法notifyDataSetChanged()
。
这是我的适配器代码:
public class MealExpandableAdapter extends ExpandableRecyclerAdapter<MealParentViewHolder, MealChildViewHolder>
{
private Context context;
private List<ParentObject> refeicoes;
private boolean[] checkedState;
private LayoutInflater mInflater;
private MealExpandableAdapter.MealChildViewHolderListener onChildCheckChangedListener;
public interface MealChildViewHolderListener
{
public void onCheckChange(int mealNumber, Food food, boolean selected);
}
public MealExpandableAdapter(Context context, List<ParentObject> refeicoes)
{
super(context, refeicoes);
this.context = context;
this.refeicoes = refeicoes;
mInflater = LayoutInflater.from(context);
checkedState = new boolean[refeicoes.size()];
for(int i = 0; i < checkedState.length; ++i)
checkedState[i] = false;
}
protected void setOnChilCheckedChangedListener(MealExpandableAdapter.MealChildViewHolderListener onChildCheckChangedListener)
{
this.onChildCheckChangedListener = onChildCheckChangedListener;
}
@Override
public MealParentViewHolder onCreateParentViewHolder(ViewGroup viewGroup)
{
View view = mInflater.inflate(R.layout.adapter_refeicao, viewGroup, false);
return new MealParentViewHolder(view);
}
@Override
public MealChildViewHolder onCreateChildViewHolder(ViewGroup viewGroup)
{
View view = mInflater.inflate(R.layout.adapter_refeicao_child, viewGroup, false);
return new MealChildViewHolder(view);
}
@Override
public void onBindParentViewHolder(MealParentViewHolder mealParentViewHolder, final int mealNumber, Object parentObject)
{
final Meal meal = (Meal) parentObject;
mealParentViewHolder.mMealParentTextView.setText(meal.getNome());
mealParentViewHolder.mMealParentImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("Teste", "img btn click");
meal.addFood(0, new Food("New item", 30, 30, 30));
//notify();
//notifyItemInserted(mealNumber);
notifyDataSetChanged();
notifyItemChanged(mealNumber);
}
});
}
@Override
public void onBindChildViewHolder(final MealChildViewHolder mealChildViewHolder, final int mealNumber, Object childObject)
{
//final Meal meal = (Meal) refeicoes.get(mealNumber);
final Food food = (Food) childObject;
mealChildViewHolder.mMealChildTextView.setText(food.getName());
mealChildViewHolder.mMealChildCheckBox.setChecked(food.isChecked());
mealChildViewHolder.mMealChildCheckBox.setChecked(food.isChecked());
mealChildViewHolder.mMealChildCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
Log.i("Teste", "checked");
food.checkFood();
onChildCheckChangedListener.onCheckChange(mealNumber, food, true);
} else {
Log.i("Teste", "unchecked");
food.checkFood();
onChildCheckChangedListener.onCheckChange(mealNumber, food, false);
}
}
});
}
这是我的ParentViewHolder:
public class MealParentViewHolder extends ParentViewHolder
{
public TextView mMealParentTextView;
public ImageButton mMealParentImageButton;
public CheckBox mMealParentCheckBox;
public MealParentViewHolder(View itemView)
{
super(itemView);
mMealParentTextView = (TextView) itemView.findViewById(R.id.tTitle);
mMealParentImageButton = (ImageButton) itemView.findViewById(R.id.imgBtnParent);
mMealParentCheckBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
}
这是我的ChildViewHolder
public class MealChildViewHolder extends ChildViewHolder
{
public TextView mMealChildTextView;
public CheckBox mMealChildCheckBox;
public MealChildViewHolder(View itemView)
{
super(itemView);
mMealChildTextView = (TextView) itemView.findViewById(R.id.txtFragMeal);
mMealChildCheckBox = (CheckBox) itemView.findViewById(R.id.checkBoxFragMeal);
mMealChildCheckBox.setChecked(false);
mMealChildCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
Log.i("Teste", "checked");
} else {
}
}
});
}
}
这就是我在片段中正在使用ViewHolder的方式:
RecyclerView recyclerView = (RecyclerView) getView().findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
meals = user.getDiet().getMeals();
MealExpandableAdapter mMealExpandableAdapter = new MealExpandableAdapter(getActivity(), meals);
mMealExpandableAdapter.setOnChilCheckedChangedListener(onChildCheckChangedListener());
// mCrimeExpandableAdapter.setCustomParentAnimationViewId(R.id.parent_list_item_expand_arrow);
mMealExpandableAdapter.setParentClickableViewAnimationDefaultDuration();
mMealExpandableAdapter.setParentAndIconExpandOnClick(true);
recyclerView.setAdapter(mMealExpandableAdapter);
我认为问题在于适配器,但我不知道出了什么问题,我很感激任何帮助。
答案 0 :(得分:0)
我打赌这个问题就在这条线上:
checkedState = new boolean[refeicoes.size()];
数组是基于0的。
包含5个元素的列表将创建一个包含6个条目的数组。因此,当您尝试在整个长度上迭代数组时,您将获得ArrayIndexOutOfBoundsException
,因为该数组包含的条目少于您预期的条目。