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:
parent
ff140b060c
commit
97156d6061
3 changed files with 58 additions and 33 deletions
|
@ -9,26 +9,19 @@ import android.support.v4.view.ViewPager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import be.digitalia.fosdem.R;
|
|
||||||
|
|
||||||
import com.example.android.common.view.SlidingTabLayout;
|
import com.example.android.common.view.SlidingTabLayout;
|
||||||
|
|
||||||
|
import be.digitalia.fosdem.R;
|
||||||
|
|
||||||
public class LiveFragment extends Fragment {
|
public class LiveFragment extends Fragment {
|
||||||
|
|
||||||
private LivePagerAdapter livePagerAdapter;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
livePagerAdapter = new LivePagerAdapter(getChildFragmentManager(), getResources());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_live, container, false);
|
View view = inflater.inflate(R.layout.fragment_live, container, false);
|
||||||
|
|
||||||
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
|
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);
|
SlidingTabLayout slidingTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
|
||||||
slidingTabs.setViewPager(pager);
|
slidingTabs.setViewPager(pager);
|
||||||
|
|
||||||
|
|
|
@ -33,19 +33,18 @@ public class TracksFragment extends Fragment implements LoaderCallbacks<List<Day
|
||||||
View emptyView;
|
View emptyView;
|
||||||
ViewPager pager;
|
ViewPager pager;
|
||||||
SlidingTabLayout slidingTabs;
|
SlidingTabLayout slidingTabs;
|
||||||
|
DaysAdapter daysAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int DAYS_LOADER_ID = 1;
|
private static final int DAYS_LOADER_ID = 1;
|
||||||
private static final String PREF_CURRENT_PAGE = "tracks_current_page";
|
private static final String PREF_CURRENT_PAGE = "tracks_current_page";
|
||||||
|
|
||||||
private DaysAdapter daysAdapter;
|
|
||||||
private ViewHolder holder;
|
private ViewHolder holder;
|
||||||
private int savedCurrentPage = -1;
|
private int savedCurrentPage = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
daysAdapter = new DaysAdapter(getChildFragmentManager());
|
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
// Restore the current page from preferences
|
// 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.emptyView = view.findViewById(android.R.id.empty);
|
||||||
holder.pager = (ViewPager) view.findViewById(R.id.pager);
|
holder.pager = (ViewPager) view.findViewById(R.id.pager);
|
||||||
holder.slidingTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
|
holder.slidingTabs = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
|
||||||
|
holder.daysAdapter = new DaysAdapter(getChildFragmentManager());
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -131,20 +131,19 @@ public class TracksFragment extends Fragment implements LoaderCallbacks<List<Day
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<List<Day>> loader, List<Day> data) {
|
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) {
|
if (totalPages == 0) {
|
||||||
holder.contentView.setVisibility(View.GONE);
|
holder.contentView.setVisibility(View.GONE);
|
||||||
holder.emptyView.setVisibility(View.VISIBLE);
|
holder.emptyView.setVisibility(View.VISIBLE);
|
||||||
holder.pager.clearOnPageChangeListeners();
|
|
||||||
} else {
|
} else {
|
||||||
holder.contentView.setVisibility(View.VISIBLE);
|
holder.contentView.setVisibility(View.VISIBLE);
|
||||||
holder.emptyView.setVisibility(View.GONE);
|
holder.emptyView.setVisibility(View.GONE);
|
||||||
if (holder.pager.getAdapter() == null) {
|
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) {
|
if (savedCurrentPage != -1) {
|
||||||
holder.pager.setCurrentItem(Math.min(savedCurrentPage, totalPages - 1), false);
|
holder.pager.setCurrentItem(Math.min(savedCurrentPage, totalPages - 1), false);
|
||||||
savedCurrentPage = -1;
|
savedCurrentPage = -1;
|
||||||
|
|
|
@ -20,6 +20,7 @@ package com.example.android.common.view;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
|
@ -59,6 +60,9 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
private ColorStateList mTextColor;
|
private ColorStateList mTextColor;
|
||||||
|
|
||||||
private ViewPager mViewPager;
|
private ViewPager mViewPager;
|
||||||
|
private PagerAdapter mAdapter;
|
||||||
|
private final InternalViewPagerListener mPageChangeListener = new InternalViewPagerListener();
|
||||||
|
private final PagerAdapterObserver mPagerAdapterObserver = new PagerAdapterObserver();
|
||||||
|
|
||||||
private TabListener mTabListener;
|
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
|
* Sets the associated view pager. The ViewPager must have an adapter set.
|
||||||
* (number of tabs and tab titles) does not change after this call has been made.
|
* The SlidingTabLayout will then listen for changes and update the tabs automatically.
|
||||||
*/
|
*/
|
||||||
public void setViewPager(ViewPager viewPager) {
|
public void setViewPager(ViewPager viewPager) {
|
||||||
mViewPager = viewPager;
|
if (mViewPager != null) {
|
||||||
|
mViewPager.removeOnPageChangeListener(mPageChangeListener);
|
||||||
|
mAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
|
||||||
|
}
|
||||||
if (viewPager != null) {
|
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();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyDataSetChanged() {
|
private void notifyDataSetChanged() {
|
||||||
mTabStrip.removeAllViews();
|
mTabStrip.removeAllViews();
|
||||||
if (mViewPager != null) {
|
if (mViewPager != null) {
|
||||||
populateTabStrip();
|
populateTabStrip();
|
||||||
|
@ -167,8 +185,7 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateTabStrip() {
|
private void populateTabStrip() {
|
||||||
final PagerAdapter adapter = mViewPager.getAdapter();
|
final int adapterCount = mAdapter.getCount();
|
||||||
final int adapterCount = adapter.getCount();
|
|
||||||
final View.OnClickListener tabClickListener = new TabClickListener();
|
final View.OnClickListener tabClickListener = new TabClickListener();
|
||||||
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
final int currentItem = mViewPager.getCurrentItem();
|
final int currentItem = mViewPager.getCurrentItem();
|
||||||
|
@ -203,7 +220,7 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
lp.weight = 1;
|
lp.weight = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tabTitleView.setText(adapter.getPageTitle(i));
|
tabTitleView.setText(mAdapter.getPageTitle(i));
|
||||||
tabView.setFocusable(true);
|
tabView.setFocusable(true);
|
||||||
tabView.setOnClickListener(tabClickListener);
|
tabView.setOnClickListener(tabClickListener);
|
||||||
|
|
||||||
|
@ -270,6 +287,22 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
mTabStrip.getChildAt(i).setSelected(position == i);
|
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 {
|
private class TabClickListener implements View.OnClickListener {
|
||||||
|
|
Loading…
Reference in a new issue