web-dev-qa-db-ja.com

FragmentでRecyclerViewを表示する

Android Lollipopの新しいRecyclerViewを試していますが、行き詰っています。

アイコンとTextView内のアイコンの右側にFragmentが付いたリストを受信しようとしています。

この素晴らしいチュートリアルを見つけましたRecyclerViewの設定方法について。私はあらゆる点に従い、必要に応じてitem_layout.xmlのみを変更しました。

プロジェクトはエラーなしでビルドされますが、デバイスで起動するとこのエラーが発生します。

Java.lang.RuntimeException:アクティビティComponentInfo {com.fredrikaldgard.materialcolors/com.fredrikaldgard.materialcolors.MainActivity}を開始できません:Java.lang.NullPointerException:仮想メソッド 'void Android.support.v7.widget.RecyclerView。を呼び出そうとしました。 nullオブジェクト参照のsetLayoutManager(Android.support.v7.widget.RecyclerView $ LayoutManager) '

私はこの問題をグーグルで調べようとしましたが、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;
    }
}

何が間違っているのでしょうか?

37
fredthemugwump

これは少し前に尋ねられましたが、@ 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()を使用する必要があることです。

47
The Dude

そのビューを使用してコアビューを拡張した後、RecyclerViewFragmentを取得する必要があります。多分それはあなたのrecyclerを見つけることができません

@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;
}
29
user4182277

正しいレイアウトになっていること、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); 
0
live-love