我已将基于Fragment的ViewPager指定为RecyclerView项目。 onBindViewHolder()
RecyclerView.Adapter
生成
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
setText()
设置文字时。表示在绑定值时不创建视图。
我无法弄明白 - >为什么未创建视图,即使在ViewPager
中处理Fragment
和onCreateViewHolder()
通货膨胀?我也在onBindViewHolder()
尝试了通货膨胀,但仍然是一样。
如何在Page Fragment
之前强制onBindViewHolder()
充气。
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;
}
}
答案 0 :(得分:1)
这是我的最终解决方案。
1)我添加了一个条件来检查onBindViewHolder
2)如果为null,我只是在片段类中将boolean bindExceptionally
标记为true。
3)当片段将在onCreateView()
创建视图时,它将检查标志是否为true以设置文本。否则,它将在不设置文本的情况下继续前进。
注意:片段在onCreateViewHolder()
而不在onBindViewHolder()
中膨胀,因此片段只会膨胀一次然后再循环。
更新 - 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;
}
}
答案 1 :(得分:0)
当然title
为空。
FolderMainPageFragment
在您访问title
时甚至还没有开始其生命周期。这意味着onCreateView
尚未调用,布局未被夸大,因此title
。
就onCreateViewHolder()
中的通货膨胀而言,您只是夸大了布局view_pager_main_list_item_folder
而不是main_list_item_view
(来自包含FolderMainPageFragment
的{{1}}),因为title
还没有开始。
另外,为什么要将FolderVPAdapter
置于ViewPager
内?也许你可以做别的事。
要将数据传递给RecyclerView
,请在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;
}
}
方法的好处是,您现在可以在 onBindViewHolder()中使用它。但是,您需要想出一种方法,即不在 onBindViewHolder()中创建Bundle的新实例。
答案 2 :(得分:0)
正如阿巴斯所提到的,片段内的观点并非在调用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"));