Android: hiển thị / ẩn chế độ xem bằng hoạt ảnh


81

Tôi đã xem qua nhiều kết quả / câu hỏi trên google ở ​​đây để xác định cách hiển thị / ẩn một chế độ xem qua hoạt ảnh dọc, nhưng dường như tôi không thể tìm thấy một chế độ xem chính xác hoặc không quá mơ hồ.

Tôi có một bố cục (thanh hoàn tác) bên dưới một bố cục khác và bên trên nhiều tiện ích con khác; thanh hoàn tác này sẽ trượt mở theo chiều dọc và trượt đóng, tùy thuộc vào trường hợp.

Hiện tại tất cả những gì tôi làm bây giờ là đặt chế độ xem ở chế độ hiển thị hoặc biến mất.

Câu trả lời:


64

Đặt thuộc tính android:animateLayoutChanges="true" bên trong bố cục mẹ.

Đặt chế độ xem trong một bố cục nếu không và đặt android:animateLayoutChanges="true"cho bố cục đó.

LƯU Ý: Điều này chỉ hoạt động từ API Cấp 11+ (Android 3.0)


19

Tôi đã tạo một tiện ích mở rộng để RelativeLayouthiển thị / ẩn Bố cục bằng hình ảnh động. Nó có thể mở rộng bất kỳ loại nào Viewđể đạt được những tính năng này.

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;
    }
}

Bạn có thể ghi đè các bản gốc Animationbằng cách sử dụng overrideDefaultInAnimationoverrideDefaultOutAnimation

Hoạt ảnh ban đầu của tôi là fadeIn / Out, tôi đang thêm các tệp hoạt ảnh XML để Dịch ra / vào màn hình (Dịch từ trên xuống và từ trên xuống)

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" />

15

Điều này có thể đạt được một cách hợp lý trong một câu lệnh dòng đơn trong API 12 trở lên. Dưới đây là một ví dụ mà ở đó vlà chế độ xem bạn muốn tạo hoạt ảnh;

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

Thao tác này sẽ trượt Viewcâu hỏi sang trái 1000px. Để trượt chế độ xem trở lại giao diện người dùng, chúng ta chỉ cần làm như sau.

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

Tôi hi vọng ai đó thấy nó hữu ích.


11

Nếu bạn chỉ muốn tạo hoạt ảnh chiều cao của chế độ xem (từ giả sử 0 đến một số nhất định), bạn có thể triển khai hoạt ảnh của riêng mình:

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);

7

Tôi đã sử dụng hai chức năng này để ẩn và hiển thị chế độ xem với hoạt ảnh chuyển tiếp một cách trơn tru.

@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();

            }
        });
    }

4

Hãy thử sử dụng lớp TranslateAnimation , lớp này tạo hoạt ảnh cho các thay đổi vị trí. Hãy thử đọc phần này để được trợ giúp - http://developer.android.com/reference/android/view/animation/TranslateAnimation.html

Cập nhật: Đây là ví dụ cho điều này. Nếu bạn có chiều cao của chế độ xem là 50 và ở chế độ ẩn, bạn chỉ muốn hiển thị 10 px. Mã mẫu sẽ là -

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

Tái bút: Có rất nhiều hoặc các phương pháp khác ở đó để giúp bạn sử dụng hình ảnh động theo nhu cầu của bạn. Ngoài ra, hãy xem RelativeLayout.LayoutParams nếu bạn muốn tùy chỉnh hoàn toàn mã, tuy nhiên việc sử dụng TranslateAnimation sẽ dễ sử dụng hơn.

CHỈNH SỬA: -Complex phiên bản sử dụng 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);

Mã ví dụ này giả định rằng bạn đang đặt chế độ xem của mình trong RelativeLayout, nếu không thay đổi tên của Bố cục, tuy nhiên bố cục khác có thể không hoạt động. Nếu bạn muốn tạo hiệu ứng hoạt hình cho chúng, hãy giảm hoặc tăng topMargin từ từ. Bạn cũng có thể cân nhắc sử dụng Thread.sleep () ở đó.


1
ScaleAnimation không thay đổi vị trí, nó chia tỷ lệ xem ... Bạn đang nhầm lẫn với TranslateAnimation.
Rotemmiz

Tôi đoán bạn đã có những gì bạn cần, và nếu không, đây là mã mẫu - TranslateAnimation anim = new TranslateAnimation (fromX, toX, fromY, toY); view.setAnimation (hoạt ảnh);
noob

3

Thử đi.

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

1

Trước hết, hãy lấy chiều cao của chế độ xem bạn muốn xem và tạo boolean để lưu nếu chế độ xem đang hiển thị:

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));
            }
        });

Sau đó, gọi phương thức để hiển thị ẩn chế độ xem và thay đổi giá trị của boolean:

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

Phương pháp:

/**
     * 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);


        }

    }

1

ViewAnimator:

Trong 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>

Chức năng:

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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.