Java Android-使用AnimatorSet缩放动画
官方教程使用放大视图来放大Java Android-使用AnimatorSet缩放动画,java,android,android-animation,objectanimator,viewpropertyanimator,Java,Android,Android Animation,Objectanimator,Viewpropertyanimator,官方教程使用放大视图来放大视图。随着视图的扩展,它会产生向下移动的错觉。稍后,AnimatorSet将简单地向后播放,以创建缩小效果 我需要实现的恰恰相反。我需要从一个展开的视图开始,然后将其缩小为一个向上移动的较小视图: 在示例中,我似乎无法使用反转代码。该示例假定您首先放大视图并将其展开,然后将其收缩回原始缩略图图标 这是我到目前为止试过的。我的XML布局是 <FrameLayout xmlns:android="http://schemas.android.com/apk/res
视图
。随着视图的扩展,它会产生向下移动的错觉。稍后,AnimatorSet
将简单地向后播放,以创建缩小效果
我需要实现的恰恰相反。我需要从一个展开的视图开始,然后将其缩小为一个向上移动的较小视图:
在示例中,我似乎无法使用反转代码。该示例假定您首先放大视图并将其展开,然后将其收缩回原始缩略图图标
这是我到目前为止试过的。我的XML布局是
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#1999da">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center">
<!-- The final shrunk image -->
<ImageView
android:id="@+id/thumb_button_1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginRight="1dp"
android:visibility="invisible"/>
</LinearLayout>
</LinearLayout>
<!-- The initial expanded image that needs to be shrunk -->
<ImageView
android:id="@+id/expanded_image"
android:layout_width="wrap_content"
android:layout_height="125dp"
android:layout_gravity="center"
android:src="@drawable/title_logo_expanded"
android:scaleType="centerCrop"/>
</FrameLayout>
我在onCreate()
中调用此方法,如下所示:
final View expandedImageView = findViewById(R.id.expanded_image);
new Handler().postDelayed(new Runnable(){
public void run() {
zoomImageFromThumbReverse(expandedImageView, R.drawable.title_logo_min, 1000);
}}, 1000);
好了,就这样,伙计们。它不起作用了。我不知道为什么。演示示例工作得很好,那么为什么这个不工作呢?看一看,告诉我我是不是疯了
有人能识别错误吗?或者给我指出正确的方向?非常感谢您提供的所有帮助。好的,我想您需要从图像和描述中向上缩小。我不能理解你的代码,它对我来说太复杂了(我是个傻瓜)。现在,我已经使用以下代码完成了您想要的操作。首先,我用一个图像视图声明一个相对布局,这个相对布局就是容器。我设置了初始宽度和高度,但稍后我们将从代码中更改它
<RelativeLayout
android:id="@+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="400dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@drawable/my_image"/>
</RelativeLayout>
我们必须在这里设置三个动画,宽度、高度和上边距(用于定位)。所以,我为animator的初始位置声明了三个变量,并在初始布局设置中计算它们。现在我们需要同时设置这三个变量的动画,这很容易
private void startAnimation() {
AnimatorSet animator = new AnimatorSet();
Animator widthAnimator = ObjectAnimator.ofInt(this, "width", width, 200);
widthAnimator.setInterpolator(new LinearInterpolator());
Animator heightAnimator = ObjectAnimator.ofInt(this, "height", height, 100);
heightAnimator.setInterpolator(new LinearInterpolator());
Animator marginAnimator = ObjectAnimator.ofInt(this, "topMargin", topMargin, 0);
marginAnimator.setInterpolator(new LinearInterpolator());
animator.playTogether(widthAnimator, heightAnimator, marginAnimator);
animator.setDuration(3000);
animator.start();
}
public void setWidth(int w) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) im.getLayoutParams();
layoutParams.width = w;
im.setLayoutParams(layoutParams);
}
public void setHeight(int h) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) im.getLayoutParams();
layoutParams.height = h;
im.setLayoutParams(layoutParams);
}
public void setTopMargin(int m) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) im.getLayoutParams();
layoutParams.topMargin = m;
im.setLayoutParams(layoutParams);
}
}
这是我最终使用的解决方案:
private void applyAnimation(final View startView, final View finishView, long duration) {
float scalingFactor = ((float)finishView.getHeight())/((float)startView.getHeight());
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, scalingFactor,
1f, scalingFactor,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(duration);
scaleAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
Display display = getWindowManager().getDefaultDisplay();
int H;
if(Build.VERSION.SDK_INT >= 13){
Point size = new Point();
display.getSize(size);
H = size.y;
}
else{
H = display.getHeight();
}
float h = ((float)finishView.getHeight());
float verticalDisplacement = (-(H/2)+(3*h/4));
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, verticalDisplacement);
translateAnimation.setDuration(duration);
translateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.setFillAfter(false);
startView.startAnimation(animationSet);
}
这里的关键因素是TranslateAnimation
参数中toYDelta
的值:
toYDelta = (-(H/2)+(3*h/4));
最主要的是要理解为什么这样做有效。剩下的大部分都很简单
private void applyAnimation(final View startView, final View finishView, long duration) {
float scalingFactor = ((float)finishView.getHeight())/((float)startView.getHeight());
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, scalingFactor,
1f, scalingFactor,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(duration);
scaleAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
Display display = getWindowManager().getDefaultDisplay();
int H;
if(Build.VERSION.SDK_INT >= 13){
Point size = new Point();
display.getSize(size);
H = size.y;
}
else{
H = display.getHeight();
}
float h = ((float)finishView.getHeight());
float verticalDisplacement = (-(H/2)+(3*h/4));
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, verticalDisplacement);
translateAnimation.setDuration(duration);
translateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.setFillAfter(false);
startView.startAnimation(animationSet);
}
toYDelta = (-(H/2)+(3*h/4));