【问题标题】:How to update ArrayAdapter in Fragment using AsyncTaskLoader?如何使用 AsyncTaskLoader 更新 Fragment 中的 ArrayAdapter?
【发布时间】:2018-02-26 17:18:06
【问题描述】:

我正在设置一个 Fragment(TabLayout) 和一个 ArrayAdapter 来显示单词列表。 我想在从 onLoadFinished() 中返回的源中完全获取数据后更新 Fragment。 AsyncTaskLoader 在 MainActivity 中设置。

@Override
public void onLoadFinished(Loader<List<Word>> loader, List<Word> words) {

            if (words != null && !words.isEmpty()) {
        NounsFragment nounsFragment = new NounsFragment();
        nounsFragment.updateList(words);

        NumberFragment numberFragment = new NumberFragment();
        numberFragment.updateList(words);

        Log.v(LOG_TAG, "OnFinishedLoad status : " + words.size());
    }else{
        Toast.makeText(this, R.string.no_words, Toast.LENGTH_SHORT).show();
    }
}

然后我调用片段 updateList() 中的函数来更新片段。

 public void updateList(List<Word> words) {

    // Hide loading indicator because the data has been loaded
    //View loadingIndicator = rootView.findViewById(R.id.loading_indicator);
    //loadingIndicator.setVisibility(View.GONE);

    //TextView loadingTextView = rootView.findViewById(R.id.loading_text_view);
    //loadingTextView.setVisibility(View.GONE);

    mAdapter.clear();

    if (words != null && !words.isEmpty()) {
        List<Word> wordsList = new ArrayList<>();

        for (int i = 0; i < words.size(); i++) {
            Word word = words.get(i);
            Log.v(LOG_TAG, "Current Word Category: " + word.getmCategory());
            if (word.getmCategory() != null) {
                if (word.getmCategory().contains("1"))
                    wordsList.add(word);
                Log.v(LOG_TAG, "Item Added: " + word.getmEnglishTranslation());
            }
        }
        //words.add(new Word("Uhr", "Clock", 2));
        //words.add(new Word("Bleistift","Pencil", 1 ));
        mAdapter.addAll(wordsList);
    } else {

        // Set empty state text to display "No earthquakes found."
        mEmptyStateTextView.setText(R.string.no_words);
        Toast.makeText(getActivity(), R.string.no_words, Toast.LENGTH_SHORT).show();
    }
}

我收到运行时错误

 FATAL EXCEPTION: main
Process: com.example.android.german, PID: 24298
                                                                        java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.android.german.WordAdapter.clear()' on a null object reference
at com.example.android.german.NounsFragment.updateList(NounsFragment.java:63)
                                                                            at com.example.android.german.MainActivity.onLoadFinished(MainActivity.java:83)
                                                                            at com.example.android.german.MainActivity.onLoadFinished(MainActivity.java:22)
                                                                            at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:483)
                                                                            at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:451)
                                                                            at android.content.Loader.deliverResult(Loader.java:144)
                                                                            at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:265)
                                                                            at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:92)
                                                                            at android.os.AsyncTask.finish(AsyncTask.java:651)
                                                                            at android.os.AsyncTask.-wrap1(AsyncTask.java)
                                                                            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

【问题讨论】:

  • 你在哪里创建了 mAdapter 对象?
  • @MiteshMachhoya 它是片段类中的全局变量
  • 请告诉我你是如何初始化的
  • 私有 WordAdapter mAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { .... mAdapter = new WordAdapter(getActivity(), new ArrayList()); ... }
  • 首先让我告诉你适配器没有提供任何 clear(),如果你在适配器类中创建了 clear(),那么请告诉我。

标签: android listview android-fragments


【解决方案1】:

在继续之前您需要了解两件事,第一个异步任务将在后台线程中执行操作,并使用 onPostExecute() 将从后台线程接收到的数据传递给主线程,其次,您需要更新UI何时成功接收数据。

现在您需要遵循简单的步骤 1.创建一个listview/recyclerview通过设置适配器和东西来显示数据。 2. 制作一个空的项目列表,如

List<Word> words = new ArrayList<>();

此步骤很重要,因为您不应重新创建列表或重新分配变量词。 3.在后台线程使用AsyncTask执行任务,在主线程使用onPostExecute()接收数据 4. 收到数据后将其传递给 MainActivity 或您想要将其传递给 MainActivity 的 Activity,可以使用 setupUI() 之类的方法完成,该方法返回 List。 5. 清除前一个列表以避免重复项目,然后使用 list.addAll() 将所有项目简单地添加到现有列表中。 6. 从那里调用 notifyDataSetChanged() 来更新 UI

mAdapter.notifyDatasetChanged()

【讨论】:

    猜你喜欢
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 2017-11-30
    • 1970-01-01
    相关资源
    最近更新 更多