2016-06-29 10 views
2

Ich verwende eine ExpandableRecyclerView von Big Nerd Ranch wie die in dieser example. Das Problem ist immer dann, wenn ich versuche, meinem RecyclerView dynamisch einen weiteren Untereintrag hinzuzufügen. Der Speicherplatz dieses neuen Eintrags belegt den Platz eines bereits vorhandenen Eintrags, etwa so, als würde man diesen Eintrag vom Bildschirm löschen. Ich weiß nicht, wie es besser zu erklären, so habe ich die folgenden Screenshots angehängt:Hinzufügen eines untergeordneten Elements zu ExpandalbeRecyclerView

enter image description here

Das obige Bild zeigt die Liste vor Addinga neuen Unterpunkt. Als ich in der Schaltfläche Hinzufügen klicken, muß es das Kind Ansicht kollabieren und es dann wieder zu erweitern, so dass es wie unten angezeigt:

enter image description here

Die neue Artikel Ansicht den anderen Kind Blick nach unten drückt, um den Raum zu besetzen, dass einmal war für den Punkt 2. Und wenn ich versuche, ein neues untergeordnetes Element zum letzten geordneten Elemente hinzuzufügen gibt es diesen Fehler:

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) 

wenn ich den neuen Unterpunkt hinzuzufügen, füge ich ein neues Element in meinem Array Liste und rufen Sie dann die Methode notifyDataSetChanged().

Hier ist mein Adapter Code:

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); 
       } 
      } 

     }); 
    } 

Hier mein ParentViewHolder ist:

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); 
    } 
} 

Und hier ist mein 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 { 


       } 
      } 
     }); 
    } 
} 

Das ist, wie ich die ViewHolder bin Initalizing in mein Fragment:

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); 

Ich denke, das Problem ist mit dem Adapter, aber ich habe keine Ahnung, was los ist, ich freue mich über jede Hilfe.

Antwort

0

Ich wette, das Problem um diese Linie ist:

checkedState = new boolean[refeicoes.size()];

Arrays sind 0 basiert.

Eine Liste mit 5 Elementen erstellt ein Array mit 6 Einträgen. Wenn Sie also versuchen, das Array über die Länge zu iterieren, erhalten Sie ArrayIndexOutOfBoundsException, weil das Array einen Eintrag weniger enthält, als Sie erwarten.

+0

Was ist mit dem neuen Unterpunkt, der den Platz auf dem Bildschirm von Punkt 2 belegt? –

+0

Kann oder darf nicht verwandt sein. Es scheint, dass Sie ein Indizierungsproblem haben. – Emmanuel

+0

Aber "Refeicoes" ist die Liste der Elemente, nicht Sub-Elemente, also, wenn ich ein anderes Unterelement hinzufügen 'refeicoes.size()' ändert sich nicht. Oder tut es? –

Verwandte Themen