【问题标题】:Stop ListView scrolling in progress when fragment is going away当片段消失时停止 ListView 滚动
【发布时间】:2014-07-18 23:05:25
【问题描述】:

我有一个片段,它使用 ListView 显示多达数百个项目的列表。当用户导致列表长时间滚动并且在运动中按下返回时,会发生不好的事情(列表适配器的 getView() 中的空指针崩溃)。到目前为止,我能够找到以下解决方法:

@Override
public void onDestroyView() {
    super.onDestroyView();
    // prevent a crash when Back is pressed while a long list is still being scrolled
    mAdapter.clear();
    Log.d(TAG, "Cleared adapter");
}

让这项工作发挥作用的诀窍是让适配器使用源项目列表的克隆:

    mAdapter = new ListAdapter((MyListType)mMyList.clone());
    setListAdapter(mAdapter);

否则,对 mAdapter.clear() 的调用将清除源项目列表,因此当在方向更改时重新创建片段时,列表上将没有要显示的项目。然而,克隆如此大量的项目,即使是浅拷贝,也是一项昂贵的操作,我宁愿避免。

作为一种替代方法,我在 onDestroyView() 中尝试过

mListView.setScrollContainer(false);

但它也导致了崩溃。

是否有比上述解决方法更好的方法来实现对正在进行滚动的 ListView 的彻底销毁? (提示:试图通过安装监听器来延迟片段销毁以等待 ListView 停止滚动是不可接受的——用户希望立即响应 Back press。)

【问题讨论】:

  • 这不应该发生,你能告诉我们 Adapter#getView() 代码吗?
  • 我的 getView() 使用的是传统的 ViewHolder 模式,没有任何异国情调,所以我没有发布它。崩溃发生在 convertView = getActivity().getLayoutInflater().inflate(...) 由于片段销毁后的空指针,滚动仍在发生。
  • 我认为 getActivity() 返回 null,你必须检查它。我建议全局定义layoutInflater(在适配器中)然后在适配器构造函数中初始化它并在getView中使用它

标签: android android-fragments android-listview scroll ondestroy


【解决方案1】:

当你使用时

convertView = getActivity().getLayoutInflater().inflate(...) 

我认为getActivity() 返回null
要解决这个问题:

  1. 全局定义LayoutInflater(在Adapter中)
  2. 在适配器构造函数中初始化LayoutInflater
  3. getView() 方法中使用LayoutInflater

另外,我建议您始终将Adapter 定义为static class 或新的Java file

【讨论】:

  • 我尝试了这种方法,它似乎可以防止我的应用程序崩溃。但是,我仍然担心当片段已经消失时,列表滚动(以及通过适配器产生的相关视图)会继续进行。如果底层活动也消失了会发生什么——缓存它和适配器中的布局膨胀器没有用?
猜你喜欢
  • 2011-01-13
  • 2011-09-16
  • 2014-07-14
  • 2015-04-27
  • 2011-05-24
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多