在 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 中的活动也为空

是否可以在片段类中设置 ViewPager?

如何使用Material Design在Alert Dialog Fragment中设置按钮样式?

在 Objective-C 中设置一个新的 Parse 服务器

禁用时在某个活动中设置新的ActionBar

批准后如何在新的iTunesConnect界面中设置具体的发布日期?