0

I have some problems with overlapping Fragments. I use a TabLayout with a FragmentStatePagerAdapter and 3 Tabs (Fragments with ListView). If I change the tabs while i processing data in background and go back to the first tab there are two overlapping fragments.

I add the items by AsyncTask to the Fragments, code below. The first Async Task adds 2 items to the first tab, now i switch to the third tab. The next Task adds 4 other items to the first tab. If i now switch back to the first tab, the 2 first added items (or rather the fragment) are overlapping a new first fragment. This contains all 6 items...

If i doesn't switch until all items added all tabs are shown correctly.

I tried to avoid this by removing all fragments with the Fragmentmanager, detach and attach the fragments and the notifyDataSetChanged() of the FragmentStatePagerAdapter and the BaseAdapter of my ListviewFragment. Nothing worked.

In the onCreateMethod i do this

         // 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);

My FragmentStatePagerAdapter is just like this

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 "";
    }
}

}

My ListView Fragment

    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);
}

}

This is how i add items to the ListViewFragments in my MainActivity

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();
        }
    }
}

I am very thankful for any tip

Neo1989
  • 21
  • 3

1 Answers1

0

I think the problem was that the Adapter saved the incomplete state of the ListView Fragment. The reference was kept in memory because of the async task.

I added this line of code to my ViewPager:

vpPager.setOffscreenPageLimit(3);

So all 3 Fragments were kept in memory. Now the Problem is solved. My lists are not very big, so i think this solution acceptable.

Neo1989
  • 21
  • 3