21

Tôi đang thử số mới RecyclerView trong Android Lollipop và tôi bị kẹt.Hiển thị một RecyclerView trong Fragment

Tôi đang cố gắng nhận danh sách, có biểu tượng và TextView ở bên phải của biểu tượng, bên trong một Fragment.

I found this great tutorial về cách thiết lập RecyclerView. Tôi đã theo dõi mọi điểm và chỉ thay đổi item_layout.xml để phù hợp với nhu cầu của tôi.

Dự án xây dựng mà không cần bất kỳ lỗi nào nhưng khi nó ra mắt trên điện thoại của tôi tôi nhận được lỗi này:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.fredrikaldgard.materialcolors/com.fredrikaldgard.materialcolors.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference

Tôi đã cố gắng để google vấn đề nhưng tôi khá một nghiệp dư với sự phát triển Android.

Dưới đây là tôi MainActivity:

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

    // 1. get a reference to recyclerView 
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list); 

    // 2. set layoutManger 
    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 

    // this is data fro recycler view 
    ItemData itemsData[] = { new ItemData("Indigo",R.drawable.circle), 
      new ItemData("Red",R.drawable.color_ic_launcher), 
      new ItemData("Blue",R.drawable.indigo), 
      new ItemData("Green",R.drawable.circle), 
      new ItemData("Amber",R.drawable.color_ic_launcher), 
      new ItemData("Deep Orange",R.drawable.indigo)}; 


    // 3. create an adapter 
    MyAdapter mAdapter = new MyAdapter(itemsData); 
    // 4. set adapter 
    recyclerView.setAdapter(mAdapter); 
    // 5. set item animator to DefaultAnimator 
    recyclerView.setItemAnimator(new DefaultItemAnimator()); 

MyAdapter tôi:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { 
private ItemData[] itemsData; 

public MyAdapter(ItemData[] itemsData) { 
    this.itemsData = itemsData; 
} 

// Create new views (invoked by the layout manager) 
@Override 
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
               int viewType) { 
    // create a new view 
    View itemLayoutView = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.item_layout, null); 

    // create ViewHolder 

    ViewHolder viewHolder = new ViewHolder(itemLayoutView); 
    return viewHolder; 
} 

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(ViewHolder viewHolder, int position) { 

    // - get data from your itemsData at this position 
    // - replace the contents of the view with that itemsData 

    viewHolder.txtViewTitle.setText(itemsData[position].getTitle()); 
    viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl()); 


} 

// inner class to hold a reference to each item of RecyclerView 
public static class ViewHolder extends RecyclerView.ViewHolder { 

    public TextView txtViewTitle; 
    public ImageView imgViewIcon; 

    public ViewHolder(View itemLayoutView) { 
     super(itemLayoutView); 
     txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title); 
     imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon); 
    } 
} 


// Return the size of your itemsData (invoked by the layout manager) 
@Override 
public int getItemCount() { 
    return itemsData.length; 
} 
} 

Edit: Đây là Fragment

public class ColorsFragment extends Fragment { 

    public ColorsFragment(){} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_colors, container, false); 

     return rootView; 
    } 
} 

gì đã có thể đi sai?

+4

Bạn vẫn có một RecyclerView với danh sách id trong file layout xml của bạn? Nếu không, biến recyclerView sẽ là null trong bước 2. – stkent

+0

Có, tôi có một RecyclerView trong xml của tôi với id "danh sách". – fredthemugwump

+0

Phải rõ ràng hơn: trong tệp 'activity_main.xml', phải không? – stkent

Trả lời

16

Bạn nên truy xuất RecyclerView trong một Fragment sau khi tăng lượt xem lõi bằng Chế độ xem đó. Có lẽ nó không thể tìm thấy bạn tái chế vì nó không phải là một phần của Hoạt động

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
    final View view = inflater.inflate(R.layout.fragment_artist_tracks, container, false); 
    final FragmentActivity c = getActivity(); 
    final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); 
    LinearLayoutManager layoutManager = new LinearLayoutManager(c); 
    recyclerView.setLayoutManager(layoutManager); 

    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      final RecyclerAdapter adapter = new RecyclerAdapter(c); 
      c.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        recyclerView.setAdapter(adapter); 
       } 
      }); 
     } 
    }).start(); 

    return view; 
} 
+0

Cảm ơn rất nhiều! Tôi đã cố gắng thay thế mã của mình bên trong Phân đoạn của tôi với bạn nhưng tôi gặp sự cố với "final FragmentActivity c = getActivity();" Nó cho tôi một lỗi: Yêu cầu "android.support.v4.app.FragmentActitvity" Tìm thấy "android.app.Activity". Tôi đã biên soạn thư viện hỗ trợ v4 trong dự án của mình. – fredthemugwump

+0

Bạn có thể sử dụng bất kỳ hoạt động nào, bạn không phải sử dụng thư viện hỗ trợ nếu không cần nó – user4182277

+0

Bạn có ý gì khi sử dụng bất kỳ hoạt động nào? Tôi đang sử dụng thư viện hỗ trợ cho một ngăn kéo nav anyway. – fredthemugwump

26

này được hỏi một số thời gian trước đây bây giờ, nhưng dựa trên câu trả lời mà @ nacho_zona3 cung cấp, và kinh nghiệm trước đó với các mảnh, vấn đề là các khung nhìn chưa được tạo ra khi bạn đang cố gắng tìm chúng bằng phương pháp findViewById() trong onCreate() để khắc phục điều này, di chuyển như sau mã số:

// 1. get a reference to recyclerView 
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list); 

// 2. set layoutManger 
recyclerView.setLayoutManager(new LinearLayoutManager(this)); 

// this is data fro recycler view 
ItemData itemsData[] = { new ItemData("Indigo",R.drawable.circle), 
     new ItemData("Red",R.drawable.color_ic_launcher), 
     new ItemData("Blue",R.drawable.indigo), 
     new ItemData("Green",R.drawable.circle), 
     new ItemData("Amber",R.drawable.color_ic_launcher), 
     new ItemData("Deep Orange",R.drawable.indigo)}; 


// 3. create an adapter 
MyAdapter mAdapter = new MyAdapter(itemsData); 
// 4. set adapter 
recyclerView.setAdapter(mAdapter); 
// 5. set item animator to DefaultAnimator 
recyclerView.setItemAnimator(new DefaultItemAnimator()); 

để gọi số onCreateView() của phân đoạn của bạn. Một số lượng nhỏ refactoring là cần thiết vì tất cả các biến và phương thức được gọi từ phương thức này phải là tĩnh. Các mã cuối cùng sẽ giống như thế:

public class ColorsFragment extends Fragment { 

    public ColorsFragment() {} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_colors, container, false); 
     // 1. get a reference to recyclerView 
     RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.list); 

     // 2. set layoutManger 
     recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 

     // this is data fro recycler view 
     ItemData itemsData[] = { 
      new ItemData("Indigo", R.drawable.circle), 
       new ItemData("Red", R.drawable.color_ic_launcher), 
       new ItemData("Blue", R.drawable.indigo), 
       new ItemData("Green", R.drawable.circle), 
       new ItemData("Amber", R.drawable.color_ic_launcher), 
       new ItemData("Deep Orange", R.drawable.indigo) 
     }; 


     // 3. create an adapter 
     MyAdapter mAdapter = new MyAdapter(itemsData); 
     // 4. set adapter 
     recyclerView.setAdapter(mAdapter); 
     // 5. set item animator to DefaultAnimator 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 

     return rootView; 
    } 
} 

Vì vậy, điều chính ở đây là bất cứ nơi nào bạn gọi findViewById() bạn sẽ cần phải sử dụng rootView.findViewById()

+1

thay thế điều này bằng getActivity(). – swapyonubuntu

+1

Người đàn ông, bạn chỉ xứng đáng được +1 .. –

+0

Bạn cũng có thể trả lại recyclerview từ đoạn 'onCreateView' bởi vì về cơ bản phân đoạn bây giờ là một RecyclerView – Prab

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