Java 在 Fragment 中显示 RecyclerView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26621060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:57:39  来源:igfitidea点击:

Display a RecyclerView in Fragment

javaandroidandroid-fragmentsandroid-5.0-lollipopandroid-recyclerview

提问by fredthemugwump

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

我正在尝试RecyclerViewAndroid Lollipop 中的新功能,但被卡住了。

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

我正在尝试接收一个列表,其中有一个图标和一个TextView在图标右侧的Fragment.

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

我找到了有关如何设置RecyclerView. 我遵循了每一点,只更改了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?

可能出了什么问题?

回答by user4182277

You should retrieve RecyclerViewin a Fragmentafter inflating core View using that View. Perhaps it can't find your recyclerbecause it's not part of Activity

您应该RecyclerViewFragment使用该视图膨胀核心视图后检索。也许它找不到您的回收站,因为它不是 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;
}

回答by The Dude

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

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:

到你的片段的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;
     }
 }

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

所以这里的主要事情是,无论你在哪里打电话,findViewById()你都需要使用rootView.findViewById()

回答by live-love

Make sure that you have the correct layout, and that the RecyclerView id is inside the layout. Otherwise, you will be getting this error. I had the same problem, then I noticed the layout was wrong.

确保您有正确的布局,并且 RecyclerView id 在布局内。否则,您将收到此错误。我遇到了同样的问题,然后我注意到布局错误。

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