package com.kaichunlin.transition.adapter;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewPager;
import android.view.View;
import com.kaichunlin.transition.DefaultTransitionManager;
import com.kaichunlin.transition.R;
import com.kaichunlin.transition.Transition;
import com.kaichunlin.transition.TransitionConfig;
import com.kaichunlin.transition.transformer.ViewTransformer;
import com.kaichunlin.transition.TransitionManager;
import com.kaichunlin.transition.ViewTransition;
import com.kaichunlin.transition.ViewTransitionBuilder;
import com.kaichunlin.transition.internal.TransitionController;
import com.kaichunlin.transition.util.TransitionStateLogger;
import java.util.List;
import java.util.WeakHashMap;
/**
* Adapter for ViewPager.
*/
public class OnPageChangeListenerAdapter extends AbstractAdapter implements ViewPager.OnPageChangeListener, ViewPager.PageTransformer {
public static final float LEFT_OF_CENTER = -1f;
public static final float CENTER = 0f;
public static final float RIGHT_OF_CENTER = 1f;
/**
* Keeps the left fragment in the center of the screen
*/
public static final ViewTransformer LEFT_IN_PLACE = new ViewTransformer() {
float oldX;
@Override
public void updateView(TransitionController controller, View target, float progress) {
float x = 0;
if (progress <= 0) {
x = target.getWidth() * -progress;
if (oldX == x) {
return;
}
oldX = x;
target.setTranslationX(x);
} else {
target.setTranslationX(0);
}
if (TransitionConfig.isDebug()) {
controller.getTransitionStateHolder().append(controller.getId() + "->" + target, this, "CUSTOM updateProgress=" + progress + ": \t[" + controller.getStart() + ".." + controller.getEnd() + "], translationX=" + x);
}
}
};
/**
* Keeps the right fragment in the center of the screen
*/
public static final ViewTransformer RIGHT_IN_PLACE = new ViewTransformer() {
float oldX;
@Override
public void updateView(TransitionController controller, View target, float progress) {
float x = 0;
if (progress > 0 && progress <= 1) {
x = target.getWidth() * -progress;
if (oldX == x) {
return;
}
oldX = x;
target.setTranslationX(x);
} else {
target.setTranslationX(0);
}
if (TransitionConfig.isDebug()) {
controller.getTransitionStateHolder().append(controller.getId() + "->" + target, this, "CUSTOM updateProgress=" + progress + ": \t[" + controller.getStart() + ".." + controller.getEnd() + "], translationX=" + x);
}
}
};
@CheckResult
public static OnPageChangeListenerAdapter bind(@NonNull ViewPager viewPager) {
return bind(viewPager, false);
}
@CheckResult
public static OnPageChangeListenerAdapter bind(@NonNull ViewPager viewPager, boolean reverseDrawingOrder) {
OnPageChangeListenerAdapter adapter = new OnPageChangeListenerAdapter(viewPager);
adapter.init(reverseDrawingOrder);
return adapter;
}
public static OnPageChangeListenerAdapter bindWithRotationYTransition(@NonNull ViewPager viewPager) {
return bindWithRotationYTransition(bind(viewPager));
}
public static OnPageChangeListenerAdapter bindWithRotationYTransition(@NonNull OnPageChangeListenerAdapter adapter) {
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, RIGHT_OF_CENTER).rotationY(0, -40).alpha(1f, 0.25f));
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, LEFT_OF_CENTER).rotationY(0, 40).alpha(1f, 0.25f));
return adapter;
}
public static OnPageChangeListenerAdapter bindWithZoomOutTransition(@NonNull ViewPager viewPager) {
return bindWithZoomOutTransition(bind(viewPager));
}
public static OnPageChangeListenerAdapter bindWithZoomOutTransition(@NonNull OnPageChangeListenerAdapter adapter) {
return adapter.addAndSetTransition(ViewTransitionBuilder.transit().scale(1f, 0.85f).alpha(1f, 0.5f), CENTER, RIGHT_OF_CENTER * 0.15f);
}
public static OnPageChangeListenerAdapter bindWithDepthTransition(@NonNull ViewPager viewPager) {
return bindWithDepthTransition(bind(viewPager, true));
}
public static OnPageChangeListenerAdapter bindWithDepthTransition(@NonNull OnPageChangeListenerAdapter adapter) {
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, RIGHT_OF_CENTER * 0.25f).scale(1f, 0.75f).id("RIGHT_1"));
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, RIGHT_OF_CENTER).alpha(1f, 0.5f).id("RIGHT_2").addViewTransformer(RIGHT_IN_PLACE));
return adapter;
}
public static OnPageChangeListenerAdapter bindWithRotate(@NonNull OnPageChangeListenerAdapter adapter) {
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, LEFT_OF_CENTER).id("LEFT_CENTER").addViewTransformer(LEFT_IN_PLACE));
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, LEFT_OF_CENTER * 0.5f).rotationY(0, -90).scale(1f, 0.5f).id("LEFT"));
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, RIGHT_OF_CENTER).id("RIGHT_CENTER").addViewTransformer(RIGHT_IN_PLACE));
adapter.addTransition(ViewTransitionBuilder.transit().range(CENTER, RIGHT_OF_CENTER * 0.5f).rotationY(0, 90).scale(1f, 0.5f).id("RIGHT"));
return adapter;
}
private static TransitionStateLogger getTransitionStateHolder(@NonNull View view) {
return (TransitionStateLogger) view.getTag(R.id.debug_id);
}
private final ViewPager mViewPager;
private final WeakHashMap<View, PageHolder> mTransitionListMap = new WeakHashMap<>();
public OnPageChangeListenerAdapter(ViewPager viewPager) {
mViewPager = viewPager;
}
public void init(boolean reverseDrawingOrder) {
mViewPager.addOnPageChangeListener(this);
mViewPager.setPageTransformer(reverseDrawingOrder, this);
}
public OnPageChangeListenerAdapter addAndSetTransition(@NonNull ViewTransitionBuilder builder) {
return addAndSetTransition(builder, CENTER, LEFT_OF_CENTER);
}
public OnPageChangeListenerAdapter addAndSetTransition(@NonNull ViewTransitionBuilder builder, float start, float end) {
ViewTransition vt = builder.range(start, end).id("LEFT").build();
getTransitionManager().addTransition(vt);
vt = builder.clone().range(-start, -end).id("RIGHT").build();
getTransitionManager().addTransition(vt);
return this;
}
public boolean startTransition() {
throw new UnsupportedOperationException();
}
public boolean startTransition(float progress) {
throw new UnsupportedOperationException();
}
private boolean startTransition(@NonNull View page) {
if (!getAdapterState().isTransiting()) {
notifyTransitionStart();
}
PageHolder holder = mTransitionListMap.get(page);
if (holder == null) {
holder = new PageHolder(page, getTransitionManager().getTransitions());
mTransitionListMap.put(page, holder);
List<Transition> transitionList = holder.mTransitionManager.getTransitions();
final int size = transitionList.size();
Transition transition;
for (int i = 0; i < size; i++) {
transition = transitionList.get(i);
transition.setUpdateStateAfterUpdateProgress(true);
transition.setTarget(page);
transition.startTransition();
}
}
return true;
}
public void updateProgress(float value) {
throw new UnsupportedOperationException();
}
protected void updateProgress(@NonNull View page, float value) {
PageHolder holder = mTransitionListMap.get(page);
if (holder == null) {
// if (TransitionConfig.isDebug()) {
// Log.e(getClass().getSimpleName(), "updateProgress: NULL");
// }
return;
}
holder.mTransitionManager.updateProgress(value);
}
public void stopTransition() {
getAdapterState().setTransiting(false);
notifyTransitionEnd();
for (PageHolder holder : mTransitionListMap.values()) {
holder.mTransitionManager.stopTransition();
}
mTransitionListMap.clear();
}
@Override
public void transformPage(@NonNull View page, float position) {
if (getAdapterState().isTransiting()) {
startTransition(page);
updateProgress(page, position);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_IDLE:
stopTransition();
break;
case ViewPager.SCROLL_STATE_DRAGGING:
case ViewPager.SCROLL_STATE_SETTLING:
getAdapterState().setTransiting(true);
break;
}
}
private static class PageHolder {
final TransitionManager mTransitionManager = new DefaultTransitionManager();
public PageHolder(@NonNull View page, @NonNull List<Transition> transitionsList) {
final int size = transitionsList.size();
for (int i = 0; i < size; i++) {
mTransitionManager.addTransition(transitionsList.get(i).clone());
}
}
}
}