1
0
Fork 0
mirror of https://github.com/MatomoCamp/matomocamp-companion-android.git synced 2024-09-19 16:13:46 +02:00

- Improved SlidingTabLayout to properly handle adapter change and refresh automatically on dataset changed.

- Fixed memory leak caused by keeping the PagerAdapter around after the view hierarchy has been destroyed.
This commit is contained in:
Christophe Beyls 2016-05-29 18:57:49 +02:00
parent ff140b060c
commit 97156d6061
3 changed files with 58 additions and 33 deletions

View file

@ -9,26 +9,19 @@ import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import be.digitalia.fosdem.R;
import com.example.android.common.view.SlidingTabLayout;
import be.digitalia.fosdem.R;
public class LiveFragment extends Fragment {
private LivePagerAdapter livePagerAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
livePagerAdapter = new LivePagerAdapter(getChildFragmentManager(), getResources());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_live, container, false);
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(livePagerAdapter);
pager.setAdapter(new LivePagerAdapter(getChildFragmentManager(), getResources()));
SlidingTabLayout slidingTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
slidingTabs.setViewPager(pager);
@ -52,10 +45,10 @@ public class LiveFragment extends Fragment {
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new NextLiveListFragment();
case 1:
return new NowLiveListFragment();
case 0:
return new NextLiveListFragment();
case 1:
return new NowLiveListFragment();
}
return null;
}
@ -63,10 +56,10 @@ public class LiveFragment extends Fragment {
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return resources.getString(R.string.next);
case 1:
return resources.getString(R.string.now);
case 0:
return resources.getString(R.string.next);
case 1:
return resources.getString(R.string.now);
}
return null;
}

View file

@ -33,19 +33,18 @@ public class TracksFragment extends Fragment implements LoaderCallbacks<List<Day
View emptyView;
ViewPager pager;
SlidingTabLayout slidingTabs;
DaysAdapter daysAdapter;
}
private static final int DAYS_LOADER_ID = 1;
private static final String PREF_CURRENT_PAGE = "tracks_current_page";
private DaysAdapter daysAdapter;
private ViewHolder holder;
private int savedCurrentPage = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
daysAdapter = new DaysAdapter(getChildFragmentManager());
if (savedInstanceState == null) {
// Restore the current page from preferences
@ -62,6 +61,7 @@ public class TracksFragment extends Fragment implements LoaderCallbacks<List<Day
holder.emptyView = view.findViewById(android.R.id.empty);
holder.pager = (ViewPager) view.findViewById(R.id.pager);
holder.slidingTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
holder.daysAdapter = new DaysAdapter(getChildFragmentManager());
return view;
}
@ -131,20 +131,19 @@ public class TracksFragment extends Fragment implements LoaderCallbacks<List<Day
@Override
public void onLoadFinished(Loader<List<Day>> loader, List<Day> data) {
daysAdapter.setDays(data);
holder.daysAdapter.setDays(data);
final int totalPages = daysAdapter.getCount();
final int totalPages = holder.daysAdapter.getCount();
if (totalPages == 0) {
holder.contentView.setVisibility(View.GONE);
holder.emptyView.setVisibility(View.VISIBLE);
holder.pager.clearOnPageChangeListeners();
} else {
holder.contentView.setVisibility(View.VISIBLE);
holder.emptyView.setVisibility(View.GONE);
if (holder.pager.getAdapter() == null) {
holder.pager.setAdapter(daysAdapter);
holder.pager.setAdapter(holder.daysAdapter);
holder.slidingTabs.setViewPager(holder.pager);
}
holder.slidingTabs.setViewPager(holder.pager);
if (savedCurrentPage != -1) {
holder.pager.setCurrentItem(Math.min(savedCurrentPage, totalPages - 1), false);
savedCurrentPage = -1;

View file

@ -20,6 +20,7 @@ package com.example.android.common.view;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Typeface;
import android.os.Build;
import android.support.annotation.ColorInt;
@ -59,6 +60,9 @@ public class SlidingTabLayout extends HorizontalScrollView {
private ColorStateList mTextColor;
private ViewPager mViewPager;
private PagerAdapter mAdapter;
private final InternalViewPagerListener mPageChangeListener = new InternalViewPagerListener();
private final PagerAdapterObserver mPagerAdapterObserver = new PagerAdapterObserver();
private TabListener mTabListener;
@ -148,18 +152,32 @@ public class SlidingTabLayout extends HorizontalScrollView {
}
/**
* Sets the associated view pager. Note that the assumption here is that the pager content
* (number of tabs and tab titles) does not change after this call has been made.
* Sets the associated view pager. The ViewPager must have an adapter set.
* The SlidingTabLayout will then listen for changes and update the tabs automatically.
*/
public void setViewPager(ViewPager viewPager) {
mViewPager = viewPager;
if (mViewPager != null) {
mViewPager.removeOnPageChangeListener(mPageChangeListener);
mAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
}
if (viewPager != null) {
viewPager.addOnPageChangeListener(new InternalViewPagerListener());
PagerAdapter adapter = viewPager.getAdapter();
if (adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
}
mViewPager = viewPager;
mAdapter = adapter;
mPageChangeListener.reset();
viewPager.addOnPageChangeListener(mPageChangeListener);
adapter.registerDataSetObserver(mPagerAdapterObserver);
} else {
mViewPager = null;
mAdapter = null;
}
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
private void notifyDataSetChanged() {
mTabStrip.removeAllViews();
if (mViewPager != null) {
populateTabStrip();
@ -167,8 +185,7 @@ public class SlidingTabLayout extends HorizontalScrollView {
}
private void populateTabStrip() {
final PagerAdapter adapter = mViewPager.getAdapter();
final int adapterCount = adapter.getCount();
final int adapterCount = mAdapter.getCount();
final View.OnClickListener tabClickListener = new TabClickListener();
final LayoutInflater inflater = LayoutInflater.from(getContext());
final int currentItem = mViewPager.getCurrentItem();
@ -203,7 +220,7 @@ public class SlidingTabLayout extends HorizontalScrollView {
lp.weight = 1;
}
tabTitleView.setText(adapter.getPageTitle(i));
tabTitleView.setText(mAdapter.getPageTitle(i));
tabView.setFocusable(true);
tabView.setOnClickListener(tabClickListener);
@ -270,6 +287,22 @@ public class SlidingTabLayout extends HorizontalScrollView {
mTabStrip.getChildAt(i).setSelected(position == i);
}
}
public void reset() {
mScrollState = ViewPager.SCROLL_STATE_IDLE;
}
}
private class PagerAdapterObserver extends DataSetObserver {
@Override
public void onChanged() {
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
notifyDataSetChanged();
}
}
private class TabClickListener implements View.OnClickListener {