2014-10-27 19 views
47

Tôi đang cố tạo một listView với một Adapter RecyvlerView mới. Tôi đã làm theo hướng dẫn chính xác về tài nguyên dành cho nhà phát triển Android. Nhưng điều này mang lại cho tôi một lỗi lạ: Trẻ được chỉ định đã có cha/mẹ. Bạn phải gọi removeView() trên phụ huynh của đứa trẻ trước. Tôi có SDK mới nhất. Tôi cũng định nghĩa các phụ thuộc trong gradle.Lỗi khi sử dụng RecyclerView: Trẻ được chỉ định đã có một phụ huynh

MyActivity (Hoạt động chính):

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 (bố trí cho các hạng mục danh sách):

<?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 (chính hoạt động):

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

Và đây là sản phẩm 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) 

Vui lòng giúp tôi sửa chữa vấn đề này. Cảm ơn :)

+9

Sử dụng inflater.inflate (R. layout.my_text_view, parent, false); –

+4

dòng Xem v = inflater.inflate (R.layout.my_text_view, parent, true); đang gắn khung nhìn vào phụ huynh, sử dụng View v = inflater.inflate (R.layout.my_text_view, parent, false); thay vì – panini

+0

@panini bạn là nhà ảo thuật. Tôi đã thử điều đó trước rất nhiều lần. Nhưng bây giờ tôi chỉ làm việc thôi. Cảm ơn rất nhiều phản hồi nhanh chóng – zaingz

Trả lời

100

khi lạm dụng bạn không nên đính kèm chế độ xem vào cha mẹ của nó. bạn đã viết:

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

mà nên là:

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

Ngoài ra, bạn không thể sử dụng View v = inflater.inflate (R.layout.my_text_view, parent); bởi vì nó mặc định là đúng. –

+0

Nói chung lý do tại sao Chế độ xem mà chúng tôi chuyển đến ViewHolder không nên có cha mẹ? Làm thế nào để bộ nhớ đệm chính xác xảy ra ở đây? – router

+0

vì nó sẽ được thêm vào recyclerview và quan điểm chỉ có thể có một phụ huynh tại một thời điểm – 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 đây là mẹ của TextView của mình với id item_title. Sau đó, khi RecyclerView đang cố gắng thêm TextView có cha mẹ nó ném ngoại lệ.

Hãy thử mã này:

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() ** là không cần thiết! Chỉ cần chuyển ** v ** vào trong hàm tạo ViewHolder thay vì ** view **. Và gọi * findViewById() * bên trong hàm tạo ViewHolder. – goRGon

+0

tăng lượt xem bằng cách sử dụng 'parent.getContext()' đã giải quyết nó cho tôi. cảm ơn! – Eric

+0

Giải thích tốt: "RelativeLayout đây là phụ huynh của TextView của bạn với id item_title. Sau đó, khi RecyclerView đang cố gắng thêm TextView có cha mẹ nó ném ngoại lệ." – Khawar

1

Nó xảy ra quá nếu bạn di chuyển thật nhanh recyclerview của bạn. trường hợp tôi bị chèn/di chuyển/... mục có DiffUtils và gọi TransitionManager.beginDelayedTransition(view) trên layout gốc (và như vậy, recyclerview) ở đâu đó trong mã của tôi trước khi kết thúc hoạt hình recyclerview

Các vấn đề liên quan