Android: 使用动画显示/隐藏视图

我已经在这里查看了许多谷歌结果/问题,以确定如何通过垂直动画显示/隐藏视图,但我似乎找不到一个完全正确或不太模糊。

我有一个布局(撤销栏) ,它位于另一个布局之下和多个其他小部件之上; 这个撤销栏应该垂直滑动打开和滑动关闭,这取决于具体情况。

目前我所做的就是将视图设置为可见或消失。

114362 次浏览

尝试使用 翻译动画类,它为位置变化创建动画

更新: 下面是这样的例子。如果您的视图高度为50,并且在隐藏模式下,您希望只显示10px。示例代码应该是-

TranslateAnimation anim=new TranslateAnimation(0,0,-40,0);
anim.setFillAfter(true);
view.setAnimation(anim);

PS: 有很多的或其他的方法可以帮助你根据你的需要使用动画。还可以查看 RelativeLayout。如果您想完全自定义代码,可以使用 LayoutParams,但是使用 TransateAnimation 更容易。

编辑:-使用 LayoutParams 的复杂版本

RelativeLayout relParam=new RelativeLayout.LayoutParam(RelativeLayout.LayoutParam.FILL_PARENT,RelativeLayout.LayoutParam.WRAP_CONTENT); //you can give hard coded width and height here in (width,height) format.
relParam.topMargin=-50; //any number that work.Set it to 0, when you want to show it.
view.setLayoutParams(relparam);

此示例代码假定您将视图放在 RelativeLayout 中,如果不更改 Layout 的名称,则其他布局可能无法工作。如果你想给他们一个动画效果,减少或增加顶部边距慢慢。您也可以考虑在那里使用 Thread.sleep ()。

我为 RelativeLayout创建了一个扩展,它显示/隐藏带有动画的布局。 它可以扩展任何类型的 View来获得这些特性。

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;


public class AnimatingRelativeLayout extends RelativeLayout
{
Context context;
Animation inAnimation;
Animation outAnimation;


public AnimatingRelativeLayout(Context context)
{
super(context);
this.context = context;
initAnimations();


}


public AnimatingRelativeLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
initAnimations();
}


public AnimatingRelativeLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
this.context = context;
initAnimations();
}


private void initAnimations()
{
inAnimation = (AnimationSet) AnimationUtils.loadAnimation(context, R.anim.in_animation);
outAnimation = (Animation) AnimationUtils.loadAnimation(context, R.anim.out_animation);
}


public void show()
{
if (isVisible()) return;
show(true);
}


public void show(boolean withAnimation)
{
if (withAnimation) this.startAnimation(inAnimation);
this.setVisibility(View.VISIBLE);
}


public void hide()
{
if (!isVisible()) return;
hide(true);
}


public void hide(boolean withAnimation)
{
if (withAnimation) this.startAnimation(outAnimation);
this.setVisibility(View.GONE);
}


public boolean isVisible()
{
return (this.getVisibility() == View.VISIBLE);
}


public void overrideDefaultInAnimation(Animation inAnimation)
{
this.inAnimation = inAnimation;
}


public void overrideDefaultOutAnimation(Animation outAnimation)
{
this.outAnimation = outAnimation;
}
}

可以使用 overrideDefaultInAnimationoverrideDefaultOutAnimation覆盖原始的 Animation

我的原始动画是 fadeIn/Out,我正在添加 XML 动画文件,以便在屏幕中翻译(翻译到顶部和从顶部)

In _ anime.xml:

    <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="600"
android:fillAfter="false"
android:fromXDelta="0"
android:fromYDelta="-100%p"
android:toXDelta="0"
android:toYDelta="0" />

Out _ anime.xml:

  <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="600"
android:fillAfter="false"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="-100%p" />

如果你只想动画视图的高度(从0到某个数字) ,你可以实现你自己的动画:

final View v = getTheViewToAnimateHere();
Animation anim=new Animation(){
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
// Do relevant calculations here using the interpolatedTime that runs from 0 to 1
v.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, (int)(30*interpolatedTime)));
}};
anim.setDuration(500);
v.startAnimation(anim);

设置属性 android:animateLayoutChanges="true" 在父布局中。

将视图放在一个布局中(如果不是的话) ,并为该布局设置 android:animateLayoutChanges="true"

注意: 这只适用于 API Level 11 + (Android 3.0)

这可以在 API 12及以上版本的单行语句中合理地实现。下面是一个例子,其中 v是您希望动画的视图;

v.animate().translationXBy(-1000).start();

这将滑动 View的问题向左1000px。要将视图滑回 UI,我们可以简单地执行以下操作。

v.animate().translationXBy(1000).start();

希望有人觉得这个有用。

首先得到你想要看到的视图的高度,然后做一个布尔值保存,如果视图显示:

int heigth=0;
boolean showing=false;
LinearLayout layout = (LinearLayout) view.findViewById(R.id.layout);


proDetailsLL.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {


@Override
public void onGlobalLayout() {
// gets called after layout has been done but before display
// so we can get the height then hide the view


proHeight = proDetailsLL.getHeight(); // Ahaha!  Gotcha


proDetailsLL.getViewTreeObserver().removeGlobalOnLayoutListener(this);
proDetailsLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0));
}
});

然后调用显示隐藏视图的方法,并更改布尔值:

slideInOutAnimation(showing, heigth, layout);
proShowing = !proShowing;

方法:

/**
* Method to slide in out the layout
*
* @param isShowing
*            if the layout is showing
* @param height
*            the height to slide
* @param slideLL
*            the container to show
*/
private void slideInOutAnimation(boolean isShowing, int height, final LinearLayout slideLL, final ImageView arroIV) {


if (!isShowing) {
Animation animIn = new Animation() {
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
// Do relevant calculations here using the interpolatedTime that runs from 0 to 1
slideLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int) (heigth * interpolatedTime)));


}
};
animIn.setDuration(500);
slideLL.startAnimation(animIn);
} else {


Animation animOut = new Animation() {
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
// Do relevant calculations here using the interpolatedTime that runs from 0 to 1




slideLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
(int) (heigth * (1 - interpolatedTime))));


}
};
animOut.setDuration(500);
slideLL.startAnimation(animOut);




}


}

我已经使用这两个功能来隐藏和显示视图与过渡动画顺利。

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void expand(final View v, int duration, int targetHeight, final int position) {


int prevHeight = v.getHeight();


v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
valueAnimator.addListener(new AnimatorListenerAdapter() {


@Override
public void onAnimationEnd(Animator animation) {
v.clearAnimation();
}
});


}


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void collapse(final View v, int duration, int targetHeight, final int position) {
if (position == (data.size() - 1)) {
return;
}
int prevHeight = v.getHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animBoolArray.put(position, false);
v.clearAnimation();


}
});
}

试试这个。

view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});

视频动画师:

在 XML 中:

  <ViewAnimator
android:id="@+id/animator_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inAnimation="@anim/slide_down_text"
android:outAnimation="@anim/slide_up_text">


<TextView
android:id="@+id/text_message_authentication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="message_error_authentication" />


<TextView
android:id="@+id/text_message_authentication_connection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="message_error_authentication_connection" />


<TextView
android:id="@+id/text_message_authentication_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="message_error_authentication_field_empty" />


</ViewAnimator>

职能:

public void show(int viewId) {
ViewAnimator animator = (ViewAnimator) findView(animatorId);
View view = findViewById(viewId);


if (animator.getDisplayedChild() != animator.indexOfChild(view)) {
animator.setDisplayedChild(animator.indexOfChild(view));
}
}




private void showAuthenticationConnectionFailureMessage() {
show(R.id.text_message_authentication_connection);
}