Android FragmentStatePagerAdapter - 切换标签后重叠片段

时间:2018-03-19 21:49:15

标签: listview overlapping fragmentstatepageradapter

我有一些重叠片段的问题。我使用带有FragmentStatePagerAdapter的TabLayout和3个Tabs(带有ListView的片段)。如果我在后台处理数据时更改选项卡并返回第一个选项卡,则会有两个重叠的片段。

我将AsyncTask的项目添加到Fragments中,代码如下。 第一个异步任务将第2个项添加到第一个选项卡,现在我切换到第三个选项卡。下一个任务将第4个其他项添加到第一个选项卡。如果我现在切换回第一个选项卡,则第一个添加的项目(或者更确切地说是片段)与新的第一个片段重叠。这包含所有6个项目......

如果我没有切换,直到添加了所有项目,所有标签都会正确显示。

我试图通过使用Fragmentmanager删除所有片段来避免这种情况,分离并附加片段以及FragmentStatePagerAdapter的notifyDataSetChanged()和ListviewFragment的BaseAdapter。没有任何效果。

在onCreateMethod中我这样做

         // Init Pager, TabLayout, Adapter
    ViewPager vpPager = (ViewPager) findViewById(R.id.viewpager);
    adapterViewPager = new FragmentAdapter(getSupportFragmentManager());
    vpPager.setAdapter(adapterViewPager);
    TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            selectedTab = tab.getPosition();
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
    tabLayout.setupWithViewPager(vpPager);

我的FragmentStatePagerAdapter就像这样

public class FragmentAdapter extends FragmentStatePagerAdapter {

private final List<ListViewFragment> fragments = new ArrayList<>();

public String getActiveCategory() {
    return ActiveCategory;
}

private String ActiveCategory = Helper.CATEGORY_SPIRITUOSEN;

public FragmentAdapter(android.support.v4.app.FragmentManager fm) {
    super(fm);
    fragments.add(new ListViewFragment());
    fragments.add(new ListViewFragment());
    fragments.add(new ListViewFragment());
}

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}

public void changeTabs(HashMap<String,ArrayList<OfferItem>> offerItemHashMap, String category){
    if (category == Helper.CATEGORY_A)
    {
        ActiveCategory = Helper.CATEGORY_A;
        fragments.clear();
        fragments.add(new ListViewFragment());
        fragments.get(0).addOfferList(offerItemHashMap.get(Helper.CATEGORY_FOUR));
    }
    else if (category == Helper.CATEGORY_B)
    {
        ActiveCategory = Helper.CATEGORY_B;
        fragments.clear();
        fragments.add(new ListViewFragment());
        fragments.add(new ListViewFragment());
        fragments.add(new ListViewFragment());
        fragments.get(0).addOfferList(offerItemHashMap.get(Helper.CATEGORY_ONE));
        fragments.get(1).addOfferList(offerItemHashMap.get(Helper.CATEGORY_TWO));
        fragments.get(2).addOfferList(offerItemHashMap.get(Helper.CATEGORY_THREE));
    }
    notifyDataSetChanged();
}

@Override
public ListViewFragment getItem(int position) {
    return fragments.get(position);
}

@Override
public int getCount() {
    return fragments.size();
}

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
        case 0:
            if (fragments.size() == 1)
                return "CAT FOUR";
            else
                return "CAT ONE";
        case 1:
            return "CAT TWO";
        case 2:
            return "CAT THREE";
        default:
            return "";
    }
}

}

我的ListView片段

    public class ListViewFragment extends Fragment {

public SearchableAdapter getmAdapter() {
    return mAdapter;
}

public void clearItemList(){
    getmOfferItemList().clear();
    if (mAdapter != null) {
        mAdapter.resetFilteredData();
        mAdapter.notifyDataSetChanged();
    }
}

private SwipeRefreshLayout mSwipeRefreshLayout;

private SearchableAdapter mAdapter;

private ListView listView;

private AlertDialog shareDialog;

public ArrayList<OfferItem> getmOfferItemList() {
    return mOfferItemList;
}

private final ArrayList<OfferItem> mOfferItemList = new ArrayList<>();

// Store instance variables based on arguments passed
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (mAdapter == null){
        mAdapter = new SearchableAdapter(getContext(),getmOfferItemList());
        mAdapter.notifyDataSetChanged();
    }
}

// Inflate the view for the fragment based on layout XML
@SuppressLint("ClickableViewAccessibility")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if (mAdapter == null)
        mAdapter = new SearchableAdapter(getContext(),getmOfferItemList());
    mAdapter.notifyDataSetChanged();
    View rootview = inflater.inflate(R.layout.listview_fragment_layout, container, false);
    mSwipeRefreshLayout = (SwipeRefreshLayout) rootview.findViewById(R.id.swipeRefreshLayout);
    mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                                                 @Override
                                                 public void onRefresh() {
                                                     Toast.makeText(getContext(),  getString(R.string.refresh),
                                                             Toast.LENGTH_LONG).show();
                                                     ((MainActivity)getActivity()).refresh();
                                                 }
                                             });
    return rootview;
}

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

public void addOfferList(ArrayList<OfferItem> offerItemList) {
    if (offerItemList != null) {
        mOfferItemList.addAll(offerItemList);
        if (mAdapter != null) {
            mAdapter.resetFilteredData();
            mAdapter.notifyDataSetChanged();
        }
    }
}

public void stopRefresh(){
    if (mSwipeRefreshLayout != null)
        mSwipeRefreshLayout.setRefreshing(false);
}

public void startRefreshing(){
    if (mSwipeRefreshLayout != null)
        mSwipeRefreshLayout.setRefreshing(true);
}

}

这是我在MainActivity中向ListViewFragments添加项目的方法

runOnUiThread(new AddOfferItemsTask(OfferItemList));

class AddOfferItemsTask implements Runnable {
    HashMap<String,ArrayList<OfferItem>> mOfferItemHashMap = new HashMap<>();
    AddOfferItemsTask(HashMap<String,ArrayList<OfferItem>> offerItemHashMap) {
        mOfferItemHashMap = offerItemHashMap;
    }
    public void run() {
        if (adapterViewPager.getCount()== 3) {
            if (adapterViewPager != null) {
                adapterViewPager.getItem(0).addOfferList(mOfferItemHashMap.get(Helper.CATEGORY_ONE));
                adapterViewPager.getItem(1).addOfferList(mOfferItemHashMap.get(Helper.CATEGORY_TWO));
                adapterViewPager.getItem(2).addOfferList(mOfferItemHashMap.get(Helper.CATEGORY_THREE));
            }
        }
        else{
            if (adapterViewPager != null) {
                adapterViewPager.getItem(0).addOfferList(mOfferItemHashMap.get(Helper.CATEGORY_FOUR));
            }
        }
        if (parsingReady()){
            searchFieldObj.setText(getString(R.string.searchfield_text));
            dismissProgressDialog();
        }
    }
}

我非常感谢任何提示

1 个答案:

答案 0 :(得分:0)

我认为问题在于适配器保存了ListView片段的不完整状态。由于异步任务,引用保留在内存中。

我将这行代码添加到我的ViewPager中:

vpPager.setOffscreenPageLimit(3);

因此所有3个片段都保存在内存中。现在问题解决了。我的名单不是很大,所以我认为这个解决方案是可以接受的。