2014-10-27 4 views
47

Ich versuche, ein ListView mit einem neuen RecyvlerView Adapter zu erstellen. Ich habe die genaue Anleitung auf Android-Entwickler-Ressourcen gefolgt. Aber das gibt mir einen seltsamen Fehler: Das angegebene Kind hat bereits einen Elternteil. Sie müssen zuerst removeView() für das übergeordnete Element des Kindes aufrufen. Ich habe das neueste SDK. Ich definiere auch Abhängigkeiten in Gradle.Fehler bei der Verwendung des RecyclerView: Das angegebene Kind hat bereits ein Elternteil

MyActivity (Main Activity):

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 (Layout für Listenelemente):

<?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 (Haupt Aktivität):

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

Und hier ist der logcat Ausgang:

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) 

Bitte helfen Sie mir dieses Problem zu beheben. Danke :)

+9

Verwenden inflater.inflate (R aufrufen. layout.my_text_view, parent, false); –

+4

die Zeile View v = inflater.inflate (R.layout.my_text_view, parent, true); hängt die Ansicht an den Eltern an, verwenden Sie View v = inflater.inflate (R.layout.my_text_view, parent, false); stattdessen – panini

+0

@panini du bist Zauberer. Das habe ich schon so oft probiert. Aber ich arbeite jetzt einfach. Vielen Dank für die schnelle Antwort – zaingz

Antwort

100

Wenn Sie aufblasen, sollten Sie die Ansicht nicht an ihre Eltern anhängen. Sie schrieb:

View v = inflater.inflate(R.layout.my_text_view, parent, false); 
+12

Sie können auch View v = inflater.inflate nicht verwenden (R.layout.my_text_view, parent); weil es standardmäßig auf true gesetzt ist. –

+0

Warum sollte die View, die wir an einen ViewHolder übergeben, im Allgemeinen nicht übergeordnete Elemente haben? Wie genau passiert hier das Caching? – router

+0

, da es zur Recycleransicht hinzugefügt wird und Ansichten nur jeweils einen Elternteil haben können – hister

18
<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 dies Eltern Ihrer Textview mit id item_title:

View v = inflater.inflate(R.layout.my_text_view, parent, true); 

, die sein sollte. Dann, wenn RecyclerView versucht, TextView, die Eltern hat es Wurf Ausnahme hinzufügen.

Versuchen Sie diesen 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; 
    } 
+20

** v.removeView() ** wird nicht benötigt! Übergeben Sie ** v ** selbst an den ViewHolder-Konstruktor anstatt an ** view **. Und rufen Sie * findViewById() * im ViewHolder-Konstruktor auf. – goRGon

+0

das Aufblasen der Ansicht mit 'parent.getContext()' löste es für mich. Vielen Dank! – Eric

+0

Gute Erklärung: "RelativeLayout das ist übergeordnetes von Ihrem TextView mit ID item_title. Wenn RecyclerView versucht, TextView hinzuzufügen, das über die Ausnahme von parent it throw verfügt." – Khawar

1

Es passiert auch, wenn Sie wirklich schnell Ihre recyclerview blättern. Mein Fall wurde das Einfügen/Verschieben/... Artikel mit Diffutils und TransitionManager.beginDelayedTransition(view) auf dem Root-Layout (und so die recyclerview) irgendwo in meinem Code vor dem Ende der recyclerview Animationen

Verwandte Themen