package org.holoeverywhere.app;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import org.holoeverywhere.app.TabSwipeController.TabInfo;
import org.holoeverywhere.widget.ViewPager;
import java.util.ArrayList;
import java.util.List;
public abstract class TabSwipeController implements TabSwipeInterface<TabInfo> {
private final ActionBar mActionBar;
private final Context mContext;
private final FragmentManager mFragmentManager;
private TabSwipeAdapter mAdapter;
private OnTabSelectedListener mOnTabSelectedListener;
private int mPrevNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
private boolean mSmoothScroll = true;
private boolean mSwipeEnabled = true;
private List<TabInfo> mTabs = new ArrayList<TabInfo>();
private ViewPager mViewPager;
public TabSwipeController(Context context, FragmentManager fragmentManager, ActionBar actionBar) {
if (context == null || fragmentManager == null || actionBar == null) {
throw new NullPointerException();
}
mContext = context;
mFragmentManager = fragmentManager;
mActionBar = actionBar;
if (mActionBar.getTabCount() > 0) {
throw new IllegalStateException(
"TabSwipeController doesn't support multiplue tab controllers");
}
mPrevNavigationMode = mActionBar.getNavigationMode();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
@Override
public int getCurrentTab() {
return mActionBar.getSelectedNavigationIndex();
}
@Override
public void setCurrentTab(int position) {
dispatchTabSelected(Math.max(0, Math.min(position, mTabs.size() - 1)));
}
@Override
public TabInfo getTabAt(int position) {
return mTabs.get(position);
}
@Override
public TabInfo addTab(CharSequence title, Class<? extends Fragment> fragmentClass) {
return addTab(title, fragmentClass, null);
}
@Override
public TabInfo addTab(CharSequence title, Class<? extends Fragment> fragmentClass,
Bundle fragmentArguments) {
TabInfo info = new TabInfo();
info.mTitle = title;
info.mFragmentClass = fragmentClass;
info.mFragmentArguments = fragmentArguments;
return addTab(info);
}
@Override
public TabInfo addTab(int title, Class<? extends Fragment> fragmentClass) {
return addTab(mContext.getText(title), fragmentClass, null);
}
@Override
public TabInfo addTab(int title, Class<? extends Fragment> fragmentClass,
Bundle fragmentArguments) {
return addTab(mContext.getText(title), fragmentClass, fragmentArguments);
}
@Override
public TabInfo addTab(TabInfo tabInfo) {
mTabs.add(tabInfo);
mActionBar.addTab(makeActionBarTab(tabInfo));
notifyChanged();
return tabInfo;
}
@Override
public TabInfo addTab(TabInfo tabInfo, int position) {
mTabs.add(position, tabInfo);
mActionBar.addTab(makeActionBarTab(tabInfo), position);
notifyChanged();
return tabInfo;
}
public void bind(ViewPager viewPager) {
if (mViewPager != null) {
mViewPager.setAdapter(null);
mViewPager.setOnPageChangeListener(null);
}
mViewPager = viewPager;
if (mViewPager != null) {
if (mAdapter == null) {
mAdapter = new TabSwipeAdapter(mFragmentManager);
}
reloadTabs();
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(mAdapter);
mViewPager.setSwipeEnabled(mSwipeEnabled);
}
}
private void dispatchTabSelected(int position) {
boolean notify = false;
if (mViewPager.getCurrentItem() != position) {
mViewPager.setCurrentItem(position, mSmoothScroll);
notify = true;
}
if (mActionBar.getSelectedNavigationIndex() != position) {
mActionBar.selectTab(mActionBar.getTabAt(position));
notify = true;
}
if (notify) {
onTabSelected(position);
}
}
@Override
public OnTabSelectedListener getOnTabSelectedListener() {
return mOnTabSelectedListener;
}
@Override
public void setOnTabSelectedListener(OnTabSelectedListener onTabSelectedListener) {
mOnTabSelectedListener = onTabSelectedListener;
}
@Override
public boolean isSmoothScroll() {
return mSmoothScroll;
}
/**
* Smooth scroll of ViewPager when user click on tab
*/
@Override
public void setSmoothScroll(boolean smoothScroll) {
mSmoothScroll = smoothScroll;
}
@Override
public boolean isSwipeEnabled() {
return mSwipeEnabled;
}
@Override
public void setSwipeEnabled(boolean swipeEnabled) {
if (mSwipeEnabled == swipeEnabled) {
return;
}
mSwipeEnabled = swipeEnabled;
if (mViewPager != null) {
mViewPager.setSwipeEnabled(swipeEnabled);
}
}
protected Tab makeActionBarTab(TabInfo tabInfo) {
Tab tab = mActionBar.newTab();
tab.setText(tabInfo.mTitle);
tab.setTabListener(mAdapter);
return tab;
}
private void notifyChanged() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
public void onDestroyView() {
mActionBar.removeAllTabs();
mActionBar.setNavigationMode(mPrevNavigationMode);
}
protected abstract void onHandleTabs();
public void onTabSelected(int position) {
if (mOnTabSelectedListener != null) {
mOnTabSelectedListener.onTabSelected(position);
}
}
@Override
public void reloadTabs() {
removeAllTabs();
onHandleTabs();
}
@Override
public void removeAllTabs() {
mActionBar.removeAllTabs();
mTabs.clear();
notifyChanged();
}
@Override
public TabInfo removeTab(int position) {
TabInfo tabInfo = mTabs.remove(position);
mActionBar.removeTabAt(position);
notifyChanged();
return tabInfo;
}
@Override
public TabInfo removeTab(TabInfo tabInfo) {
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tabInfo) {
return removeTab(i);
}
}
return tabInfo;
}
public static class TabInfo implements TabSwipeInterface.ITabInfo<TabInfo> {
private Bundle mFragmentArguments;
private Class<? extends Fragment> mFragmentClass;
private CharSequence mTitle;
@Override
public Bundle getFragmentArguments() {
return mFragmentArguments;
}
@Override
public TabInfo setFragmentArguments(Bundle fragmentArguments) {
mFragmentArguments = fragmentArguments;
return this;
}
@Override
public Class<? extends Fragment> getFragmentClass() {
return mFragmentClass;
}
@Override
public TabInfo setFragmentClass(Class<? extends Fragment> fragmentClass) {
mFragmentClass = fragmentClass;
return this;
}
@Override
public CharSequence getTitle() {
return mTitle;
}
@Override
public TabInfo setTitle(CharSequence title) {
mTitle = title;
return this;
}
}
private final class TabSwipeAdapter extends FragmentStatePagerAdapter implements
OnPageChangeListener, TabListener {
public TabSwipeAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
final TabInfo info = mTabs.get(position);
return Fragment.instantiate(info.mFragmentClass, info.mFragmentArguments);
}
@Override
public void onPageScrolled(int position, float percent, int pixels) {
// Do nothing
}
@Override
public void onPageScrollStateChanged(int scrollState) {
// Do nothing
}
@Override
public void onPageSelected(int position) {
dispatchTabSelected(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// Do nothing
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
dispatchTabSelected(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// Do nothing
}
}
}