在 Fragment 中设置一个新的 ListAdapter
Posted
技术标签:
【中文标题】在 Fragment 中设置一个新的 ListAdapter【英文标题】:Set a new ListAdapter in Fragment 【发布时间】:2019-12-31 11:45:04 【问题描述】:我想在 Fragment 中创建一个新的 ListAdapter,但是每次运行此代码时都会收到此错误:
尝试调用虚方法'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' 空对象引用
在这条线上:listAdapter = new ListAdapter(this.getActivity(), dataModelArrayList);
。
我不确定我在这里做错了什么。我有这个:listAdapter = new ListAdapter(this, dataModelArrayList);
首先在我的 MainActivity 中,一切似乎都工作正常,但是当我把它放在片段中并将 this
更改为 this.getActivity()
并且它停止工作。如果您需要更多代码,请告诉我。
在我的片段中:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View v = inflater.inflate(R.layout.fragment_home, container,false);
listView = v.findViewById(R.id.lv);
return v;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
//..
loadData();
UsernameInput.addTextChangedListener(new TextWatcher()
public void afterTextChanged(Editable s)
Username = UsernameInput.getText().toString();
if (Username.trim().length() == 0)
//..
loadData();
else
retrieveJSON();
//..
//..
);
private void retrieveJSON()
//..
StringRequest stringRequest = new StringRequest(Request.Method.GET, URLstring,
new Response.Listener<String>()
@Override
public void onResponse(String response)
try
JSONObject obj = new JSONObject(response);
if(obj.optString("status").equals("ok"))
//..
setupListview();
if (Username.trim().length() == 0)
//..
else
catch (JSONException e)
e.printStackTrace();
,
new Response.ErrorListener() //..);
//...
private void setupListview()
listAdapter = new ListAdapter(getActivity(), dataModelArrayList);
if (listAdapter.getCount() != 0)
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
//..
);
private void loadData()
//..
if (HistoryList == null)
HistoryList = new ArrayList<>();
setupListview_History();
//..
else
setupListview_History();
//..
错误:
2019-08-27 12:31:13.098 10033-10033/com.instapf.danik.instapfforinstagram E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.instapf.danik.instapfforinstagram, PID: 10033
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.instapf.danik.instapfforinstagram.Home.setupListview_History(Home.java:257)
at com.instapf.danik.instapfforinstagram.Home.loadData(Home.java:336)
at com.instapf.danik.instapfforinstagram.Home.onCreate(Home.java:119)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2414)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1418)
at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1195)
at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1078)
at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:117)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2408)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:24545)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:742)
at android.view.View.measure(View.java:24545)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3006)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1833)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2122)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:725)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
2019-08-27 12:31:13.099 10033-10033/com.instapf.danik.instapfforinstagram E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
【问题讨论】:
What is a NullPointerException, and how do I fix it?的可能重复 您的ListView
可能/可能为空
可能是你忘记初始化列表了。
使用 getActivity() 代替这个
问题似乎与getActivity()
无关,而是与listView
有关,即null
。如何在 Fragment 中实例化 listView?
【参考方案1】:
检查Fragment lifecycle。create()
方法被调用之前 onCreateView()
。
在您的情况下,这意味着您正在使用 setupListview()/loadData()
方法
listView.setAdapter(listAdapter);
之前 listView = v.findViewById(R.id.lv);
在onCreateView()
中被调用。
那么 listView
在你的情况下是 null
。
您应该将设置代码从onCreate()
移至onActivityCreated(Bundle)
方法。
【讨论】:
感谢您的回复。我已经更改了我的代码,以便在listView.setAdapter(listAdapter);
之前调用 listView = v.findViewById(R.id.lv);
但它似乎没有奏效。仍然出现同样的错误。
onCreateView()
之前的任何情况下都不能使用此代码。【参考方案2】:
您没有遵循片段的生命周期。您可以按照以下顺序进行:
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
//do nothing here
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View v = inflater.inflate(R.layout.fragment_home, container,false);
listView = v.findViewById(R.id.lv);
return v;
@Override
public View onViewCreated(View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
dataModelArrayList = new ArrayList<>();
setupListview();
//retrive data based on text change
retrieveJSON()
【讨论】:
【参考方案3】:我只需要放置:
loadData();
Clear.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
ClearData();
);
UsernameInput.addTextChangedListener(new TextWatcher()
public void afterTextChanged(Editable s)
Username = UsernameInput.getText().toString();
if (Username.trim().length() == 0)
Search.setText("SEARCH HISTORY");
//Remove.setVisibility(View.VISIBLE);
if (HistoryList != null)
HistoryList.clear();
if (dataModelArrayList != null)
dataModelArrayList.clear();
loadData();
Log.d("Empty", "Empty");
else
retrieveJSON();
Search.setText("SEARCH RESULTS");
//Remove.setVisibility(View.GONE);
public void beforeTextChanged(CharSequence s, int start, int count, int after)
public void onTextChanged(CharSequence s, int start, int before, int count)
);
在onCreateView
而不是onCreate
。
【讨论】:
以上是关于在 Fragment 中设置一个新的 ListAdapter的主要内容,如果未能解决你的问题,请参考以下文章
即使在 onAttach() 中设置,Fragment 中的活动也为空
如何使用Material Design在Alert Dialog Fragment中设置按钮样式?