21

我正在尝试Android Lollipop中的新RecyclerView,并且卡住了。在片段中显示RecyclerView

我试图在Fragment的图标右侧收到一个带有图标和TextView的列表。

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

我试图谷歌这个问题,但我与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; 
} 
} 

编辑:这里的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

你仍然有ID列表RecyclerView在XML布局文件?如果没有,recyclerView变量将在步骤2为空。 – stkent 2014-10-29 00:56:08

+0

是的,我有一个RecyclerView在我的XML与ID“列表”。 – fredthemugwump 2014-10-29 13:44:06

+0

应该已经更清楚了:在activity_main.xml文件中,对吗? – stkent 2014-10-29 14:04:35

回答

16

在使用该视图扩充核心视图后,您应该在Fragment中检索RecyclerView。也许它不能找到你回收因为它不是活动的一部分

@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 2014-10-29 13:48:43

+0

您可以使用任何活动,如果不需要它,您不必使用支持库 – user4182277 2014-10-29 13:56:35

+0

“使用任何活动”是什么意思?无论如何,我正在使用导航抽屉的支持库。 – fredthemugwump 2014-10-29 14:06:30

26

这被问到前一段时间现在,但基于@ nacho_zona3提供的答案以及以前的片段使用经验,问题在于在您尝试使用方法中的findViewById()方法尝试找到这些视图以解决此问题时,视图尚未创建,请移动以下内容代码:

// 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 2015-10-06 17:33:20

+1

男人,你应该得到一个+1 .. – 2015-12-16 17:00:10

+0

你也可以从片段'onCreateView'返回recyclerview,因为基本上片段现在是一个RecyclerView – Prab 2018-02-26 00:46:39