Sunday, September 24, 2017

android:The specified child already has a parent. You must call removeView()

Leave a Comment

I have an activity which opens a fragment with view pager. when I change between the tabs I get this error: The specified child already has a parent. You must call removeView() on the child's parent first.

I think is the problem is from the header of the RecyclerView and I posted a new question about it 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);         }     }  } 

the adapters are the same except for the data so I will put one example:

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> 

1 Answers

Answers 1

Try changing to:

@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; } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment