package cl.monsoon.s1next.view.fragment;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import cl.monsoon.s1next.R;
import cl.monsoon.s1next.util.ResourceUtil;
import cl.monsoon.s1next.util.StringUtil;
import cl.monsoon.s1next.view.dialog.PageJumpDialogFragment;
import cl.monsoon.s1next.view.internal.PagerCallback;
import cl.monsoon.s1next.widget.FragmentStatePagerAdapter;
/**
* A base Fragment wraps {@link ViewPager} and provides related methods.
*/
abstract class BaseViewPagerFragment extends Fragment
implements PageJumpDialogFragment.OnPageJumpedListener, PagerCallback {
/**
* The serialization (saved instance state) Bundle key representing
* the total pages.
*/
private static final String STATE_TOTAL_PAGES = "total_pages";
private ViewPager mViewPager;
private int mTotalPages;
private MenuItem mMenuPageJump;
@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_view_pager, container, false);
}
@Override
@CallSuper
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState == null) {
mTotalPages = 1;
} else {
mTotalPages = savedInstanceState.getInt(STATE_TOTAL_PAGES);
}
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
// don't use getChildFragmentManager()
// because we can't retain Fragments (DataRetainedFragment)
// that are nested in other fragments
mViewPager.setAdapter(getPagerAdapter(getFragmentManager()));
}
@Override
@CallSuper
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
@CallSuper
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_view_pager, menu);
mMenuPageJump = menu.findItem(R.id.menu_page_jump);
preparePageJumpMenu();
}
@Override
@CallSuper
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_page_jump:
new PageJumpDialogFragment(mTotalPages, getCurrentPage()).show(
getChildFragmentManager(), PageJumpDialogFragment.TAG);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
@CallSuper
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_TOTAL_PAGES, mTotalPages);
}
abstract BaseFragmentStatePagerAdapter getPagerAdapter(FragmentManager fragmentManager);
public final int getTotalPages() {
return mTotalPages;
}
public final void setTotalPages(int totalPages) {
this.mTotalPages = totalPages;
mViewPager.getAdapter().notifyDataSetChanged();
preparePageJumpMenu();
}
final int getCurrentPage() {
return mViewPager.getCurrentItem();
}
final void setCurrentPage(int currentPage) {
mViewPager.setCurrentItem(currentPage);
}
@Override
@CallSuper
public void onPageJumped(int position) {
mViewPager.setCurrentItem(position);
}
/**
* Disables the page jump menu if only has one page.
*/
private void preparePageJumpMenu() {
if (mMenuPageJump == null) {
return;
}
if (mTotalPages == 1) {
mMenuPageJump.setEnabled(false);
} else {
mMenuPageJump.setEnabled(true);
}
}
final void setTitleWithPosition(int position) {
CharSequence titleWithoutPosition = getTitleWithoutPosition();
if (titleWithoutPosition == null) {
getActivity().setTitle(null);
return;
}
String titleWithPosition;
if (ResourceUtil.isRTL(getResources())) {
titleWithPosition = StringUtil.concatWithTwoSpaces(position + 1, titleWithoutPosition);
} else {
titleWithPosition = StringUtil.concatWithTwoSpaces(titleWithoutPosition, position + 1);
}
getActivity().setTitle(titleWithPosition);
}
@Nullable
abstract CharSequence getTitleWithoutPosition();
/**
* A base {@link FragmentStatePagerAdapter} wraps some implement.
*/
abstract class BaseFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
public BaseFragmentStatePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public final int getCount() {
return mTotalPages;
}
@Override
@CallSuper
public void setPrimaryItem(ViewGroup container, int position, Object object) {
setTitleWithPosition(position);
super.setPrimaryItem(container, position, object);
}
@Override
@CallSuper
public void destroyItem(ViewGroup container, int position, Object object) {
if (object instanceof BaseFragment) {
// We don't reuse Fragment in ViewPager and its retained Fragment
// because it is not cost-effective nowadays.
((BaseFragment) object).destroyRetainedFragment();
}
super.destroyItem(container, position, object);
}
}
}