简体   繁体   English

在 Fragment 中显示 RecyclerView

[英]Display a RecyclerView in Fragment

I'm trying out the new RecyclerView in Android Lollipop and I'm stuck.我正在 Android Lollipop 中试用新的RecyclerView ,但被卡住了。

I'm trying to receive a list, with an icon and a TextView to the right of the icon, inside a Fragment .我正在尝试接收一个列表,在一个Fragment ,在图标的右侧有一个图标和一个TextView

I found this great tutorial on how to set up a RecyclerView . 我发现了这个关于如何设置RecyclerView 很棒的教程 I have followed every point and only changed the item_layout.xml to fit my needs.我遵循了每一点,只更改了item_layout.xml以满足我的需要。

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 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.fredrikaldgard.materialcolors/com.fredikaldgard.materialcolors.MainActivity}:java.lang.NullPointerException:尝试调用虚拟方法 'void android.support.v7.widget.RecyclerView。空对象引用上的 setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)'

I've tried to google the problem but I'm quite an amateur with Android development.我试图用谷歌搜索这个问题,但我对 Android 开发非常业余。

Here's my MainActivity :这是我的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 :还有我的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编辑:这是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?可能出了什么问题?

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:这是前一段时间被问到的,但是根据@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 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.到您片段的onCreateView()调用。 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()所以这里的主要事情是在任何你调用findViewById()你都需要使用rootView.findViewById()

You should retrieve RecyclerView in a Fragment after inflating core View using that View.在使用该视图膨胀核心视图后,您应该在Fragment检索RecyclerView Perhaps it can't find your recycler because it's not part of Activity也许它找不到您的回收站,因为它不是 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;
}

Make sure that you have the correct layout, and that the RecyclerView id is inside the layout.确保您有正确的布局,并且 RecyclerView id 在布局内。 Otherwise, you will be getting this error.否则,您将收到此错误。 I had the same problem, then I noticed the layout was wrong.我遇到了同样的问题,然后我注意到布局错误。

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

I faced same problem.我遇到了同样的问题。 And got the solution when I use this code to call context.并在我使用此代码调用上下文时得到了解决方案。 I use Grid Layout.我使用网格布局。 If you use another one you can change.如果你使用另一个你可以改变。

   recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),1));

if you have adapter to set.如果你有适配器要设置。 So you can follow this.所以你可以遵循这个。 Just call the getContext只需调用 getContext

  adapter = new Adapter(getContext(), myModelList);

If you have Toast to show, use same thing above如果您要显示 Toast,请使用上面相同的内容

   Toast.makeText(getContext(), "Error in "+e, Toast.LENGTH_SHORT).show();

Hope this will work.希望这会奏效。

HappyCoding快乐编码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM