Optimize SimpleDialogCurtain

This commit is contained in:
seven332 committed 2015-05-29 00:53:48 +08:00
1 parent aa61dada92
commit 3bcb96d89f
6 files changed
+250 -125

No files matched your search

@@ -19,6 +19,7 @@ import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.hippo.util.ViewUtils;
import com.hippo.widget.HotspotTouchHelper;
@@ -72,7 +73,7 @@ public class SceneDialogView extends SceneView implements View.OnClickListener,
@Override
public void onClick(View v) {
if (v == this && !ViewUtils.isViewUnder(getChildAt(0), (int) mHostpotX,
if (v == this && !ViewUtils.isViewUnder(((ViewGroup) getChildAt(0)).getChildAt(0), (int) mHostpotX,
(int) mHostpotY) && mOnClickOutOfDialogListener != null) {
mOnClickOutOfDialogListener.onClickOutOfDialog((int) mHostpotX, (int) mHostpotY);
}
@@ -21,7 +21,9 @@ import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.widget.CardView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
@@ -46,6 +48,8 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
private Builder mBuilder;
private SceneDialogView mSceneDialogView;
private SimpleDialogLayout mLayout;
private CardView mCushion;
private SimpleDialogFrame mFrame;
private View mBody;
private TextView mTitle;
@@ -73,7 +77,10 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
setBackgroundColor(BACKGROUND_COLOR);
setContentView(R.layout.simple_dialog_frame);
mFrame = (SimpleDialogFrame) findViewById(R.id.simple_dialog_frame);
mLayout = (SimpleDialogLayout) findViewById(R.id.simple_dialog_layout);
mCushion = (CardView) mLayout.findViewById(R.id.simple_dialog_cushion);
mFrame = (SimpleDialogFrame) mLayout.findViewById(R.id.simple_dialog_frame);
getStageActivity().getLayoutInflater().inflate(R.layout.simple_dialog, mFrame);
@@ -181,10 +188,14 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
@Override
protected void onGetFitPaddingBottom(int b) {
mFitPaddingBottom = b;
mFrame.setFitPaddingBottom(b);
mLayout.setFitPaddingBottom(b);
}
public SimpleDialogFrame getFrame() {
public CardView getCushion() {
return mCushion;
}
public ViewGroup getFrame() {
return mFrame;
}
@@ -78,55 +78,64 @@ public class SimpleDialogCurtain extends Curtain {
colorAnim.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
animatorCollection.add(colorAnim);
final View mFrame = enterDialog.getFrame();
AssertUtils.assertNotNull("Frame view must not be null.", mFrame);
final View cushion = enterDialog.getCushion();
final View frame = enterDialog.getFrame();
AssertUtils.assertNotNull("Cushion view must not be null.", cushion);
AssertUtils.assertNotNull("Frame view must not be null.", frame);
ViewUtils.setVisibility(mFrame, View.INVISIBLE);
ViewUtils.setVisibility(cushion, View.INVISIBLE);
ViewUtils.setVisibility(frame, View.INVISIBLE);
mFrame.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
frame.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewUtils.removeOnGlobalLayoutListener(mFrame.getViewTreeObserver(), this);
ViewUtils.removeOnGlobalLayoutListener(frame.getViewTreeObserver(), this);
int endLeft = mFrame.getLeft();
int endTop = mFrame.getTop();
int endRight = mFrame.getRight();
int endBottom = mFrame.getBottom();
int startLeft;
int startTop;
int startRight;
int startBottom;
float floatStartX;
float floatStartY;
int intStartX;
int intStartY;
if (mStartX == 0 && mStartY == 0) {
int[] center = new int[2];
enterDialog.getCenterLocation(center);
startLeft = center[0];
startTop = center[1];
startRight = center[0];
startBottom = center[1];
floatStartX = center[0];
floatStartY = center[1];
intStartX = center[0];
intStartY = center[1];
} else {
startLeft = mStartX;
startTop = mStartY;
startRight = mStartX;
startBottom = mStartY;
floatStartX = mStartX;
floatStartY = mStartY;
intStartX = mStartX;
intStartY = mStartY;
}
// TODO should start from frame edge when it is out of frame
PropertyValuesHolder leftPvh = PropertyValuesHolder.ofInt("drawLeft", startLeft, endLeft);
PropertyValuesHolder topPvh = PropertyValuesHolder.ofInt("drawTop", startTop, endTop);
PropertyValuesHolder rightPvh = PropertyValuesHolder.ofInt("drawRight", startRight, endRight);
PropertyValuesHolder bottomPvh = PropertyValuesHolder.ofInt("drawBottom", startBottom, endBottom);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(mFrame, leftPvh, topPvh, rightPvh, bottomPvh);
anim.setDuration(ANIMATE_TIME);
anim.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
cushion.setPivotX(0f);
cushion.setPivotY(0f);
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", floatStartX, frame.getLeft());
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", floatStartY, frame.getTop());
ObjectAnimator animCushion = ObjectAnimator.ofPropertyValuesHolder(cushion, scaleXPvh, scaleYPvh, xPvh, yPvh);
animCushion.setDuration(ANIMATE_TIME);
animCushion.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
animatorCollection.add(animCushion);
animatorCollection.add(anim);
PropertyValuesHolder leftPvh = PropertyValuesHolder.ofInt("drawLeft", intStartX, frame.getLeft());
PropertyValuesHolder topPvh = PropertyValuesHolder.ofInt("drawTop", intStartY, frame.getTop());
PropertyValuesHolder rightPvh = PropertyValuesHolder.ofInt("drawRight", intStartX, frame.getRight());
PropertyValuesHolder bottomPvh = PropertyValuesHolder.ofInt("drawBottom", intStartY, frame.getBottom());
ObjectAnimator animFrame = ObjectAnimator.ofPropertyValuesHolder(frame, leftPvh, topPvh, rightPvh, bottomPvh);
animFrame.setDuration(ANIMATE_TIME);
animFrame.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
animatorCollection.add(animFrame);
mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(animatorCollection);
mAnimatorSet.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(mFrame, View.VISIBLE);
ViewUtils.setVisibility(cushion, View.VISIBLE);
ViewUtils.setVisibility(frame, View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -155,40 +164,48 @@ public class SimpleDialogCurtain extends Curtain {
animatorCollection.add(colorAnim);
colorAnim.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR);
final View mFrame = exitDialog.getFrame();
AssertUtils.assertNotNull("Frame view must not be null.", mFrame);
final View cushion = exitDialog.getCushion();
final View frame = exitDialog.getFrame();
AssertUtils.assertNotNull("Cushion view must not be null.", cushion);
AssertUtils.assertNotNull("Frame view must not be null.", frame);
int startLeft = mFrame.getLeft();
int startTop = mFrame.getTop();
int startRight = mFrame.getRight();
int startBottom = mFrame.getBottom();
int endLeft;
int endTop;
int endRight;
int endBottom;
float floatEndX;
float floatEndY;
int intEndX;
int intEndY;
if (mStartX == 0 && mStartY == 0) {
int[] center = new int[2];
exitDialog.getCenterLocation(center);
endLeft = center[0];
endTop = center[1];
endRight = center[0];
endBottom = center[1];
floatEndX = center[0];
floatEndY = center[1];
intEndX = center[0];
intEndY = center[1];
} else {
endLeft = mStartX;
endTop = mStartY;
endRight = mStartX;
endBottom = mStartY;
floatEndX = mStartX;
floatEndY = mStartY;
intEndX = mStartX;
intEndY = mStartY;
}
PropertyValuesHolder leftPvh = PropertyValuesHolder.ofInt("drawLeft", startLeft, endLeft);
PropertyValuesHolder topPvh = PropertyValuesHolder.ofInt("drawTop", startTop, endTop);
PropertyValuesHolder rightPvh = PropertyValuesHolder.ofInt("drawRight", startRight, endRight);
PropertyValuesHolder bottomPvh = PropertyValuesHolder.ofInt("drawBottom", startBottom, endBottom);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(mFrame, leftPvh, topPvh, rightPvh, bottomPvh);
anim.setDuration(ANIMATE_TIME);
anim.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR);
cushion.setPivotX(0f);
cushion.setPivotY(0f);
PropertyValuesHolder scaleXPvh = PropertyValuesHolder.ofFloat("scaleX", 0f);
PropertyValuesHolder scaleYPvh = PropertyValuesHolder.ofFloat("scaleY", 0f);
PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat("x", floatEndX);
PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat("y", floatEndY);
ObjectAnimator animCushion = ObjectAnimator.ofPropertyValuesHolder(cushion, scaleXPvh, scaleYPvh, xPvh, yPvh);
animCushion.setDuration(ANIMATE_TIME);
animCushion.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
animatorCollection.add(animCushion);
animatorCollection.add(anim);
PropertyValuesHolder leftPvh = PropertyValuesHolder.ofInt("drawLeft", intEndX);
PropertyValuesHolder topPvh = PropertyValuesHolder.ofInt("drawTop", intEndY);
PropertyValuesHolder rightPvh = PropertyValuesHolder.ofInt("drawRight", intEndX);
PropertyValuesHolder bottomPvh = PropertyValuesHolder.ofInt("drawBottom", intEndY);
ObjectAnimator animFrame = ObjectAnimator.ofPropertyValuesHolder(frame, leftPvh, topPvh, rightPvh, bottomPvh);
animFrame.setDuration(ANIMATE_TIME);
animFrame.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
animatorCollection.add(animFrame);
mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(animatorCollection);
@@ -16,22 +16,10 @@
package com.hippo.scene;
import android.content.Context;
import android.content.res.Resources;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.view.RenderNodeAnimator;
import android.widget.AbsoluteLayout;
import android.widget.FrameLayout;
import com.hippo.ehviewer.R;
import com.hippo.util.ResourcesUtils;
public class SimpleDialogFrame extends CardView {
private int mPadding;
private int mFixedWidth;
private float mFixedWidthPercent;
private float mFixedHeightPercent;
private int mFitPaddingBottom;
public class SimpleDialogFrame extends FrameLayout {
private int mOriginLeft;
private int mOriginTop;
@@ -40,59 +28,14 @@ public class SimpleDialogFrame extends CardView {
public SimpleDialogFrame(Context context) {
super(context);
init(context);
}
public SimpleDialogFrame(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SimpleDialogFrame(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
Resources resources = context.getResources();
mPadding = resources.getDimensionPixelOffset(R.dimen.simple_dialog_padding);
mFixedWidth = resources.getDimensionPixelOffset(R.dimen.simple_dialog_fixed_width);
mFixedWidthPercent = ResourcesUtils.getFloat(resources, R.dimen.simple_dialog_fixed_width_percent);
mFixedHeightPercent = ResourcesUtils.getFloat(resources, R.dimen.simple_dialog_fixed_height_percent);
}
public void setFitPaddingBottom(int fitPaddingBottom) {
if (mFitPaddingBottom != fitPaddingBottom) {
mFitPaddingBottom = fitPaddingBottom;
requestLayout();
}
}
@SuppressWarnings("deprecation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Width
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {
int fixedWidth = Math.min((int) (originalWidth * mFixedWidthPercent), mFixedWidth) -
(2 * mPadding);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(fixedWidth, MeasureSpec.EXACTLY);
}
// Height
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.UNSPECIFIED) {
int fixedHeight = (int) ((originalHeight - mFitPaddingBottom) * mFixedHeightPercent) -
(2 * mPadding);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(fixedHeight, MeasureSpec.AT_MOST);
}
// Measure
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Update x, y
int width = getMeasuredWidth();
int height = getMeasuredHeight();
AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) getLayoutParams();
lp.x = (originalWidth - width) / 2;
lp.y = (originalHeight - mFitPaddingBottom - height) / 2;
}
@Override
@@ -111,7 +54,6 @@ public class SimpleDialogFrame extends CardView {
mDrawLeft = drawLeft;
setLeft(drawLeft);
setScrollX(drawLeft - mOriginLeft);
RenderNodeAnimator animato;
}
@SuppressWarnings("unused")
@@ -0,0 +1,141 @@
/*
* 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.content.res.Resources;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.hippo.ehviewer.R;
import com.hippo.util.ResourcesUtils;
public class SimpleDialogLayout extends ViewGroup {
private int mPadding;
private int mFixedWidth;
private float mFixedWidthPercent;
private float mFixedHeightPercent;
private int mFitPaddingBottom;
private CardView mCushion;
private ViewGroup mFrame;
public SimpleDialogLayout(Context context) {
super(context);
init(context);
}
public SimpleDialogLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SimpleDialogLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
Resources resources = context.getResources();
mPadding = resources.getDimensionPixelOffset(R.dimen.simple_dialog_padding);
mFixedWidth = resources.getDimensionPixelOffset(R.dimen.simple_dialog_fixed_width);
mFixedWidthPercent = ResourcesUtils.getFloat(resources, R.dimen.simple_dialog_fixed_width_percent);
mFixedHeightPercent = ResourcesUtils.getFloat(resources, R.dimen.simple_dialog_fixed_height_percent);
}
@Override
public final void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
if (child instanceof CardView) {
if (mCushion != null) {
throw new IllegalStateException("Only need one cushion in SimpleDialog");
}
mCushion = (CardView) child;
if (mFrame != null) {
mFrame.setPadding(mCushion.getPaddingLeft(),
mCushion.getPaddingTop(), mCushion.getPaddingRight(),
mCushion.getPaddingBottom());
}
} else {
if (mFrame != null) {
throw new IllegalStateException("Only need one frame in SimpleDialog");
}
mFrame = (ViewGroup) child;
if (mCushion != null) {
mFrame.setPadding(mCushion.getPaddingLeft(),
mCushion.getPaddingTop(), mCushion.getPaddingRight(),
mCushion.getPaddingBottom());
}
}
}
public void setFitPaddingBottom(int fitPaddingBottom) {
if (mFitPaddingBottom != fitPaddingBottom) {
mFitPaddingBottom = fitPaddingBottom;
requestLayout();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int newWidthMeasureSpec;
int newHeightMeasureSpec;
// Width
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {
int fixedWidth = Math.min((int) (originalWidth * mFixedWidthPercent), mFixedWidth) -
(2 * mPadding);
newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(fixedWidth, MeasureSpec.EXACTLY);
} else {
throw new IllegalStateException("MeasureSpec.UNSPECIFIED is not allowed in SimpleDialogLayout");
}
// Height
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.UNSPECIFIED) {
int fixedHeight = (int) ((originalHeight - mFitPaddingBottom) * mFixedHeightPercent) -
(2 * mPadding);
newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(fixedHeight, MeasureSpec.AT_MOST);
} else {
throw new IllegalStateException("MeasureSpec.UNSPECIFIED is not allowed in SimpleDialogLayout");
}
measureChild(mFrame, newWidthMeasureSpec, newHeightMeasureSpec);
measureChild(mCushion,
MeasureSpec.makeMeasureSpec(mFrame.getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mFrame.getMeasuredHeight(), MeasureSpec.EXACTLY));
setMeasuredDimension(originalWidth, originalHeight);
}
private void layoutChild(View child) {
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
int left = (getWidth() / 2) - (childWidth / 2);
int top = ((getHeight() - mFitPaddingBottom) / 2) - (childHeight / 2);
child.layout(left, top, left + childWidth, top + childHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
layoutChild(mCushion);
layoutChild(mFrame);
}
}