ArrayAdapter notifyDataSetChanged()在片段中不起作用

时间:2014-10-23 18:36:06

标签: android android-fragments

我有一个数组适配器和相关代码,在活动中工作正常。我正在迁移到使用片段,现在它不会更新。使用操作栏选项卡,如果我第一次填充列表并显示正常时转到我的选项卡。如果我转到另一个选项卡并返回,则会填充列表,但列表视图为空。

如果我在第一次访问期间向列表添加内容,则列表会更新。如果我离开,请回来,并添加一个未显示的项目。通过将图像保存到数据库然后调用refreshGallery()来将项目添加到列表中。

@Override
public onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View v = inflater.inflate(R.layout.inspection_images, container, false);
  mListView = (ListView) v.findViewById(R.id.inspection_images_list);
  setInspectionImages(mInspection.getInspectionImages());

  return v;
}

@Override
public void onResume() {
  refreshGallery();
}

public void refreshGallery() {
  mInspectionImages = mInspection.getInspectionImages();
  setInspectionImages(mInspectionImages());
}

public void setInspectionImages(ArrayList<InspectionImage> images) {
  if (null == mArrayAdapter) {
    mArrayAdapter = new InspectionImageAdapter(getActivity().getApplicationContext(), R.layout.inspection_image_list_item, images);
    mListView.setAdapter(mArrayAdapter);
  }
  else {
    mArrayAdapter.clear();
    addInspectionImagesToList(images);
  }
}

public void addInspectionImagesToList(ArrayList<InpsectionImage> images) {
  mArrayAdapter.addAll(images);
  mArrayAdapter.notifyDataSetChanged();
}

1 个答案:

答案 0 :(得分:2)

假设您已根据Android developers guide实施onTabSelected(),即:

public void onTabSelected(Tab tab, FragmentTransaction ft) {
    // Check if the fragment is already initialized
    if (mFragment == null) {
        // If not, instantiate and add it to the activity
        mFragment = Fragment.instantiate(mActivity, mClass.getName());
        ft.add(android.R.id.content, mFragment, mTag);
    } else {
        // If it exists, simply attach it in order to show it
        ft.attach(mFragment);
    }
}

当您显示片段第一个时间时会发生什么:

  1. onTabSelected()中,mFragment为空,而新的实例化
  2. 创建的片段已附加到mActivity
  3. 调用片段onCreateView(),创建mListView,创建mArrayAdapter并填充mListView并附加到mListView并返回onTabSelected()
  4. 列表视图项目可见且一切都很花花公子
  5. 切换到另一个标签然后切换回同一个标签后会发生什么:

    1. mFragment中,ft.attach(mFragment);存在,因此只执行mActivity(与之前相同的片段,即没有创建新片段
    2. 现有片段再次附加到onCreateView()
    3. 调用片段的mListView(检查fragment lifecycle以及如果您想知道原因为片段attached会发生什么情况),新{{1}创建了<}> ,调用了setInspectionImages()并且mArrayAdapter 已存在,因此已填充但从未附加到新mListView }
    4. 布局中显示的mListView没有附加任何适配器,并且您的所有操作都填充了一个现在不相关的数组适配器
    5. 首先,您不必在每个onResume()上重新填充适配器。在创建时执行一次(我会将其放在onActivityCreated()中)并在必要时更新它。

      然后您不需要检查是否存在mArrayAdapter,只需在onActivityCreated()中创建它。

      如果您想保留当前的设计,请确保在列表视图消失后取消其引用:

      @Override
      public void onDestroyView () {
          mArrayAdapter = null;
          mListView = null;
      }