2

我有一个通过 ListFragments 进行分页的 ViewPager。每页是一个特定的日期,每页中的列表包含多个类别的项目。

用户可以随时通过对话框切换显示的类别。这对于在类别列表更改后实例化的页面(及其片段)来说不是问题,因为它们是使用新设置实例化的(在它们更改时传递给 FragmentStatePagerAdapter)。

但我的问题是用户更改类别列表时已经实例化的所有页面。这些页面(或者更确切地说,它们的片段)需要立即刷新。为此,我需要能够调用方法 (changeData()) 将新类别设置传递给每个 ListFragment,然后调用 notifyDataSetChanged() 以便他们刷新视图。

如何对 FragmentStatePagerAdapter 中已实例化的片段执行此调用?

这是我用于填充页面的 FragmentStatePagerAdapter 和 ListFragments 的代码:

public static class ListingPagerAdapter extends FragmentStatePagerAdapter {

    private Date mStartingDate;
    private String mListingCat;
    private Calendar cal;

    public ListingPagerAdapter(FragmentManager fm, Date startDate, String listingCat) {
        super(fm);
        mStartingDate = startDate;
        mListingCat = listingCat;
        cal = Calendar.getInstance();
    }

    public void setListingCategories(String categories) {
        mListingCat = categories;
        //notifyDataSetChanged();
    }

    @Override
    public Fragment getItem(int i) {
        cal.setTime(mStartingDate);
        cal.add(Calendar.DAY_OF_YEAR,i);
        Bundle fragmentArgs = new Bundle();
        fragmentArgs.putString(Utils.DIRECTORY_CAT_STORE_KEY, mListingCat);
        fragmentArgs.putLong(Utils.FILTER_DATE_STORAGE_KEY, cal.getTimeInMillis());
        ListingFragment listingFragment = ListingFragment.newInstance(fragmentArgs);
        return listingFragment;
    }

    @Override
    public int getItemPosition(Object object) {
        if (object instanceof ListingFragment) {
            ((ListingFragment) object).changeData(mListingCat, 0);
        }
        return super.getItemPosition(object);
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }
}

您会注意到上面的 seListingCategories() 方法,我使用该方法在适配器上设置类别字符串,因此每个新实例化的 Fragment 都有要显示的正确类别。在相同的方法中,您会注意到在适配器上调用 notifyDataSetChanged() 的行已被注释掉。

该调用导致适配器为内存中的每个 Fragment(当前页面和所有其他尚未销毁的页面)调用 getItemPosition(),我借此机会以这种方式对它们调用 changeData()。并且视图已成功更新。

但是,似乎已经销毁的片段(具有保存状态)只是恢复到没有更新类别列表的保存状态。更不用说这似乎有点矫枉过正。当我可以更新现有对象时,为什么要销毁并重新创建每个片段?

无论如何,下面是 FragmentStatePageAdapter 中使用的 ListFragment 类:

public static class ListingFragment extends ListFragment {

    private Map<String,String> filters;
    private JSONArray mListingData;

    public static ListingFragment newInstance(Bundle args) {
        ListingFragment lf = new ListingFragment();
        lf.setArguments(args);
        return lf;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        if (filters == null)
            filters = new HashMap<String, String>();

        if (savedInstanceState != null) {
            filters.put(Utils.DIRECTORY_CAT_STORE_KEY, savedInstanceState.getString(Utils.DIRECTORY_CAT_STORE_KEY));
            filters.put(Utils.FILTER_DATE_STORAGE_KEY, ""+savedInstanceState.getLong(Utils.FILTER_DATE_STORAGE_KEY));
        }
        else {
            filters.put(Utils.DIRECTORY_CAT_STORE_KEY, getArguments().getString(Utils.DIRECTORY_CAT_STORE_KEY));
            filters.put(Utils.FILTER_DATE_STORAGE_KEY, ""+getArguments().getLong(Utils.FILTER_DATE_STORAGE_KEY));
        }

        mListingData = Utils.getDataByTypeAndFilters(getResources().getString(R.string.nav_promotions), filters, getActivity().getResources());
        setListAdapter(new PromotionListingAdapter(getActivity(), mListingData));

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(Utils.DIRECTORY_CAT_STORE_KEY, filters.get(Utils.DIRECTORY_CAT_STORE_KEY));
        outState.putLong(Utils.FILTER_DATE_STORAGE_KEY, Long.parseLong(filters.get(Utils.FILTER_DATE_STORAGE_KEY)));
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onListItemClick(ListView l, View view, int position, long id) {
        Intent newDetailIntent = new Intent(getActivity(), PromotionDetails.class);
        newDetailIntent.putExtra(Utils.LISTING_OBJECT_STORE_KEY, ((JSONObject) l.getAdapter().getItem(position)).toString());
        startActivity(newDetailIntent);
    }

    public void changeData(String category, long date) {
        if (category != null)
            filters.put(Utils.DIRECTORY_CAT_STORE_KEY, category);
        if (date > 0)
            filters.put(Utils.FILTER_DATE_STORAGE_KEY, ""+date);
        mListingData = Utils.getDataByTypeAndFilters(getResources().getString(R.string.nav_promotions), filters, getActivity().getResources());
        PromotionListingAdapter promotionsAdapter = ((PromotionListingAdapter) getListAdapter());
        promotionsAdapter.setData(mListingData);
        promotionsAdapter.notifyDataSetChanged();
    }
}

提前感谢您的帮助!

4

0 回答 0