blob: 30e11e3e27be4ef815f62ac2f084571aaf697e9c [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.android.messaging.ui;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.viewpager.widget.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import com.android.messaging.Factory;
import com.android.messaging.util.Assert;
import com.android.messaging.util.UiUtils;
import com.google.common.annotations.VisibleForTesting;
/**
* A PagerAdapter that provides a fixed number of paged Views provided by a fixed set of
* {@link PagerViewHolder}'s. This allows us to put a fixed number of Views, instead of fragments,
* into a given ViewPager.
*/
public class FixedViewPagerAdapter<T extends PagerViewHolder> extends PagerAdapter {
private final T[] mViewHolders;
public FixedViewPagerAdapter(final T[] viewHolders) {
Assert.notNull(viewHolders);
mViewHolders = viewHolders;
}
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
final PagerViewHolder viewHolder = getViewHolder(position);
final View view = viewHolder.getView(container);
if (view == null) {
return null;
}
view.setTag(viewHolder);
container.addView(view);
return viewHolder;
}
@Override
public void destroyItem(final ViewGroup container, final int position, final Object object) {
final PagerViewHolder viewHolder = getViewHolder(position);
final View destroyedView = viewHolder.destroyView();
if (destroyedView != null) {
container.removeView(destroyedView);
}
}
@Override
public int getCount() {
return mViewHolders.length;
}
@Override
public boolean isViewFromObject(final View view, final Object object) {
return view.getTag() == object;
}
public T getViewHolder(final int i) {
return getViewHolder(i, true /* rtlAware */);
}
@VisibleForTesting
public T getViewHolder(final int i, final boolean rtlAware) {
return mViewHolders[rtlAware ? getRtlPosition(i) : i];
}
@Override
public Parcelable saveState() {
// The paged views in the view pager gets created and destroyed as the user scrolls through
// them. By default, only the pages to the immediate left and right of the current visible
// page are realized. Moreover, if the activity gets destroyed and recreated, the pages are
// automatically destroyed. Therefore, in order to preserve transient page UI states that
// are not persisted in the DB we'd like to store them in a Bundle when views get
// destroyed. When the views get recreated, we rehydrate them by passing them the saved
// data. When the activity gets destroyed, it invokes saveState() on this adapter to
// add this saved Bundle to the overall saved instance state.
final Bundle savedViewHolderState = new Bundle(Factory.get().getApplicationContext()
.getClassLoader());
for (int i = 0; i < mViewHolders.length; i++) {
final Parcelable pageState = getViewHolder(i).saveState();
savedViewHolderState.putParcelable(getInstanceStateKeyForPage(i), pageState);
}
return savedViewHolderState;
}
@Override
public void restoreState(final Parcelable state, final ClassLoader loader) {
if (state instanceof Bundle) {
final Bundle restoredViewHolderState = (Bundle) state;
((Bundle) state).setClassLoader(Factory.get().getApplicationContext().getClassLoader());
for (int i = 0; i < mViewHolders.length; i++) {
final Parcelable pageState = restoredViewHolderState
.getParcelable(getInstanceStateKeyForPage(i));
getViewHolder(i).restoreState(pageState);
}
} else {
super.restoreState(state, loader);
}
}
public void resetState() {
for (int i = 0; i < mViewHolders.length; i++) {
getViewHolder(i).resetState();
}
}
private String getInstanceStateKeyForPage(final int i) {
return getViewHolder(i).getClass().getCanonicalName() + "_savedstate_" + i;
}
protected int getRtlPosition(final int position) {
if (UiUtils.isRtlMode()) {
return mViewHolders.length - 1 - position;
}
return position;
}
}