/*
* Copyright 2014 Yaroslav Mytkalyk
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.docd.purefm.adapters;
import com.docd.purefm.ui.fragments.BrowserFragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.annotation.NonNull;
import java.util.HashMap;
/**
* FragmentPagerAdapter for BrowserFragments used by BrowserPagerActivity
*
* @author Doctoror
*/
public final class BrowserTabsAdapter extends FragmentStatePagerAdapter {
/**
* Prefix for manual saved Fragment state extra
*/
private static final String STATE_FRAGMENT_PREFIX = "BrowserTabsAdapter.state.FRAGMENT_";
/**
* Currently displayed Fragment reference array
*/
@NonNull
private final BrowserFragment[] mTabs;
/**
* Manually saved state to restore
*/
private Parcelable mToRestore;
/**
* ViewPager that uses this adapter
*/
private ViewPager mPager;
public BrowserTabsAdapter(@NonNull final FragmentManager fm) {
super(fm);
this.mTabs = new BrowserFragment[2];
}
/**
* Creates and returns Fragment for the position, adding it to reference array
* and tries to restore manual saved state if the Fragment for last position is returned
*
* @param position position to return Fragment associated for
* @return new Fragment associated with a specified position.
*/
@Override
public BrowserFragment getItem(final int position) {
final BrowserFragment f = new BrowserFragment();
this.mTabs[position] = f;
if (position == 1 && mToRestore != null) {
doRestoreManualState(mToRestore);
}
return f;
}
/**
* Sets ViewPager which uses this adapter.
*
* @param viewPager ViewPager that uses this adapter
*/
public void setViewPager(final ViewPager viewPager) {
mPager = viewPager;
}
/**
* {@inheritDoc}
*/
@Override
public int getCount() {
return mTabs.length;
}
/**
* For fragments being recreated in notifyDataSetChanged
*/
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
/**
* Saves manual state.
* This state should be manually restored by calling {@link #restoreManualState(android.os.Parcelable)}
*
* @return object holding the saved state
*/
public Parcelable saveManualState() {
final BrowserTabsAdapterState state = new BrowserTabsAdapterState();
for (int i = 0; i < mTabs.length; i++) {
final BrowserFragment tab = mTabs[i];
if (tab != null) {
final Bundle tabState = new Bundle();
tab.saveManualState(tabState);
state.mFragmentStates.put(STATE_FRAGMENT_PREFIX + i, tabState);
}
}
if (mPager != null) {
state.mCurrentPage = mPager.getCurrentItem();
}
return state;
}
/**
* Restores manual-saved state
*
* @param state State saved by {@link #saveManualState()}
*/
private void doRestoreManualState(final Parcelable state) {
mToRestore = null;
final BrowserTabsAdapterState savedState = (BrowserTabsAdapterState) state;
for (int i = 0; i < mTabs.length; i++) {
final BrowserFragment tab = mTabs[i];
if (tab != null) {
final Bundle tabState = savedState.mFragmentStates.get(STATE_FRAGMENT_PREFIX + i);
tab.restoreManualState(tabState);
}
}
if (mPager != null && savedState.mCurrentPage < getCount()) {
mPager.setCurrentItem(savedState.mCurrentPage);
}
}
/**
* Restores manual-saved state when all fragments were initialized
*
* @param state State saved by {@link #saveManualState()}
*/
public void restoreManualState(final Parcelable state) {
int initedFragments = 0;
for (final Object tab : mTabs) {
if (tab != null) {
initedFragments++;
}
}
if (initedFragments == 2) {
doRestoreManualState(state);
} else {
mToRestore = state;
}
}
/**
* Represents manual saved state
*/
private static final class BrowserTabsAdapterState implements Parcelable {
private final HashMap<String, Bundle> mFragmentStates;
private int mCurrentPage;
BrowserTabsAdapterState() {
this.mFragmentStates = new HashMap<>();
}
@SuppressWarnings("unchecked")
BrowserTabsAdapterState(final Parcel source) {
this.mFragmentStates = source.readHashMap(HashMap.class.getClassLoader());
this.mCurrentPage = source.readInt();
}
/**
* {@inheritDoc}
*/
@Override
public int describeContents() {
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeMap(this.mFragmentStates);
dest.writeInt(this.mCurrentPage);
}
public static final Creator<BrowserTabsAdapterState> CREATOR = new Creator<BrowserTabsAdapterState>() {
@NonNull
@Override
public BrowserTabsAdapterState createFromParcel(final Parcel source) {
return new BrowserTabsAdapterState(source);
}
@Override
public BrowserTabsAdapterState[] newArray(final int size) {
return new BrowserTabsAdapterState[size];
}
};
}
}