J'essaie de créer un listView avec un nouvel adaptateur RecyvlerView. J'ai suivi le guide exact présent sur les ressources pour développeurs Android. Mais cela me donne une étrange erreur: L'enfant spécifié a déjà un parent. Vous devez d'abord appeler removeView () sur le parent de l'enfant. J'ai le dernier SDK. Je définis également les dépendances dans gradle.
MyActivity (Activité principale):
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
// specify an adapter (see also next example)
mAdapter = new MyAdapter(new String[]{"Zain", "Nadeem"});
mRecyclerView.setAdapter(mAdapter);
}
}
MyAdapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.my_text_view, parent, true);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.item_title);
}
}
}
my_text_view.xml (présentation des éléments de liste):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="80dp"
>
<!-- title -->
<TextView
Android:id="@+id/item_title"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:textColor="@Android:color/darker_gray"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:layout_marginTop="8dp"
Android:textSize="22dp" />
</RelativeLayout>
activity_my.xml (activité principale):
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_height="fill_parent"
Android:layout_width="fill_parent"
Android:background="@Android:color/holo_orange_light"
>
<!-- A CardView that contains a TextView -->
<Android.support.v7.widget.RecyclerView
Android:id="@+id/my_recycler_view"
Android:scrollbars="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MyActivity"/>
</LinearLayout>
Et voici la sortie logcat:
10-28 01:20:30.287 22729-22729/osman.zaingz.com.Lollipop E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: osman.zaingz.com.Lollipop, PID: 22729
Java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at Android.view.ViewGroup.addViewInner(ViewGroup.Java:3562)
at Android.view.ViewGroup.addView(ViewGroup.Java:3415)
at Android.view.ViewGroup.addView(ViewGroup.Java:3360)
at Android.support.v7.widget.RecyclerView$4.addView(RecyclerView.Java:322)
at Android.support.v7.widget.ChildHelper.addView(ChildHelper.Java:79)
at Android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.Java:4845)
at Android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.Java:4803)
at Android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.Java:4791)
at Android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.Java:1316)
at Android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.Java:1265)
at Android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.Java:522)
at Android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.Java:1918)
at Android.support.v7.widget.RecyclerView.onLayout(RecyclerView.Java:2155)
at Android.view.View.layout(View.Java:14817)
at Android.view.ViewGroup.layout(ViewGroup.Java:4631)
at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1671)
at Android.widget.LinearLayout.layoutHorizontal(LinearLayout.Java:1660)
at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1436)
at Android.view.View.layout(View.Java:14817)
at Android.view.ViewGroup.layout(ViewGroup.Java:4631)
at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
at Android.view.View.layout(View.Java:14817)
at Android.view.ViewGroup.layout(ViewGroup.Java:4631)
at com.Android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.Java:374)
at Android.view.View.layout(View.Java:14817)
at Android.view.ViewGroup.layout(ViewGroup.Java:4631)
at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
at Android.view.View.layout(View.Java:14817)
at Android.view.ViewGroup.layout(ViewGroup.Java:4631)
at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:1983)
at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1740)
at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:996)
at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:5600)
at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:761)
at Android.view.Choreographer.doCallbacks(Choreographer.Java:574)
at Android.view.Choreographer.doFrame(Choreographer.Java:544)
at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:747)
at Android.os.Handler.handleCallback(Handler.Java:733)
at Android.os.Handler.dispatchMessage(Handler.Java:95)
at Android.os.Looper.loop(Looper.Java:136)
at Android.app.ActivityThread.main(ActivityThread.Java:5001)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:785)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:601)
lors du gonflage, vous ne devez pas attacher la vue à son parent. tu as écrit:
View v = inflater.inflate(R.layout.my_text_view, parent, true);
qui devrait être:
View v = inflater.inflate(R.layout.my_text_view, parent, false);
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="80dp">
<TextView
Android:id="@+id/item_title"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:textColor="@Android:color/darker_gray"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:layout_marginTop="8dp"
Android:textSize="22dp" />
</RelativeLayout>
RelativeLayout c'est le parent de votre TextView avec l'ID item_title
. Ensuite, lorsque RecyclerView essaie d'ajouter TextView qui a un parent, il lance une exception.
Essayez ce code:
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
Log.d(TAG, "onCreateViewHolder");
RelativeLayout v = (RelativeLayout)LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
View view = v.findViewById(R.id.text1);
v.removeView(view);
ViewHolder vh = new ViewHolder(view);
return vh;
}
Cela se produit également si vous faites défiler très rapidement votre aperçu du recyclage. Mon cas insérait/déplaçait/... des éléments avec DiffUtils et appelait TransitionManager.beginDelayedTransition(view)
sur la disposition racine (et donc, la vue de recyclage) quelque part dans mon code avant la fin des animations de vue de recyclage
Je l'ai résolu en supprimant `TransitionManager.beginDelayedTransition ();
C'est peut-être un peu tard, mais j'ai eu le même problème (recyclerview-v7: 26.1.0) et la raison en est que j'ai essayé de faire défiler (par la méthode scrollToPosition ()) la liste dans une position qui était actuellement visible. Après avoir ajouté une vérification de position avant le défilement (défilement uniquement dans la position invisible), le problème a été résolu