21

Я тестирую новый RecyclerView в Android Lollipop, и я застрял.Отобразить RecyclerView в фрагменте

Я пытаюсь получить список с иконкой и TextView справа от значка, внутри Fragment.

I found this great tutorial о том, как настроить RecyclerView. Я следил за каждым пунктом и только менял item_layout.xml в соответствии со своими потребностями.

Проект строит без каких-либо ошибок, но когда он запускает на моем устройстве я получаю эту ошибку:

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

Я пытался Google проблемы, но я вполне любитель с развитием Android.

Вот мой 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:

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: Вот 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; 
    } 
} 

Что, возможно, пошло не так?

+4

У вас еще есть RecyclerView со списком идентификаторов в файле макета XML? Если нет, переменная recyclerView будет равна нулю на этапе 2. – stkent

+0

Да, у меня есть RecyclerView в моем xml с идентификатором «list». – fredthemugwump

+0

Должно быть, было яснее: в файле 'activity_main.xml', правильно? – stkent

ответ

16

Вы должны получить RecyclerView в Fragment после раздувания сердечника Просмотр с использованием этого вида. Возможно, он не может найти свой переробочика, потому что это не является часть деятельности

@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

Спасибо большое! Я попытался заменить свой код внутри своего фрагмента, но у меня возникла проблема с "final FragmentActivity c = getActivity();" Это дает мне сообщение об ошибке: Обязательно "android.support.v4.app.FragmentActitvity" Найдено "android.app.Activity". Я собрал библиотеку поддержки v4 в своем проекте. – fredthemugwump

+0

Вы можете использовать любую деятельность, вам не нужно использовать библиотеку поддержки, если она не нужна. – user4182277

+0

Что вы подразумеваете под «использование какой-либо деятельности»? В любом случае я использую библиотеку поддержки для навигационного ящика. – fredthemugwump

26

Это было предложено некоторое время назад теперь, но на основании ответа, предоставленного @ nacho_zona3, и предыдущего опыта с фрагментами, проблема заключается в том, что представления не были созданы к тому моменту, когда вы пытаетесь найти их с помощью метода findViewById() в onCreate(), чтобы исправить это, переместите следующие код:

// 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()); 

на звонок onCreateView() вашего фрагмента. Требуется небольшое количество рефакторинга, потому что все переменные и методы, вызванные этим методом, должны быть статическими. Окончательный код должен выглядеть следующим образом:

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

Так что главное здесь в том, что в любом месте вы звоните findViewById() вам нужно будет использовать rootView.findViewById()

+1

замените это на getActivity(). – swapyonubuntu

+1

Человек, вы просто заслуживаете +1 .. –

+0

Вы также можете вернуть recyclerview из фрагмента 'onCreateView', потому что по существу фрагмент теперь является RecyclerView – Prab

Смежные вопросы