私はここで多くのグーグルの結果/質問を見て、垂直アニメーションを介してビューを表示/非表示にする方法を決定しましたが、正確で曖昧ではないものを見つけることができないようです。
別のレイアウトの下にあり、複数の他のウィジェットの上にあるレイアウト(アンドゥバー)があります。このアンドゥバーは、状況に応じて垂直方向にスライドして開き、スライドを閉じる必要があります。
現在、私が今していることは、ビューを表示または非表示に設定することだけです。
親レイアウト内に属性Android:animateLayoutChanges="true"
を設定します。
そうでない場合はビューをレイアウトに配置し、そのレイアウトにAndroid:animateLayoutChanges="true"
を設定します。
注:これはAPIレベル11+(Android 3.0)からのみ機能します
アニメーション付きのレイアウトを表示/非表示する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;
}
}
Animation
およびoverrideDefaultInAnimation
を使用して、元のoverrideDefaultOutAnimation
sをオーバーライドできます
私の元のアニメーションはフェードイン/フェードで、画面のイン/アウトの翻訳用にXMLアニメーションファイルを追加しています(上から上への翻訳)
in_animation.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_animation.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" />
これは、API 12以降の単一行ステートメントで合理的に達成できます。以下は、v
がアニメーション化するビューである例です。
v.animate().translationXBy(-1000).start();
これにより、問題のView
が1000pxだけ左にスライドします。ビューをUIにスライドして戻すには、次のようにします。
v.animate().translationXBy(1000).start();
誰かがこれが役に立つことを願っています。
ビューの高さ(たとえば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);
この2つの関数を使用して、トランジションアニメーションでビューをスムーズに非表示および表示しました。
@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();
}
});
}
おそらくあなたが探しているのは SlidingDrawer です。
TranslateAnimation クラスを使用してみてください。これにより、位置変更用のアニメーションが作成されます。ヘルプをお読みください- http://developer.Android.com/reference/Android/view/animation/TranslateAnimation.html
更新:この例を次に示します。ビューの高さが50で、非表示モードでは10ピクセルのみを表示したい場合。サンプルコードは次のようになります-
TranslateAnimation anim=new TranslateAnimation(0,0,-40,0);
anim.setFillAfter(true);
view.setAnimation(anim);
PS:必要に応じてアニメーションを使用するのに役立つ多くの方法または他の方法があります。コードを完全にカスタマイズする場合は、RelativeLayout.LayoutParamsもご覧ください。ただし、TranslateAnimationを使用する方が使いやすいです。
EDIT:-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に配置し、レイアウトの名前を変更しない場合を想定していますが、他のレイアウトは機能しない可能性があります。それらにアニメーション効果を与えたい場合は、topMarginをゆっくりと増減します。 Thread.sleep()の使用も検討できます。
これを試して。
view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});
まず、見たいビューの高さを取得し、ビューが表示されている場合に保存するブール値を作成します。
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);
}
}
ViewAnimator:
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);
}