Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display a RecyclerView in Fragment

I'm trying out the new RecyclerView in Android Lollipop and I'm stuck.

I'm trying to receive a list, with an icon and a TextView to the right of the icon, inside a Fragment.

I found this great tutorial on how to set up a RecyclerView. I have followed every point and only changed the item_layout.xml to fit my needs.

The project builds without any errors but when it launches on my device I'm getting this error:

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

I've tried to google the problem but I'm quite an amateur with Android development.

Here's my 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()); 

And my MyAdapter:

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: Here's the 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;     } } 

What has possibly gone wrong?

like image 725
fredthemugwump Avatar asked Oct 29 '14 00:10

fredthemugwump


People also ask

Can I put recycler view in fragment?

Set the Adapter to RecyclerView on Fragment class This class will call the layout that consists of the RecyclerView and connect the adapter with the RecyclerView. onViewCreated() will set the RecyclerAdapter to the RecyclerView layout.

How do I fix no adapter attached skipping layout?

setLayoutManager(new LinearLayoutManager(this)); recyclerView. setAdapter(adapter); Just replace above code with this and it should work. What you did wrong is you called setAdapter(adapter) before calling layout manager.

What is an android fragment?

According to the Android documentation, a fragment is a part of applications user interface that is bound to an activity. Fragments have their lifecycle and layouts or UI components. Fragments help enrich your UI design, pass data between different screens, and adapt to different device configurations.


2 Answers

This was asked some time ago now, but based on the answer that @nacho_zona3 provided, and previous experience with fragments, the issue is that the views have not been created by the time you are trying to find them with the findViewById() method in onCreate() to fix this, move the following code:

// 1. get a reference to recyclerView RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);  // 2. set layoutManger recyclerView.setLayoutManager(new LinearLayoutManager(this));  // this is data from 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());  

to your fragment's onCreateView() call. A small amount of refactoring is required because all variables and methods called from this method have to be static. The final code should look like:

 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 from 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;      }  } 

So the main thing here is that anywhere you call findViewById() you will need to use rootView.findViewById()

like image 159
The Dude Avatar answered Oct 10 '22 18:10

The Dude


You should retrieve RecyclerView in a Fragment after inflating core View using that View. Perhaps it can't find your recycler because it's not part of Activity

@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; } 
like image 25
user4182277 Avatar answered Oct 10 '22 18:10

user4182277