使用 BaseAdapter 时片段 TabLayout 中的 NullPointerException
Posted
技术标签:
【中文标题】使用 BaseAdapter 时片段 TabLayout 中的 NullPointerException【英文标题】:NullPointerException in Fragment TabLayout when using BaseAdapter 【发布时间】:2020-02-23 14:21:56 【问题描述】:我已经成功解析了一个带有后台 AsyncTask 的简单 rss 提要(XML 提要)。但无法使用 BaseAdapter (MyBaseAdapter) 将接收到的提要从 Fragment (FragmentTOI) 设置为 ListView。由于解析来自片段,我使用“getActivity()”而不是“MainActivity.this”。我可以看到从 rss xml 提要解析的 logcat 中的所有标题。附上代码 sn-ps 和 Logcat 截图。
代码:
// Fragment
public static class FragmentTOI extends Fragment
ListView listView;
MyAsyncTask myAsyncTask;
Context context;
ArrayAdapter<String> arrayAdapter;
public FragmentTOI(Context context)
// this.context = context;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
super.onCreateView (inflater, container, savedInstanceState);
View view = inflater.inflate (R.layout.fragment_toi, container, false);
listView = view.findViewById (R.id.list_view_toi);
startTask ();
return view;
// Method to start the AsyncTask with new one if null.
public void startTask()
//if the download is empty then cancel, else start the task
if (myAsyncTask != null)
myAsyncTask.cancel (true);
else
myAsyncTask = new MyAsyncTask (getActivity ());
myAsyncTask.execute ();
// Method to receive data from onPostExecute of AsyncTask.
public void receiveData(ArrayList<HashMap<String, String>> results)
Log.d ("XML", "FragmentTOI receiveData Method: " + results);
listView.setAdapter (new MyBaseAdapter (context, results));
listView.setAdapter (arrayAdapter);
// AsyncTask downloader
public static class MyAsyncTask extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> hashMaps)
super.onPostExecute (hashMaps);
fragmentTOI.receiveData (hashMaps);
public static class MyBaseAdapter extends BaseAdapter
ArrayList<HashMap<String, String>> data;
LayoutInflater layoutInflater;
public MyBaseAdapter(Context context, ArrayList<HashMap<String, String>> data)
this.data = data;
layoutInflater = (LayoutInflater) context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
@Override
public int getCount()
return data.size ();
@Override
public Object getItem(int i)
return data.get (i);
@Override
public long getItemId(int i)
return i;
@Override
public View getView(int i, View view, ViewGroup viewGroup)
View view1 = view;
MyRowHolder myRowHolder = null;
if (view1 == null)
view1 = layoutInflater.inflate (R.layout.single_row, viewGroup, false);
myRowHolder = new MyRowHolder (view1);
view1.setTag (myRowHolder);
else
myRowHolder = (MyRowHolder) view1.getTag ();
HashMap<String, String> currentItem = data.get (i);
myRowHolder.textViewTitle.setText (currentItem.get ("title"));
return view1;
static class MyRowHolder
TextView textViewTitle;
public MyRowHolder(View view)
textViewTitle = view.findViewById (R.id.text_view_title);
Logcat:
【问题讨论】:
【参考方案1】:当您将适配器设置为您的列表视图时,请使用context
,如下所示。
// Method to receive data from onPostExecute of AsyncTask.
public void receiveData(ArrayList<HashMap<String, String>> results)
//listView.setAdapter (new MyBaseAdapter (getActivity (), results)); // here you got exception.
// use context as you initialize it inside the constructor of your fragment.
listView.setAdapter (new MyBaseAdapter (context, results));
listView.setAdapter (arrayAdapter);
【讨论】:
请将您的activity
代码贴在您拨打FragmentTOI
的位置。【参考方案2】:
选项 - 1:
试试requireActivity()
或requireContext()
。
而不是
listView.setAdapter (new MyBaseAdapter (getActivity (), results));
使用
listView.setAdapter (new MyBaseAdapter (requireActivity(), results));
选项 - 2:
无需在 Adapter 中传递Context
即可获取LayoutInflater
。删除这个:
public MyBaseAdapter(Context context, ArrayList<HashMap<String, String>> data)
this.data = data;
//layoutInflater = (LayoutInflater) context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
在getView
里面试试这样:
if (view1 == null)
view1 = LayoutInflater.from(viewGroup.getContext()).inflate (R.layout.single_row, viewGroup, false);
myRowHolder = new MyRowHolder (view1);
view1.setTag (myRowHolder);
【讨论】:
为什么你的片段static
以及为什么你通过Context
来调用片段?如果您需要传递Context
,请使用它而不是getActivity()
。不是吗?
在我的回答中尝试使用 option-2,然后告诉我
当我删除 static
时发生此异常:java.lang.IllegalStateException: Fragment com.shiva.pillu.headlinessample.MainActivity.FragmentTOI must be a public static class to be properly recreated from instance state.
当我尝试选项 2 时发生此错误:java.lang.IllegalStateException: Fragment FragmentTOIc84840f not attached to an activity.
不要在 AsyncTask 中使用 fragmentTOI = new FragmentTOI (context);
,而是使用接口将数据返回到片段。您创建了一个不附加到活动的 FragmentTOI 的新实例
请进一步研究并重构您的代码库。它充满了问题。以上是关于使用 BaseAdapter 时片段 TabLayout 中的 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章
如何在填充了 BaseAdapter 的 Fragment 中刷新 ListView?
ListFragment(或 Fragment)中的 BaseAdapter 不起作用