1

フラグメントベースのViewPagerをRecyclerViewアイテムとして割り当てました。 setText()を使用してテキストを設定しながらRecyclerView.AdapterフラグメントベースのViewPager(RecyclerViewアイテムとして)はヌルオブジェクトリファレンスを生成します

内部onBindViewHolder()

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

を生成します。値をバインドするときにビューが作成されないことを意味します。

ViewPagerFragmentのインフレ率がonCreateViewHolder()で処理されていても、なぜそのビューが作成されないのかわかりません。私はonBindViewHolder()でもインフレを試みましたが、それでも同じです。

どうすればPage FragmentonBindViewHolder()の前に強制的に押し込むことができますか?

RecyclerView.Adapter

public class MainListRVA extends RecyclerView.Adapter<ViewHolder> implements ConstantValues { 

    FragmentManager oFm; 

    private int viewPagerId = 1; 

    private static ArrayList<MainListItem> oListItems = new ArrayList<MainListItem>(); 

    MainListRVA(ArrayList<MainListItem> theArray, FragmentManager fm){ 
     oListItems = theArray; 
     oFm = fm; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_pager_main_list_item_folder, parent, false); 
     return new FolderVH(v); 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, int position) { 

     FolderVH folderVH = (FolderVH) holder; 
     MainListItem listItem = oListItems.get(position); 

     folderVH.fragmentOne.title.setText(listItem.oTitle); 
     folderVH.fragmentTwo.title.setText(listItem.oDetail); 
     ///////////////////////////////////////////////////// 
     ////////////////////THIS GIVE NULL POINTER EXCEPTION 
    } 

    public class FolderVH extends ViewHolder { 

     FolderMainPageFragment fragmentOne, fragmentTwo; 
     ViewPager viewPager; 

     FolderVH(View v) { 

      super(v); 

      ArrayList<Fragment> fragments = new ArrayList<Fragment>(); 

      fragmentOne = FolderMainPageFragment.newInstance("one"); 
      fragmentTwo = FolderMainPageFragment.newInstance("two"); 

      fragments.add(fragmentOne); 
      fragments.add(fragmentTwo); 

      FolderVPAdapter folderVPAdapter = new FolderVPAdapter(oFm, fragments); 

      viewPager = (ViewPager) v.findViewById(R.id.viewPager); 
      viewPager.setId(viewPagerId++); 
      viewPager.setAdapter(folderVPAdapter); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return oListItems.size(); 
    } 

    void move(int fromPos, int toPos){ } 

    void remove(int position){ } 
} 

FragmentPagerAdapter

public class FolderVPAdapter extends FragmentPagerAdapter { 

    private List<Fragment> fragments; 

    public FolderVPAdapter(FragmentManager fm, List<Fragment> fragments) { 
     super(fm); 
     this.fragments = fragments; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return this.fragments.get(position); 
    } 

    @Override 
    public int getCount() { 
     return this.fragments.size(); 
    } 
} 

ページャフラグメント

public class FolderMainPageFragment extends Fragment { 

    TextView title; 

    public static FolderMainPageFragment newInstance(String text) { 
     return new FolderMainPageFragment(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.main_list_item_view, container, false); 
     this.title = (TextView) v.findViewById(R.id.list_title); 
     return v; 
    } 
} 

答えて

1

ここれます私が持っている最終的な解決策。

1)ヌルは、私はちょうど断片クラス内の真bindExceptionallyブールフラグが立てられた場合、私は)onBindViewHolder

2に結合しながら、ビューがnullであるかどうかを確認する条件を追加しました。

3)フラグメントがonCreateView()にビューを作成するとき、フラグがtrueであるかどうかを確認してテキストを設定します。そうでなければ、テキストを設定せずに先に進むだけです。

注:断片は、onCreateViewHolder()で膨らまされ、onBindViewHolder()ではなく、従って、断片は1回だけ膨張し、次いでそれらはリサイクルされる。

更新 - RecyclerView.Adapter更新

public class MainListRVA extends RecyclerView.Adapter<ViewHolder> implements ConstantValues { 

    FragmentManager oFm; 

    private int viewPagerId = 1; 

    static ArrayList<MainListItem> oListItems = new ArrayList<MainListItem>(); 

    MainListRVA(ArrayList<MainListItem> theArray, FragmentManager fm){ 
     oListItems = theArray; 
     oFm = fm; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_pager_main_list_item_folder, parent, false); 
     return new FolderVH(v); 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, int position) { 

     Log.e("onBindViewHolder", "onBindViewHolder"); 

     FolderVH folderVH = (FolderVH) holder; 
     MainListItem listItem = oListItems.get(position); 
     folderVH.viewPager.setCurrentItem(0); 

     if(folderVH.fragmentOne.title != null) { 
      folderVH.fragmentOne.title.setText(listItem.oTitle); 
     } else { 
      folderVH.fragmentOne.bindExceptionally = true; 
      folderVH.fragmentOne.currListItem = listItem; 
     } 
    } 

    public class FolderVH extends RecyclerView.ViewHolder { 

     FolderMainPageFragment fragmentOne, fragmentTwo; 
     ViewPager viewPager; 

     FolderVH(View v) { 

      super(v); 

      Log.e("FolderVH", "FolderVH"); 

      ArrayList<Fragment> fragments = new ArrayList<Fragment>(); 

      fragmentOne = FolderMainPageFragment.newInstance("one"); 
      fragmentTwo = FolderMainPageFragment.newInstance("two"); 

      fragments.add(fragmentOne); 
      fragments.add(fragmentTwo); 

      FolderVPAdapter folderVPAdapter = new FolderVPAdapter(oFm, fragments); 

      viewPager = (ViewPager) v.findViewById(R.id.viewPager); 
      viewPager.setId(viewPagerId++); 
      viewPager.setAdapter(folderVPAdapter); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return oListItems.size(); 
    } 

    void move(int fromPos, int toPos){ } 

    void remove(int position){ } 
} 

- ポケットベル断片

public static class FolderMainPageFragment extends Fragment { 

    TextView title; 
    boolean bindExceptionally = false; 
    MainListItem currListItem; 

    public static FolderMainPageFragment newInstance(String text) { 
     return new FolderMainPageFragment(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.main_list_item_view_folder, container, false); 
     this.title = (TextView) v.findViewById(R.id.list_title); 

     if(bindExceptionally) { 
      title.setText(currListItem.oTitle); 
      bindExceptionally = false; 
      currListItem = null; 
     } 

     return v; 
    } 
} 
0

もちろんtitleはnullです。

FolderMainPageFragmentは、titleにアクセスする時点までにライフサイクルを開始していません。つまり、onCreateViewはまだ呼び出されておらず、レイアウトは拡張されていないので、titleです。 FolderVPAdapterもまだ開始されていないので、

限りonCreateViewHolder()のインフレを懸念しているとして、あなたは、単に(FolderMainPageFragmentからtitleを含む)レイアウトview_pager_main_list_item_folderなくmain_list_item_viewを膨らませています。

また、なぜViewPagerRecyclerViewに入れたいのですか?おそらくあなたは何か他のことをすることができます。

Fragmentにデータを渡すには、handleArgs()FolderMainPageFragmentに書き込んでください。

public class FolderMainPageFragment extends Fragment { 

    TextView title; 
    Bundle mBundle; 

    public void handleArgs(Bundle bundle) { 
     mBundle = bundle; 

     if (title != null) 
      title.setText(bundle.getString("title")); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.main_list_item_view, container, false); 
     this.title = (TextView) v.findViewById(R.id.list_title); 

     if (mBundle != null)  // When handleArgs() is called before onCreateView(). 
      handleArgs(mBundle); 
     return v; 
    } 
} 

独自のBundle方法を書くことの利点は、あなたが今onBindViewHolder()でそれを使用することができるということです。しかし、バンドルの新しいインスタンスがonBindViewHolder()に作成されない方法を考え出す必要があります。

+0

を私はそれについて少し知っていたが、確認されませんでした。しかし、まだonBindViewHolder()の前にページフラグメントの膨張を強制する方法はありません。インフレ後にテキストを設定するその他の方法はありますか? – kanudo

+0

もちろん、 'Bundle'を使って他の情報と一緒にタイトルを渡し、' getArguments() 'を呼び出すことで' FolderMainPageFragment.onCreate() 'で取り出すことができます。 – Abbas

+0

あなたは正しいです。 @ Furedalもそれを示唆した。 **しかし**それはRecyclerViewの利点を妨げるでしょう。このアプローチと同様に、私は** onBindViewHolder()からViewPagerのFragmentsとPassの値を** Inflate **しなければなりません。私はそれを膨らませたくない。 – kanudo

0

上記のAbbasのように、フラグメント内のビューは、onBindViewHolderが呼び出された時点で開始されません。

フラグメントについては少し読んでください。もしフラグメントが行きたいと思ったら、そのフラグメント内の特定のフラグメントのビューロジックを分離する必要があります。 フラグメントに渡す情報は、フラグメントの開始時にsetArgumentsで渡すバンドルに入れた情報だけです。そうでなければ痛みを与えるライフサイクルの問題がたくさんあります。この場合

あなたは断片にタイトルを設定したい場合は、あなたの代わりに開始時にこのような何かを行う必要があります。

Bundle args = new Bundle(); 
bundle.putString("title", "My title"); 
fragmentOne = FolderMainPageFragment.newInstance("one"); 
fragmentOne.setArguments(args); 

そして、あなたの断片でonViewCreated()

Bundle args = getArguments(); 
title.setText(args.getString("title")); 
+0

このアプローチでは、ViewHolderまたはonBindViewHolder()の 'onCreateViewHolder()'に値を渡す必要があります。ビューホルダーのカスタムメソッドを呼び出して、フラグメントを作成し、 'ViewPager'に割り当てます。これは、 'RecyclerView'を使うことの恩恵を消すでしょう。 ViewPagerの 'onBindViewHolder()'フラグメントが呼び出されるたびに、膨大になり、アダプタを介して割り当てられます。 – kanudo

+0

'onCreateViewHolder()'の内部でinflateされるようにrecyclerviewアイテムのビューグループを完全にする必要があります。 – kanudo

+0

なぜフラグメントを使用する必要がありますか?ビューを直接膨張させる通常のPagerAdapterを使いたいかもしれません。確かにあなたに少し問題を与えるだろう:) – Furedal

関連する問題