2017-07-08 48 views
4

我有一個活動,它與視圖分頁器打開一個片段。 當我在選項卡之間切換時出現此錯誤: 指定的子項已具有父項。您必須先調用子對象的父對象的removeView()。android:指定的孩子已經有父母。你必須調用removeView()

我認爲這個問題是從RecyclerView的頭,我發佈了一個新問題,它here

the view pager code is:

private void mViewPager(ViewPager viewPager) { 
     ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); 
     adapter.addFragment(new a_Frag(), getString("A")); 
     adapter.addFragment(new b_Frag(), getString("B")); 
     adapter.addFragment(new c_Frag(), getString("C")); 
     viewPager.setAdapter(adapter); 
    } 

the a_frag code as example:

public class a_Frag extends Fragment { 
    RecyclerView recyclerView; 

    public a_Frag() { 
    } 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 


    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     View view = inflater.inflate(R.layout.rv, container, false); 
     recyclerView = (RecyclerView) view.findViewById(R.id.rv); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
     recyclerView.setAdapter(new a_Adapter(getContext(), R.layout.group_header)); 


     return recyclerView; 
    } 

ExpandableRecyclerView code:

public class ExpandableRecyclerView extends RecyclerView { 
    public ExpandableRecyclerView(Context context) { 
     super(context, null); 
     initRecycler(); 
    } 

    public ExpandableRecyclerView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     initRecycler(); 
    } 

    public ExpandableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     initRecycler(); 
    } 

    private void initRecycler() { 
     setClipToPadding(false); 
     setItemAnimator(new DefaultItemAnimator()); 

    } 

    @Override 
    public Parcelable onSaveInstanceState() { 
     //begin boilerplate code that allows parent classes to save state 
     Parcelable superState = super.onSaveInstanceState(); 

     SavedState ss = new SavedState(superState); 
     //end 

     if (getAdapter() != null) 
      ss.stateToSave = ((Adapter) this.getAdapter()).getExpandedGroups(); 

     return ss; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     //begin boilerplate code so parent classes can restore state 
     if (!(state instanceof SavedState)) // if state is not instance of out SaveState just restore in reg way 
     { 
      super.onRestoreInstanceState(state); 
      return; 
     } 
     // else if cast him to SavedState 

     SavedState ss = (SavedState) state; 
     super.onRestoreInstanceState(ss.getSuperState()); 
     //end 

     if (getAdapter() != null) 
      ((Adapter) getAdapter()).setExpandedGroups(ss.stateToSave); 
    } 

    @Override 
    public void setAdapter(RecyclerView.Adapter adapter) { 
     if (!(adapter instanceof Adapter)) 
      throw new IllegalArgumentException("adapter has to be of type ExpandableRecyclerView.Adapter"); 
     super.setAdapter(adapter); 
    } 


    public interface OnChildItemClickedListener { 
     void onChildItemClicked(int group, int position); 
    } 

    static class SavedState implements Parcelable { 
     public static final SavedState EMPTY_STATE = new SavedState() { 
     }; 
     //required field that makes Parcelables from a Parcel 
     public static final Creator<SavedState> CREATOR = 
       new Creator<SavedState>() { 
        public SavedState createFromParcel(Parcel in) { 
         return new SavedState(in); 
        } 

        public SavedState[] newArray(int size) { 
         return new SavedState[size]; 
        } 
       }; 
     SparseBooleanArray stateToSave; 
     Parcelable superState; 

     SavedState() { 
      superState = null; 
     } 

     SavedState(Parcelable superState) { 
      this.superState = superState != EMPTY_STATE ? superState : null; 
     } 

     private SavedState(Parcel in) { 
      Parcelable superState = in.readParcelable(ExpandableRecyclerView.class.getClassLoader()); 
      this.superState = superState != null ? superState : EMPTY_STATE; 
      this.stateToSave = in.readSparseBooleanArray(); 
     } 

     @Override 
     public int describeContents() { 
      return 0; 
     } 

     @Override 
     public void writeToParcel(@NonNull Parcel out, int flags) { 
      out.writeParcelable(superState, flags); 
      out.writeSparseBooleanArray(this.stateToSave); 
     } 

     public Parcelable getSuperState() { 
      return superState; 
     } 
    } 

    public static abstract class Adapter<CVH extends ViewHolder, GVH extends ViewHolder, C, G> extends RecyclerView.Adapter<ViewHolder> { 

     private static final int TYPE_HEADER = 0; 
     SparseBooleanArray expanded = new SparseBooleanArray(); 
     private OnChildItemClickedListener onChildItemClickedListener; 

     public Adapter() { 
     } 

     boolean isExpanded(int group) { 
      return expanded.get(group); 
     } 

     SparseBooleanArray getExpandedGroups() { 
      return expanded; 
     } 

     public void setExpandedGroups(SparseBooleanArray expanded) { 
      this.expanded = expanded; 
     } 

     public void expand(int group) { 
      if (isExpanded(group)) 
       return; 

      // this lines of code calculate number of shown item in recycler view. also group is counting . 
      int position = 0; 
      for (int i = 0; i < group; i++) { 
       position++; 
       if (isExpanded(i)) 
        position += getChildItemCount(i); 
      } 
      position++; // this for percent group 

      notifyItemRangeInserted(position, getChildItemCount(group)); // notify recycler view for expanding 
      expanded.put(group, true); // save expanding in sparce array 
     } 

     public void collapse(int group) { 
      if (!isExpanded(group)) // if is not expanded . so nothing to collapse. 
       return; 

      int position = 0; 
      for (int i = 0; i < group; i++) { 
       position++; 
       if (isExpanded(i)) 
        position += getChildItemCount(i); // item 
      } 
      position++; 
      notifyItemRangeRemoved(position, getChildItemCount(group)); 
      expanded.put(group, false); 
     } 

     public abstract int getGroupItemCount(); 

     public abstract int getChildItemCount(int group); 

     @Override 
     public int getItemCount() { 
      int count = 0; 
      for (int i = 0; i <= getGroupItemCount(); i++) { 
       count += isExpanded(i) ? getChildItemCount(i) + 1 : 1; 
      } 
      return count; 
     } 

     public abstract G getGroupItem(int position); 

     public abstract C getChildItem(int group, int position); 

     public Object getItem(int i) { 
      int group = 0; 
      while (group <= getGroupItemCount()) { 
       if (i > 0 && !isExpanded(group)) { 
        i--; 
        group++; 
        continue; 
       } 
       if (i > 0 && isExpanded(group)) { 
        i--; 
        if (i < getChildItemCount(group)) 
         return getChildItem(group, i); 
        i -= getChildItemCount(group); 
        group++; 
        continue; 
       } 
       if (i == 0) 
        return getGroupItem(group); 
      } 
      throw new IndexOutOfBoundsException(); 
     } 

     @Override 
     public void onBindViewHolder(ViewHolder holder, int i) { 
      int group = 0; 
      while (group <= getGroupItemCount()) { 
       if (i > 0 && !isExpanded(group)) { 
        i--; 
        group++; 
        continue; 
       } 
       if (i > 0 && isExpanded(group)) { 
        i--; 
        if (i < getChildItemCount(group)) { 
         onBindChildViewHolder((CVH) holder, group, i); 
         return; 
        } 
        i -= getChildItemCount(group); 
        group++; 
        continue; 
       } 
       if (i == 0) { 
        onBindGroupViewHolder((GVH) holder, group); 
        return; 
       } 
      } 
      throw new IndexOutOfBoundsException(); 
     } 

     @Override 
     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      return viewType == TYPE_HEADER ? onCreateGroupViewHolder(parent) : onCreateChildViewHolder(parent, viewType); 
     } 

     protected abstract GVH onCreateGroupViewHolder(ViewGroup parent); 

     protected abstract CVH onCreateChildViewHolder(ViewGroup parent, int viewType); 

     public abstract int getChildItemViewType(int group, int position); 

     @Override 
     public int getItemViewType(int i) { 
      int group = 0; 
      while (group <= getGroupItemCount()) { 
       if (i > 0 && !isExpanded(group)) { 
        i--; 
        group++; 
        continue; 
       } 
       if (i > 0 && isExpanded(group)) { 
        i--; 
        if (i < getChildItemCount(group)) 
         return getChildItemViewType(group, i); 
        i -= getChildItemCount(group); 
        group++; 
        continue; 
       } 
       if (i == 0) 
        return TYPE_HEADER; 
      } 
      throw new IndexOutOfBoundsException(); 
     } 

     public void setOnChildItemClickedListener(OnChildItemClickedListener onItemClickedListener) { 
      this.onChildItemClickedListener = onItemClickedListener; 
     } 

     public void onBindChildViewHolder(CVH holder, final int group, final int position) { 
      holder.itemView.setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 
        if (Adapter.this.onChildItemClickedListener != null) { 
         Adapter.this.onChildItemClickedListener.onChildItemClicked(group, position); 
        } 

       } 
      }); 
     } 

     public void onBindGroupViewHolder(final GVH holder, final int group) { 
      if (holder instanceof GroupViewHolder) 
       ((GroupViewHolder) holder).setExpanded(isExpanded(group)); 

      holder.itemView.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        if (isExpanded(group)) { 
         collapse(group); 
         if (holder instanceof GroupViewHolder) 
          ((GroupViewHolder) holder).collapse(); 
        } else { 
         expand(group); 
         if (holder instanceof GroupViewHolder) 
          ((GroupViewHolder) holder).expand(); 
        } 
       } 
      }); 
     } 
    } 

    public static abstract class GroupViewHolder extends ViewHolder { 

     public GroupViewHolder(View itemView) { 
      super(itemView); 
     } 

     public abstract void expand(); 

     public abstract void collapse(); 

     public abstract boolean isExpanded(); 

     public abstract void setExpanded(boolean expanded); 
    } 

    public static class SimpleGroupViewHolder extends GroupViewHolder { 
     ImageView expandedIndicator; 
     TextView text; 
     private boolean expanded; 

     public SimpleGroupViewHolder(Context context) { 
      super(View.inflate(context, R.layout.group_header, null)); 

      itemView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 
      expandedIndicator = (ImageView) itemView.findViewById(R.id.carbon_groupExpandedIndicator); 
      text = (TextView) itemView.findViewById(R.id.carbon_groupText); 
     } 

     public SimpleGroupViewHolder(Context context, int layout) { 
      super(View.inflate(context, layout, null)); 

      itemView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 
      expandedIndicator = (ImageView) itemView.findViewById(R.id.carbon_groupExpandedIndicator); 
      text = (TextView) itemView.findViewById(R.id.carbon_groupText); 
     } 

     public void expand() { 
      ValueAnimator animator = ValueAnimator.ofFloat(0, 1); 
      animator.setInterpolator(new DecelerateInterpolator()); 
      animator.setDuration(200); 
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue())); 
        expandedIndicator.postInvalidate(); 
       } 
      }); 
      animator.start(); 
      expanded = true; 
     } 

     public void collapse() { 
      ValueAnimator animator = ValueAnimator.ofFloat(1, 0); 
      animator.setInterpolator(new DecelerateInterpolator()); 
      animator.setDuration(200); 
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue())); 
        expandedIndicator.postInvalidate(); 
       } 
      }); 
      animator.start(); 
      expanded = false; 
     } 

     @Override 
     public boolean isExpanded() { 
      return expanded; 
     } 

     public void setExpanded(boolean expanded) { 
      ViewHelper.setRotation(expandedIndicator, expanded ? 180 : 0); 
      this.expanded = expanded; 
     } 

     public String getText() { 
      return text.getText().toString(); 
     } 

     public void setText(String t) { 
      text.setText(t); 
     } 
    } 

} 

的適配器除了數據以外,所以我會放一個例子mple:

Adapter code example:

public class Adapter extends ExpandableRecyclerView.Adapter<Adapter.ChildViewHolder, Adapter.GroupViewHolder, String, String> { 

    private DatabaseHelper db; 
    private ArrayList List; 
    private int layout; 


    public Adapter(Context c, int resource) { 
     layout = resource; 
     db = new DatabaseHelper(c); 
     List = db.getRecords();//returns list 
    } 

    @Override 
    public int getGroupItemCount() { 
     return List.size() - 1; 
    } 

    @Override 
    public int getChildItemCount(int i) { 
     return 1; 
    } 

    @Override 
    public String getGroupItem(int i) { 
     return null; 
    } 

    @Override 
    public String getChildItem(int group, int child) { 
     return null; 
    } 

    @Override 
    protected GroupViewHolder onCreateGroupViewHolder(ViewGroup parent) { 
     return new GroupViewHolder(parent.getContext(), layout); 
    } 

    @Override 
    protected ChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) { 
     View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.group_item, parent, false); 
     return new ChildViewHolder(rootView); 
    } 

    @Override 
    public void onBindGroupViewHolder(GroupViewHolder holder, int group) { 
     super.onBindGroupViewHolder(holder, group); 

     holder.setText1("A"); 


     holder.setText2("B"); 
    } 

    @Override 
    public void onBindChildViewHolder(ChildViewHolder holder, int group, int position) { 
     super.onBindChildViewHolder(holder, group, position); 

     holder.t1.setText("t1"); 


     holder.t2.setText("t2"); 


     holder.t3.setText("t3"); 


        holder.t4.setText("t4"); 

    } 

    @Override 
    public int getChildItemViewType(int i, int i1) { 
     return 1; 
    } 

    static class GroupViewHolder extends ExpandableRecyclerView.GroupViewHolder { 
     ImageView expandedIndicator; 
     TextView text1; 
     TextView text2; 
     private boolean expanded; 


     GroupViewHolder(Context context, int layout) { 
      super(View.inflate(context, layout, null)); 

      itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 
      expandedIndicator = (ImageView) itemView.findViewById(R.id.groupExpandedIndicator); 
      text1 = (TextView) itemView.findViewById(R.id.text1); 
      text2 = (TextView) itemView.findViewById(R.id.text2); 
     } 

     public void expand() { 
      ValueAnimator animator = ValueAnimator.ofFloat(0, 1); 
      animator.setInterpolator(new DecelerateInterpolator()); 
      animator.setDuration(200); 
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue())); 
        expandedIndicator.postInvalidate(); 
       } 
      }); 
      animator.start(); 
      expanded = true; 
     } 

     public void collapse() { 
      ValueAnimator animator = ValueAnimator.ofFloat(1, 0); 
      animator.setInterpolator(new DecelerateInterpolator()); 
      animator.setDuration(200); 
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue())); 
        expandedIndicator.postInvalidate(); 
       } 
      }); 
      animator.start(); 
      expanded = false; 
     } 

     @Override 
     public boolean isExpanded() { 
      return expanded; 
     } 

     public void setExpanded(boolean expanded) { 
      ViewHelper.setRotation(expandedIndicator, expanded ? 180 : 0); 
      this.expanded = expanded; 
     } 

     void setText1(String t) { 
      text1.setText(t); 
     } 


     void setText2(String t) { 
      text2.setText(t); 
     } 
    } 

    class ChildViewHolder extends RecyclerView.ViewHolder { 
     private TextView t1; 
     private TextView t2; 
     private TextView t3; 
     private TextView t4; 


     ChildViewHolder(View itemView) { 
      super(itemView); 
      t1 = (TextView) itemView.findViewById(R.id.tv1); 
      t2 = (TextView) itemView.findViewById(R.id.tv2); 
      t3 = (TextView) itemView.findViewById(R.id.tv3); 
      t4 = (TextView) itemView.findViewById(R.id.tv4); 
     } 
    } 
} 

group_header.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:clickable="true"> 

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:card_view="http://schemas.android.com/apk/res-auto" 
     android:id="@+id/Card1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:layout_marginLeft="7dp" 
     android:layout_marginRight="7dp" 
     android:layout_marginTop="10dp"   
     card_view:cardCornerRadius="10dp" 
     card_view:cardElevation="5dp"> 

     <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="wrap_content" 
      android:gravity="right" 
      android:orientation="horizontal"> 

      <TextView 
       android:id="@+id/text1" 
       style="@style/MyLargeTextAppearance" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:gravity="center" 
       android:padding="16dp" 
       android:textColor="@color/highlight" 
       android:textStyle="bold" /> 


     </LinearLayout> 
    </android.support.v7.widget.CardView> 

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:card_view="http://schemas.android.com/apk/res-auto" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/Card1" 
     android:layout_gravity="center" 
     android:layout_marginLeft="7dp" 
     android:layout_marginRight="7dp" 
     android:layout_marginTop="1dp" 
     card_view:cardCornerRadius="10dp" 
     card_view:cardElevation="5dp"> 

     <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="wrap_content" 
      android:gravity="right" 
      android:orientation="horizontal"> 

      <TextView 
       android:id="@+id/text2" 
       style="@style/MyLargeTextAppearance" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:gravity="center" 
       android:padding="16dp" 
       android:textColor="@color/highlight" 
       android:textStyle="bold" /> 

      <ImageView 
       android:id="@+id/groupExpandedIndicator" 
       android:layout_width="24dp" 
       android:layout_height="24dp" 
       android:layout_gravity="center_vertical" 
       android:layout_marginEnd="16dp" 
       android:layout_marginRight="16dp" 
       app:srcCompat="@drawable/ic_expand_more" /> 
     </LinearLayout> 
    </android.support.v7.widget.CardView> 
</RelativeLayout> 

group_item.xml:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/card" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:layout_marginLeft="7dp" 
    android:layout_marginRight="7dp" 
    android:layout_marginTop="10dp" 
    card_view:cardCornerRadius="10dp" 
    card_view:cardElevation="5dp"> 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@color/materialGray" 
     android:orientation="vertical" 
     android:padding="@dimen/activity_horizontal_margin"> 


     <TextView 
      android:id="@+id/t1" 
      style="@style/MyLargeTextAppearance" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:text="TextView" /> 

     <View 
      android:layout_width="match_parent" 
      android:layout_height="1dp" 
      android:background="@color/separatorViewBackground" /> 

     <TextView 
      android:id="@+id/t2" 
      style="@style/MyLargeTextAppearance" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:text="TextView" /> 

     <View 
      android:layout_width="match_parent" 
      android:layout_height="1dp" 
      android:background="@color/separatorViewBackground" /> 

     <TextView 
      android:id="@+id/t3" 
      style="@style/MyLargeTextAppearance" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:text="TextView"/> 

     <View 
      android:layout_width="match_parent" 
      android:layout_height="1dp" 
      android:background="@color/separatorViewBackground" /> 

     <TextView 
      android:id="@+id/t4" 
      style="@style/MyLargeTextAppearance" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:text="TextView" /> 

    </LinearLayout> 
</android.support.v7.widget.CardView> 
+0

沒有取得任何進展,到目前爲止,但我覺得在GroupViewHolder – Zacktamondo

+0

問題存在你H大聲說「指定的孩子已經有父母」的例外? – Rasmusob

+0

@Rasmusob不,我不 – Zacktamondo

回答

4

嘗試更改爲:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    View view = inflater.inflate(R.layout.rv, container, false); 
    recyclerView = (RecyclerView) view.findViewById(R.id.rv); 
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
    recyclerView.setAdapter(new a_Adapter(getContext(), R.layout.group_header)); 
    if (recyclerView != null) { 
     return recyclerView; 
    } 

    return null; 
} 
+0

這對我沒有意義。爲什麼你會否認擁有實際「RecyclerView」的視圖? –

+0

@IulianPopescu我們不排除這種觀點。如果存在,我們將返回相同的觀點。雖然錯誤不限於這種特殊情況。它也可能出現在其他各種場景中。這是其中之一。 –

相關問題