Update TransitionCurtain
This commit is contained in:
1 parent
75a6ffdd13
commit
525ce72ec1
14 files changed
+423
-280
No files matched your search
@@ -57,7 +57,7 @@ public class StartActivity extends AbsActionBarActivity {
|
||||
Intent intent = new Intent(StartActivity.this, ContentActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}, 3000);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,16 @@
|
||||
|
||||
package com.hippo.ehviewer.ui.scene;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.ehviewer.ui.ContentActivity;
|
||||
import com.hippo.ehviewer.widget.ContentLayout;
|
||||
import com.hippo.scene.Scene;
|
||||
import com.hippo.scene.TransitionCurtain;
|
||||
|
||||
public class GalleryListScene extends Scene {
|
||||
|
||||
@@ -36,7 +37,6 @@ public class GalleryListScene extends Scene {
|
||||
|
||||
private ContentLayout mContentLayout;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -48,6 +48,23 @@ public class GalleryListScene extends Scene {
|
||||
mContentLayout = (ContentLayout) findViewById(R.id.content_layout);
|
||||
|
||||
mContentLayout.showText("无法连接网络");
|
||||
|
||||
View view = getSceneView();
|
||||
assert view != null;
|
||||
view.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
TransitionCurtain tc = new TransitionCurtain(
|
||||
new TransitionCurtain.ViewPair[]{
|
||||
new TransitionCurtain.ViewPair(R.id.haha, R.id.haha),
|
||||
new TransitionCurtain.ViewPair(R.id.bbbbbb, R.id.bbbbbb)
|
||||
}
|
||||
);
|
||||
|
||||
startScene(TestScene.class, null, tc);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
protected void onGetFitPaddingBottom(int b) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.AbsoluteLayout;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.hippo.util.AssertUtils;
|
||||
@@ -48,7 +49,7 @@ public abstract class Scene {
|
||||
|
||||
private @Nullable Curtain mCurtain;
|
||||
|
||||
private @Nullable FrameLayout mSceneView;
|
||||
private @Nullable AbsoluteLayout mSceneView;
|
||||
|
||||
private int mBackgroundColor = 0xffeeeeee; // TODO Need a better to set background color
|
||||
|
||||
@@ -82,7 +83,7 @@ public abstract class Scene {
|
||||
*
|
||||
* @return Null or nonull
|
||||
*/
|
||||
public @Nullable View getSceneView() {
|
||||
public @Nullable ViewGroup getSceneView() {
|
||||
return mSceneView;
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ public abstract class Scene {
|
||||
onCreate(savedInstanceState);
|
||||
|
||||
if (mSceneView == null) {
|
||||
mSceneView = new FrameLayout(getStageActivity());
|
||||
mSceneView = new AbsoluteLayout(getStageActivity());
|
||||
initBackground(mSceneView);
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ public abstract class Scene {
|
||||
|
||||
protected void setContentView(int resId) {
|
||||
StageActivity sa = getStageActivity();
|
||||
mSceneView = new FrameLayout(sa);
|
||||
mSceneView = new AbsoluteLayout(sa);
|
||||
initBackground(mSceneView);
|
||||
mSceneView.setBackgroundColor(mBackgroundColor);
|
||||
sa.getLayoutInflater().inflate(resId, mSceneView);
|
||||
@@ -189,7 +190,7 @@ public abstract class Scene {
|
||||
|
||||
protected void setContentView(View view) {
|
||||
StageActivity sa = getStageActivity();
|
||||
mSceneView = new FrameLayout(sa);
|
||||
mSceneView = new AbsoluteLayout(sa);
|
||||
initBackground(mSceneView);
|
||||
mSceneView.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
|
||||
@@ -144,12 +144,6 @@ class SceneManager {
|
||||
scene.setState(Scene.SCENE_STATE_DESTROY);
|
||||
scene.detachFromeStage();
|
||||
}
|
||||
|
||||
/*
|
||||
// Switch stage bar
|
||||
View stageBarContent = scene.onCreateStageBar();
|
||||
getStageActivity().getStageBar().updateContent(stageBarContent);
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "The scene is not in stage");
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* 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
|
||||
* 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.hippo.scene;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.hippo.util.UiUtils;
|
||||
|
||||
/**
|
||||
* It is shown at the top of stage, just like actionbar
|
||||
*/
|
||||
public class StageBar extends CardView {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
public StageBar(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public StageBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public StageBar(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
mContext = context;
|
||||
setRadius(UiUtils.dp2pix(context, 2));
|
||||
}
|
||||
|
||||
public void updateContent(View view) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void endAnimation() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public boolean hasContent() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -16,151 +16,232 @@
|
||||
package com.hippo.scene;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsoluteLayout;
|
||||
|
||||
import com.hippo.animation.ArgbEvaluator;
|
||||
import com.hippo.animation.SimpleAnimatorListener;
|
||||
import com.hippo.util.AssertUtils;
|
||||
import com.hippo.util.Log;
|
||||
import com.hippo.util.ViewUtils;
|
||||
import com.hippo.widget.GlobalLayoutSet;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TransitionCurtain extends Curtain {
|
||||
|
||||
private static final String TAG = TransitionCurtain.class.getSimpleName();
|
||||
|
||||
private static long ANIMATE_TIME = 800L;
|
||||
private static long ANIMATE_TIME = 500L;
|
||||
|
||||
private ViewPair[] mViewPairArray;
|
||||
|
||||
private List<ObjectAnimator> mAnimList = new LinkedList<>();
|
||||
|
||||
private boolean mClearList = true;
|
||||
private AnimatorSet mAnimatorSet;
|
||||
|
||||
public TransitionCurtain(ViewPair[] viewPairArray) {
|
||||
mViewPairArray = viewPairArray;
|
||||
}
|
||||
|
||||
// TODO what if back key press before move animator start
|
||||
|
||||
// Make background from transport to default.
|
||||
// Invisible other
|
||||
@Override
|
||||
public void open(final @NonNull Scene enter, final @NonNull Scene exit) {
|
||||
|
||||
final Set<Animator> animatorCollection = new HashSet<>();
|
||||
|
||||
// Handle background
|
||||
final int bgColor = enter.getBackgroundColor();
|
||||
int bgColor = enter.getBackgroundColor();
|
||||
enter.setBackgroundColor(Color.TRANSPARENT);
|
||||
|
||||
ObjectAnimator colorAnim = ObjectAnimator.ofInt(enter, "backgroundColor", bgColor);
|
||||
colorAnim.setEvaluator(ArgbEvaluator.getInstance());
|
||||
colorAnim.setDuration(ANIMATE_TIME);
|
||||
animatorCollection.add(colorAnim);
|
||||
|
||||
colorAnim.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
dispatchOpenFinished(enter, exit);
|
||||
hideSceneOnOpen(exit);
|
||||
|
||||
if (mClearList) {
|
||||
mAnimList.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
colorAnim.start();
|
||||
|
||||
mAnimList.add(colorAnim);
|
||||
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
|
||||
Set<TransitionItem> transitionItemSet = new HashSet<>();
|
||||
|
||||
// Handle transit part
|
||||
for (ViewPair pair : mViewPairArray) {
|
||||
final View enterView = pair.getToView(enter);
|
||||
final View exitView = pair.getFromView(exit);
|
||||
if (enterView == null) {
|
||||
Log.w(TAG, "Can't get enterView when close");
|
||||
Log.e(TAG, "Can't get enterView when close.");
|
||||
continue;
|
||||
}
|
||||
if (exitView == null) {
|
||||
Log.w(TAG, "Can't get exitView when close");
|
||||
Log.e(TAG, "Can't get exitView when close.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// First make enter view invisible
|
||||
ViewUtils.setVisibility(enterView, View.INVISIBLE);
|
||||
|
||||
enterView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
ViewUtils.removeOnGlobalLayoutListener(enterView.getViewTreeObserver(), this);
|
||||
// Add item
|
||||
TransitionItem item = new TransitionItem();
|
||||
item.enterView = enterView;
|
||||
item.exitView = exitView;
|
||||
transitionItemSet.add(item);
|
||||
|
||||
int[] startloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(exitView, startloaction, exit.getSceneView());
|
||||
int[] endloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(enterView, endloaction, enter.getSceneView());
|
||||
int startWidth = exitView.getWidth();
|
||||
int startHeight = exitView.getHeight();
|
||||
int endWidth = enterView.getWidth();
|
||||
int endHeight = enterView.getHeight();
|
||||
globalLayoutSet.addListenerToObserver(enterView.getViewTreeObserver());
|
||||
// TODO show other part progressively
|
||||
}
|
||||
|
||||
ViewUtils.setVisibility(exitView, View.INVISIBLE);
|
||||
ViewUtils.setVisibility(enterView, View.VISIBLE);
|
||||
enterView.setPivotX(0);
|
||||
enterView.setPivotY(0);
|
||||
globalLayoutSet.setOnAllLayoutListener(new OpenFirstAllLayoutListener(
|
||||
enter, exit, transitionItemSet, animatorCollection));
|
||||
}
|
||||
|
||||
// Start animation
|
||||
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", (float) startWidth / endWidth, 1f);
|
||||
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", (float) startHeight / endHeight, 1f);
|
||||
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", startloaction[0], endloaction[0]);
|
||||
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", startloaction[1], endloaction[1]);
|
||||
private class OpenFirstAllLayoutListener implements GlobalLayoutSet.OnAllLayoutListener{
|
||||
|
||||
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(enterView, scaleXPvh, scaleYPvh, xPvh, yPvh);
|
||||
anim.setDuration(ANIMATE_TIME);
|
||||
Scene mEnterScene;
|
||||
Scene mExitScene;
|
||||
Set<TransitionItem> mTransitionItemSet;
|
||||
Set<Animator> mAnimatorCollection;
|
||||
|
||||
anim.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
ViewUtils.setVisibility(exitView, View.VISIBLE);
|
||||
}
|
||||
});
|
||||
public OpenFirstAllLayoutListener(Scene enterScene, Scene exitScene,
|
||||
Set<TransitionItem> transitionItemSet, Set<Animator> animatorCollection) {
|
||||
mEnterScene = enterScene;
|
||||
mExitScene = exitScene;
|
||||
mTransitionItemSet = transitionItemSet;
|
||||
mAnimatorCollection = animatorCollection;
|
||||
}
|
||||
|
||||
anim.start();
|
||||
@Override
|
||||
public void onAllLayout() {
|
||||
Set<TransitionItem> transitionItemSet = mTransitionItemSet;
|
||||
|
||||
mAnimList.add(anim);
|
||||
ViewGroup enterSceneView = mEnterScene.getSceneView();
|
||||
AssertUtils.assertNotNull("Enter scene view must not be null.", enterSceneView);
|
||||
|
||||
// TODO show other part progressively
|
||||
}
|
||||
});
|
||||
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
|
||||
|
||||
for (TransitionItem item : transitionItemSet) {
|
||||
final View enterView = item.enterView;
|
||||
final View exitView = item.exitView;
|
||||
|
||||
int[] startloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(exitView, startloaction, mExitScene.getSceneView());
|
||||
int[] endloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(enterView, endloaction, mEnterScene.getSceneView());
|
||||
int startWidth = exitView.getWidth();
|
||||
int startHeight = exitView.getHeight();
|
||||
item.endWidth = enterView.getWidth();
|
||||
item.endHeight = enterView.getHeight();
|
||||
item.startWidth = startWidth;
|
||||
item.startHeight = startHeight;
|
||||
item.endloaction = endloaction;
|
||||
|
||||
Bitmap bmp = ViewUtils.getBitmapFromView(enterView);
|
||||
View bmpView = new View(enterView.getContext());
|
||||
item.bmp = bmp;
|
||||
item.bmpView = bmpView;
|
||||
|
||||
bmpView.setBackgroundDrawable(new BitmapDrawable(bmp));
|
||||
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(
|
||||
startWidth, startHeight, startloaction[0], startloaction[1]);
|
||||
enterSceneView.addView(bmpView, lp);
|
||||
|
||||
ViewUtils.setVisibility(bmpView, View.INVISIBLE);
|
||||
|
||||
globalLayoutSet.addListenerToObserver(bmpView.getViewTreeObserver());
|
||||
}
|
||||
|
||||
globalLayoutSet.setOnAllLayoutListener(new OpenSecondAllLayoutListener(
|
||||
mEnterScene, mExitScene, transitionItemSet, mAnimatorCollection));
|
||||
}
|
||||
}
|
||||
|
||||
private class OpenSecondAllLayoutListener implements GlobalLayoutSet.OnAllLayoutListener{
|
||||
|
||||
Scene mEnterScene;
|
||||
Scene mExitScene;
|
||||
Set<TransitionItem> mTransitionItemSet;
|
||||
Set<Animator> mAnimatorCollection;
|
||||
|
||||
public OpenSecondAllLayoutListener(Scene enterScene, Scene exitScene,
|
||||
Set<TransitionItem> transitionItemSet, Set<Animator> animatorCollection) {
|
||||
mEnterScene = enterScene;
|
||||
mExitScene = exitScene;
|
||||
mTransitionItemSet = transitionItemSet;
|
||||
mAnimatorCollection = animatorCollection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllLayout() {
|
||||
Set<TransitionItem> transitionItemSet = mTransitionItemSet;
|
||||
Set<Animator> animatorCollection = mAnimatorCollection;
|
||||
|
||||
for (TransitionItem item : transitionItemSet) {
|
||||
View exitView = item.exitView;
|
||||
View bmpView = item.bmpView;
|
||||
|
||||
ViewUtils.setVisibility(exitView, View.INVISIBLE);
|
||||
ViewUtils.setVisibility(bmpView, View.VISIBLE);
|
||||
|
||||
bmpView.setPivotX(0);
|
||||
bmpView.setPivotY(0);
|
||||
|
||||
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", (float) item.endWidth / item.startWidth);
|
||||
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", (float) item.endHeight/ item.startHeight);
|
||||
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", item.endloaction[0]);
|
||||
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", item.endloaction[1]);
|
||||
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(bmpView, scaleXPvh, scaleYPvh, xPvh, yPvh);
|
||||
anim.setDuration(ANIMATE_TIME);
|
||||
|
||||
animatorCollection.add(anim);
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.playTogether(animatorCollection);
|
||||
mAnimatorSet.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
dispatchOpenFinished(mEnterScene, mExitScene);
|
||||
hideSceneOnOpen(mExitScene);
|
||||
for (TransitionItem item : mTransitionItemSet) {
|
||||
ViewUtils.setVisibility(item.enterView, View.VISIBLE);
|
||||
ViewUtils.setVisibility(item.exitView, View.VISIBLE);
|
||||
|
||||
ViewGroup enterSceneView = mEnterScene.getSceneView();
|
||||
AssertUtils.assertNotNull("Enter scene view must not be null.", enterSceneView);
|
||||
enterSceneView.removeView(item.bmpView);
|
||||
|
||||
item.bmp.recycle();
|
||||
}
|
||||
mAnimatorSet = null;
|
||||
}
|
||||
});
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close(final @NonNull Scene enter, final @NonNull Scene exit) {
|
||||
showSceneOnClose(enter);
|
||||
|
||||
final Set<Animator> animatorCollection = new HashSet<>();
|
||||
|
||||
// Handle background
|
||||
ObjectAnimator colorAnim = ObjectAnimator.ofInt(exit, "backgroundColor", Color.TRANSPARENT);
|
||||
colorAnim.setEvaluator(ArgbEvaluator.getInstance());
|
||||
colorAnim.setDuration(ANIMATE_TIME);
|
||||
animatorCollection.add(colorAnim);
|
||||
|
||||
colorAnim.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
dispatchCloseFinished(enter, exit);
|
||||
if (mClearList) {
|
||||
mAnimList.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
colorAnim.start();
|
||||
|
||||
mAnimList.add(colorAnim);
|
||||
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
|
||||
Set<TransitionItem> transitionItemSet = new HashSet<>();
|
||||
|
||||
// Handle transit part
|
||||
for (ViewPair pair : mViewPairArray) {
|
||||
@@ -175,54 +256,168 @@ public class TransitionCurtain extends Curtain {
|
||||
continue;
|
||||
}
|
||||
|
||||
int[] endloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(enterView, endloaction, enter.getSceneView());
|
||||
int startWidth = exitView.getWidth();
|
||||
int startHeight = exitView.getHeight();
|
||||
int endWidth = enterView.getWidth();
|
||||
int endHeight = enterView.getHeight();
|
||||
|
||||
ViewUtils.setVisibility(exitView, View.VISIBLE);
|
||||
// First make enter view invisible
|
||||
ViewUtils.setVisibility(enterView, View.INVISIBLE);
|
||||
exitView.setPivotX(0);
|
||||
exitView.setPivotY(0);
|
||||
|
||||
// Start animation
|
||||
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", (float) endWidth / startWidth);
|
||||
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", (float) endHeight / startHeight);
|
||||
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", endloaction[0]);
|
||||
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", endloaction[1]);
|
||||
// Add item
|
||||
TransitionItem item = new TransitionItem();
|
||||
item.enterView = enterView;
|
||||
item.exitView = exitView;
|
||||
transitionItemSet.add(item);
|
||||
|
||||
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(exitView, scaleXPvh, scaleYPvh, xPvh, yPvh);
|
||||
anim.setDuration(ANIMATE_TIME);
|
||||
globalLayoutSet.addListenerToObserver(enterView.getViewTreeObserver());
|
||||
// TODO show other part progressively
|
||||
}
|
||||
|
||||
anim.addListener(new SimpleAnimatorListener() {
|
||||
globalLayoutSet.setOnAllLayoutListener(new CloseFirstAllLayoutListener(
|
||||
enter, exit, transitionItemSet, animatorCollection));
|
||||
}
|
||||
|
||||
private class CloseFirstAllLayoutListener implements GlobalLayoutSet.OnAllLayoutListener{
|
||||
|
||||
Scene mEnterScene;
|
||||
Scene mExitScene;
|
||||
Set<TransitionItem> mTransitionItemSet;
|
||||
Set<Animator> mAnimatorCollection;
|
||||
|
||||
public CloseFirstAllLayoutListener(Scene enterScene, Scene exitScene,
|
||||
Set<TransitionItem> transitionItemSet, Set<Animator> animatorCollection) {
|
||||
mEnterScene = enterScene;
|
||||
mExitScene = exitScene;
|
||||
mTransitionItemSet = transitionItemSet;
|
||||
mAnimatorCollection = animatorCollection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllLayout() {
|
||||
Set<TransitionItem> transitionItemSet = mTransitionItemSet;
|
||||
|
||||
ViewGroup exitSceneView = mExitScene.getSceneView();
|
||||
AssertUtils.assertNotNull("Exit scene view must not be null.", exitSceneView);
|
||||
|
||||
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
|
||||
|
||||
for (TransitionItem item : transitionItemSet) {
|
||||
final View enterView = item.enterView;
|
||||
final View exitView = item.exitView;
|
||||
|
||||
int[] startloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(exitView, startloaction, mExitScene.getSceneView());
|
||||
int[] endloaction = new int[2];
|
||||
ViewUtils.getLocationInAncestor(enterView, endloaction, mEnterScene.getSceneView());
|
||||
int startWidth = exitView.getWidth();
|
||||
int startHeight = exitView.getHeight();
|
||||
item.endWidth = enterView.getWidth();
|
||||
item.endHeight = enterView.getHeight();
|
||||
item.startWidth = startWidth;
|
||||
item.startHeight = startHeight;
|
||||
item.endloaction = endloaction;
|
||||
|
||||
Bitmap bmp = ViewUtils.getBitmapFromView(exitView);
|
||||
View bmpView = new View(exitView.getContext());
|
||||
item.bmp = bmp;
|
||||
item.bmpView = bmpView;
|
||||
|
||||
bmpView.setBackgroundDrawable(new BitmapDrawable(bmp));
|
||||
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(
|
||||
startWidth, startHeight, startloaction[0], startloaction[1]);
|
||||
exitSceneView.addView(bmpView, lp);
|
||||
|
||||
ViewUtils.setVisibility(bmpView, View.INVISIBLE);
|
||||
|
||||
globalLayoutSet.addListenerToObserver(bmpView.getViewTreeObserver());
|
||||
}
|
||||
|
||||
globalLayoutSet.setOnAllLayoutListener(new CloseSecondAllLayoutListener(
|
||||
mEnterScene, mExitScene, transitionItemSet, mAnimatorCollection));
|
||||
}
|
||||
}
|
||||
|
||||
private class CloseSecondAllLayoutListener implements GlobalLayoutSet.OnAllLayoutListener{
|
||||
|
||||
Scene mEnterScene;
|
||||
Scene mExitScene;
|
||||
Set<TransitionItem> mTransitionItemSet;
|
||||
Set<Animator> mAnimatorCollection;
|
||||
|
||||
public CloseSecondAllLayoutListener(Scene enterScene, Scene exitScene,
|
||||
Set<TransitionItem> transitionItemSet, Set<Animator> animatorCollection) {
|
||||
mEnterScene = enterScene;
|
||||
mExitScene = exitScene;
|
||||
mTransitionItemSet = transitionItemSet;
|
||||
mAnimatorCollection = animatorCollection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllLayout() {
|
||||
Set<TransitionItem> transitionItemSet = mTransitionItemSet;
|
||||
Set<Animator> animatorCollection = mAnimatorCollection;
|
||||
|
||||
for (TransitionItem item : transitionItemSet) {
|
||||
View exitView = item.exitView;
|
||||
View bmpView = item.bmpView;
|
||||
|
||||
ViewUtils.setVisibility(exitView, View.INVISIBLE);
|
||||
ViewUtils.setVisibility(bmpView, View.VISIBLE);
|
||||
|
||||
bmpView.setPivotX(0);
|
||||
bmpView.setPivotY(0);
|
||||
|
||||
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", (float) item.endWidth / item.startWidth);
|
||||
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", (float) item.endHeight/ item.startHeight);
|
||||
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", item.endloaction[0]);
|
||||
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", item.endloaction[1]);
|
||||
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(bmpView, scaleXPvh, scaleYPvh, xPvh, yPvh);
|
||||
anim.setDuration(ANIMATE_TIME);
|
||||
|
||||
animatorCollection.add(anim);
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.playTogether(animatorCollection);
|
||||
mAnimatorSet.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
ViewUtils.setVisibility(enterView, View.VISIBLE);
|
||||
dispatchCloseFinished(mEnterScene, mExitScene);
|
||||
for (TransitionItem item : mTransitionItemSet) {
|
||||
ViewUtils.setVisibility(item.enterView, View.VISIBLE);
|
||||
ViewUtils.setVisibility(item.exitView, View.VISIBLE);
|
||||
|
||||
ViewGroup exitSceneView = mExitScene.getSceneView();
|
||||
AssertUtils.assertNotNull("Exit scene view must not be null.", exitSceneView);
|
||||
exitSceneView.removeView(item.bmpView);
|
||||
|
||||
item.bmp.recycle();
|
||||
}
|
||||
mAnimatorSet = null;
|
||||
}
|
||||
});
|
||||
|
||||
anim.start();
|
||||
|
||||
mAnimList.add(anim);
|
||||
// TODO show other part progressively
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endAnimation() {
|
||||
mClearList = false;
|
||||
for (ObjectAnimator oa : mAnimList) {
|
||||
oa.end();
|
||||
if (mAnimatorSet != null) {
|
||||
mAnimatorSet.end();
|
||||
}
|
||||
mClearList = true;
|
||||
mAnimList.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInAnimation() {
|
||||
return !mAnimList.isEmpty();
|
||||
return mAnimatorSet != null;
|
||||
}
|
||||
|
||||
private class TransitionItem {
|
||||
View enterView;
|
||||
View exitView;
|
||||
Bitmap bmp;
|
||||
View bmpView;
|
||||
int[] endloaction;
|
||||
int startWidth;
|
||||
int startHeight;
|
||||
int endWidth;
|
||||
int endHeight;
|
||||
}
|
||||
|
||||
public static class ViewPair {
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* 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
|
||||
* 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.hippo.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.util.ViewUtils;
|
||||
|
||||
public class Appbar extends FrameLayout {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private ImageView mNavigationIcon;
|
||||
private TextView mTitle;
|
||||
|
||||
private String mTitleString;
|
||||
|
||||
public Appbar(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public Appbar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public Appbar(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public Appbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
mContext = context;
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.widget_app_bar, this);
|
||||
|
||||
mNavigationIcon = (ImageView) findViewById(R.id.ab_navigation_icon);
|
||||
mTitle = (TextView) findViewById(R.id.ab_title);
|
||||
|
||||
ViewUtils.setVisibility(mNavigationIcon, View.GONE);
|
||||
}
|
||||
|
||||
public void setTitle(int resId) {
|
||||
setTitle(mContext.getString(resId));
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
mTitleString = title;
|
||||
mTitle.setText(title);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* 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
|
||||
* 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.hippo.widget;
|
||||
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
import com.hippo.util.ViewUtils;
|
||||
|
||||
public class GlobalLayoutSet {
|
||||
|
||||
private OnAllLayoutListener mOnAllLayoutListener;
|
||||
|
||||
private int mSize;
|
||||
|
||||
public void setOnAllLayoutListener(OnAllLayoutListener listener) {
|
||||
mOnAllLayoutListener = listener;
|
||||
}
|
||||
|
||||
public void addListenerToObserver(ViewTreeObserver observer) {
|
||||
LayoutListener ll = new LayoutListener(observer);
|
||||
observer.addOnGlobalLayoutListener(ll);
|
||||
mSize++;
|
||||
}
|
||||
|
||||
private class LayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
|
||||
private ViewTreeObserver mObserver;
|
||||
|
||||
private LayoutListener(ViewTreeObserver observer) {
|
||||
mObserver = observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
ViewUtils.removeOnGlobalLayoutListener(mObserver, this);
|
||||
|
||||
if (--mSize == 0) {
|
||||
mOnAllLayoutListener.onAllLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnAllLayoutListener {
|
||||
void onAllLayout();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user