J'essaie la nouvelle RecyclerView
dans Android Lollipop et je suis coincé.
J'essaie de recevoir une liste, avec une icône et une TextView
à la droite de l'icône, à l'intérieur d'une Fragment
.
J'ai trouvé ce bon tutoriel sur la façon de configurer une RecyclerView
. J'ai suivi chaque point et n'ai modifié que le item_layout.xml
pour l'adapter à mes besoins.
Le projet est construit sans erreur, mais lorsqu’il se lance sur mon appareil, j’obtiens cette erreur:
Java.lang.RuntimeException: Impossible de démarrer l'activité ComponentInfo {com.fredrikaldgard.materialcolors/com.fredrikaldgard.materialcolors.MainActivity}: Java.lang.NullPointerException: tentative d'invocation de la méthode virtuelle 'void Android.support.v7.widget.RecyclerView. setLayoutManager (Android.support.v7.widget.RecyclerView $ LayoutManager) 'sur une référence d'objet null
J'ai essayé de google le problème mais je suis un amateur de développement Android.
Voici ma 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());
Et ma 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: Voici la 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;
}
}
Qu'est-ce qui s'est peut-être mal passé?
Cette question a été posée il y a quelque temps déjà, mais sur la base de la réponse fournie par @ nacho_zona3 et de l'expérience acquise avec des fragments, le problème est que les vues n'ont pas été créées au moment où vous essayez de les trouver avec la méthode findViewById()
dans onCreate()
. résoudre ce problème, déplacez le code suivant:
// 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());
à l'appel onCreateView()
de votre fragment. Une petite quantité de refactoring est nécessaire car toutes les variables et méthodes appelées à partir de cette méthode doivent être statiques. Le code final devrait ressembler à ceci:
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;
}
}
Donc, l’essentiel ici est que partout où vous appelez findViewById()
, vous devrez utiliser rootView.findViewById()
Vous devriez extraire RecyclerView
dans une Fragment
après avoir gonflé la vue principale à l'aide de cette vue. Peut-être qu'il ne trouve pas votre recycleur parce que cela ne fait pas partie de l'activité
@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;
}
Assurez-vous que vous avez la bonne disposition et que l'identifiant RecyclerView se trouve à l'intérieur de la disposition. Sinon, vous obtiendrez cette erreur. J'ai eu le même problème, puis j'ai remarqué que la mise en page était fausse.
public class ColorsFragment extends Fragment {
public ColorsFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
==> make sure you are getting the correct layout here. R.layout...
View rootView = inflater.inflate(R.layout.fragment_colors, container, false);