2014-11-04 19 views
21

Tôi cố gắng sử dụng RecyclerView với RecyclerView.Adapter nhưng đây là điều gì đó sai. Tôi gửi mã của tôi dưới đây:java.lang.NullPointerException tại android.support.v7.widget.RecyclerView.onMeasure

Layout:

<android.support.v7.widget.RecyclerView 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/topic_view" 
    android:scrollbars="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

topic_tile.xml:

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="@dimen/tile_height"> 

    <com.makeramen.RoundedImageView 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:id="@+id/avatar" 
     android:padding="16dp" 
     app:riv_corner_radius="72dp" 
     android:layout_height="72dp" 
     android:layout_width="72dp" 
     /> 

    <LinearLayout 
     android:id="@+id/text_layout" 
     android:orientation="vertical" 
     android:paddingTop="@dimen/text_padding_top_and_bottom" 
     android:paddingBottom="@dimen/text_padding_top_and_bottom" 
     android:paddingRight="16dp" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
     <TextView 
      android:id="@+id/title" 
      android:textSize="@dimen/primary_font" 
      android:paddingLeft="@dimen/text_padding_left" 
      android:textColor="#000000" 
      android:text="Title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"/> 
     <TextView 
      android:id="@+id/author" 
      android:textSize="@dimen/secondary_font" 
      android:paddingLeft="@dimen/text_padding_left" 
      android:text="author" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"/> 
    </LinearLayout> 
</RelativeLayout> 

Đây là trong onCreate()

public class TitleListActivity extends ActionBarActivity { 

    private RecyclerView topic_view; 
    private RecyclerView.LayoutManager mLayoutManager; 
    private TitlelistAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_title_list); 

     ..... 

     topic_view = (RecyclerView)findViewById(R.id.topic_view); 
     adapter = new TitlelistAdapter(topicList); 

     topic_view.setHasFixedSize(true); 
     mLayoutManager = new LinearLayoutManager(TitleListActivity.this); 
     topic_view.setLayoutManager(mLayoutManager); 
     topic_view.setItemAnimator(new DefaultItemAnimator()); 

     topic_view.setAdapter(adapter); 

Adapter:

public class TitlelistAdapter extends RecyclerView.Adapter<TitlelistAdapter.ViewHolder> { 

    public List<Topic> topicList; 

    public static class ViewHolder extends RecyclerView.ViewHolder{ 

     TextView title; 
     TextView author; 
     RoundedImageView avatar; 

     public ViewHolder(View itemView) { 
      super(itemView); 

      title = (TextView)itemView.findViewById(R.id.title); 
      author = (TextView)itemView.findViewById(R.id.author); 
      avatar = (RoundedImageView)itemView.findViewById(R.id.avatar); 
     } 
    } 

    public TitlelistAdapter(List<Topic> topicList){ 
     this.topicList = topicList; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 

     View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.topic_tile,viewGroup,false); 
     return new ViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder viewHolder, int i) { 
     viewHolder.title.setText(topicList.get(i).title); 
     viewHolder.author.setText(topicList.get(i).member.username); 
    } 

    @Override 
    public long getItemId(int position) { 
     return super.getItemId(position); 
    } 

    @Override 
    public int getItemCount() { 
     return topicList.size(); 
    } 
} 

Đây là ngoại lệ:

java.lang.NullPointerException 
     at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:1694) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291) 
     at android.view.View.measure(View.java:16497) 
     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1912) 
     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1109) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1291) 
     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.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
     at dalvik.system.NativeStart.main(Native Method) 

Có điều gì đó tôi không init hoặc một cái gì đó tôi nên viết nhiều hơn?

Trả lời

17

xml của bạn cho thấy rằng bạn có hai không gian tên android mà thực sự sẽ cung cấp cho bạn một lỗi vì trong android bạn được phép sử dụng không gian tên chỉ một lần. Xóa linearLayout khỏi bố cục chính của bạn vì nó có vẻ không cần thiết. Kiểm tra bố trí tùy chỉnh Row của bạn tức là topic_tile cũng cho bất kỳ lỗi tương tự

<android.support.v7.widget.RecyclerView 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/topic_view" 
    android:scrollbars="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

EDIT:

trong onCreate()

private RecyclerView.LayoutManager mLayoutManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     . 
     . 
     . 
     mLayoutManager = new LinearLayoutManager(this); 
     recycleView.setLayoutManager(mLayoutManager); 
    } 
+0

đây là nhầm lẫn nhưng sau khi đã khắc phục, ứng dụng vẫn bị lỗi với ngoại lệ này – Randy

+0

bạn cũng có thể đăng tệp bố cục 'topic_tile' của mình không? – Android2390

+0

Ngoài ra, nếu bạn xem câu trả lời này tại: http://stackoverflow.com/questions/24458538/using-cardview-and-recyclerview-in-my-layout-files-throws-an-exception, nó gợi ý rằng bạn nên tạo một biến thành viên cho lớp 'LayoutManager' thay vì' setLayoutManager (new LinearLayoutManager (TitleListActivity.this)); ' – Android2390

11

Nếu bạn đang phải đối mặt với vấn đề tương tự cho RecycleView bên trong một mảnh, cố gắng sử dụng mã này.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View rootView = inflater.inflate(R.layout.fragment_latest, container, false); 

    // get recycler view 
    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.novel_item_list); 

    //mRecyclerView.setHasFixedSize(true); 

    // use a linear layout manager 
    mLayoutManager = new LinearLayoutManager(getActivity()); 
    mRecyclerView.setLayoutManager(mLayoutManager); 


    String[] abc = {"hi","how are you","this is recycler"}; 
    // specify an adapter (see also next example) 
    mAdapter = new RecyclerViewAdapter(abc); 
    mRecyclerView.setAdapter(mAdapter); 
    return rootView; 
} 
+1

THANK YOU rất nhiều.Tôi cũng đang sử dụng 'Fragment's, như tôi nghi ngờ các poster câu hỏi ban đầu được, và điều này phải là lý do cho' NullPointerException' này Tôi đã có mã mà bạn đã đăng (instantiating 'RecyclerView',' LinearLayoutManager', các lệnh gọi 'setLayoutManager' và' setAdapter', vv) trong phương thức 'onCreate()' của Fragment thay vì phương thức 'onCreateView'. – clamum

1

Bạn phải thiết lập LayoutManager cho RecycleView:

Hiện nay, Android hỗ trợ 3 loại bố cục.

Nếu bạn muốn nó có vẻ như bình thường ListView, hãy sử dụng LinearLayoutManager.

Nếu bạn muốn có vẻ như lưới điện, hãy sử dụng GridLayoutManager.

Nếu bạn muốn nó có vẻ loạng choạng, sử dụng StaggeredGridLayoutManager

Constructors 3 loại bố trí trên

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 

GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2); 

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.HORIZONTAL); 

Sau đó, bạn thiết lập LinearLayout để RecycleView (trong trường hợp này tôi đã sử dụng LinearLayoutManager

recyclerView = (RecyclerView) view.findViewById(R.id.saved_recycle_view); 
recyclerView.setHasFixedSize(true); 
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); 
recyclerView.setLayoutManager(linearLayoutManager); 

Dù sao, hãy sử dụng OttoBus Thư viện để truyền các sự kiện từ A dapter vào Hoạt động/Phân đoạn có chứa RecycleView. Chúc may mắn!

+2

Bạn có thể vui lòng [sửa] câu trả lời của bạn để giải thích tại sao mã này trả lời câu hỏi? Câu trả lời chỉ có mã được [nản lòng] (http : //meta.stackexchange.com/questions/148272), bởi vì họ không dạy giải pháp. – DavidPostill

+0

Cảm ơn! Tôi đã làm nó. –

21

Tôi gặp lỗi này khi RecyclerView của tôi không có LayoutManager.Thêm mã này khắc phục được vấn đề:

recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext())); 
+0

Lý do là gì? –

+0

cảm ơn, tôi quên mất Trình quản lý – user25

0

Đối với bất cứ ai cố gắng sử dụng một ViewPager cho tab, và bên trong các tab của họ có một RecyclerView mà gây ra lỗi này điên, tôi đề nghị hoãn lạm phát bằng cách tạo thêm một Fragment cho chỉ bao gồm RecylerView.

tập tin xml Đây là một trong các tab của tôi có chứa một bố cục khung hình thay vì một tái chế.

shop_most_views_fragment.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<FrameLayout 
    android:id="@+id/most_view_item_frameLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#f3f3f3" /> 
</LinearLayout> 

của lớp java

public class MostViews extends Fragment { 
private String title; 
private int page; 
View convertedView; 
RecyclerView grids; 

public static MostViews newInstance(int page, String title) { 
    MostViews fragmentFirst = new MostViews(); 
    Bundle args = new Bundle(); 
    args.putInt("someInt", page); 
    args.putString("someTitle", title); 
    fragmentFirst.setArguments(args); 
    return fragmentFirst; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    page = getArguments().getInt("someInt", 0); 
    title = getArguments().getString("someTitle"); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    convertedView = inflater.inflate(R.layout.shop_most_views_fragment, container, false); 
    transitMasonaryLayoutFragmentIntoFramLayout(); 
    return convertedView; 
} 

private void transitMasonaryLayoutFragmentIntoFramLayout() { 
    MasanoryLayout masanoryLayout = new MasanoryLayout(); 
    FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
    fragmentManager.beginTransaction() 
      .add(R.id.most_view_item_frameLayout, masanoryLayout).commit(); 
} 
} 

vì vậy chúng tôi có một bố cục khung hình để đưa đoạn recylcer của chúng tôi vào đó.

shop_most_view_masanory_fragment.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<android.support.v7.widget.RecyclerView 
    android:id="@+id/mostViewsItem" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 
</LinearLayout> 

lớp java của nó

public class MasanoryLayout extends Fragment { 
View convertedView; 
RecyclerView grids; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    convertedView = inflater.inflate(R.layout.shop_most_view_masanory_fragment, container, false); 
    grids = (RecyclerView) convertedView.findViewById(R.id.mostViewsItem); 
    setLayoutManagerOnRecyclerView(); 
    MasonryAdapter adapter = new MasonryAdapter(initializeData()); 
    grids.setAdapter(adapter); 
    return convertedView; 
} 

private void setLayoutManagerOnRecyclerView() { 
    grids.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)); 
} 

private List<StoreItem> initializeData() { 
    List<StoreItem> storeItems = new ArrayList<>(); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store)); 
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore)); 

    return storeItems; 
} 
} 

như bạn thấy FragmentPagerAdapter bạn sẽ gọi MostViews được thổi phồng và MostViews bản thân sẽ gọi MasanoryLayout được thổi phồng. vì vậy chúng tôi đã thoát khỏi bối cảnh FragmentPagerAdapter;)

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