有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Android中为ViewPager实现翻转动画(添加GIF)

编辑:添加我的视图的XML布局(如何实现安卓翻转动画(添加GIF))

顶部布局:iImage 底部布局:布局

我想实现垂直ViewPager,如下图所示。已实现垂直ViewPager,但无法实现翻转动画

任何代码片段或库

我的定制VerticalViewPage类在VerticalPageTransformer中使用普通动画Motionevent实现了垂直ViewPager

public class VViewPager2 extends ViewPager {

String TAG = "VViewPager";

float x = 0;
float mStartDragX = 0;
private static final float SWIPE_X_MIN_THRESHOLD = 15; // Decide this magical number as per your requirement

private boolean disableSwipe = false;

public VViewPager2(@NonNull Context context) {
    super(context);
    init();
}

public VViewPager2(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
    // setPageTransformer(true, new PagerTransformer());
}

private void init() {
    // The majority of the magic happens here
    setPageTransformer(true, new VerticalPageTransformer());
    // The easiest way to get rid of the overscroll drawing that happens on the left and right
    setOverScrollMode(OVER_SCROLL_NEVER);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (getAdapter() != null) {
        if (getCurrentItem() >= 0 || getCurrentItem() < getAdapter().getCount()) {
            swapXY(event);
            final int action = event.getAction();
            switch (action & MotionEventCompat.ACTION_MASK) {
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    mStartDragX = event.getX();
                    if (x < mStartDragX
                            && (mStartDragX - x > SWIPE_X_MIN_THRESHOLD)
                            && getCurrentItem() > 0) {
                        Log.i(TAG, "down " + x + " : " + mStartDragX + " : " + (mStartDragX - x));
                        setCurrentItem(getCurrentItem() - 1, true);
                        return true;
                    } else if (x > mStartDragX
                            && (x - mStartDragX > SWIPE_X_MIN_THRESHOLD)
                            && getCurrentItem() < getAdapter().getCount() - 1) {
                        Log.i(TAG, "up " + x + " : " + mStartDragX + " : " + (x - mStartDragX));
                        mStartDragX = 0;
                        setCurrentItem(getCurrentItem() + 1, true);
                        return true;
                    }
                    break;
            }
        } else {
            mStartDragX = 0;
        }
        swapXY(event);
        return !disableSwipe && super.onTouchEvent(swapXY(event));
    }
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean intercepted = !disableSwipe && super.onInterceptTouchEvent(swapXY(event));
    if ((event.getAction() & MotionEventCompat.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
        x = event.getX();
    }
    swapXY(event); // return touch coordinates to original reference frame for any child views
    return intercepted;
}

public void disableScroll(Boolean disableSwipe) {
    //When disable = true not work the scroll and when disble = false work the scroll
    this.disableSwipe = disableSwipe;
    Log.d(TAG, "disableSwipe " + disableSwipe);
}

/**
 * Swaps the X and Y coordinates of your touch event.
 */
private MotionEvent swapXY(MotionEvent ev) {
    float width = getWidth();
    float height = getHeight();

    float newX = (ev.getY() / height) * width;
    float newY = (ev.getX() / width) * height;

    ev.setLocation(newX, newY);

    return ev;
}

private class VerticalPageTransformer implements PageTransformer {
    private static final float MIN_SCALE = 0.75f;

    @Override
    public void transformPage(@NonNull View view, float position) {

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 1) { // [-1,1]
            view.setAlpha(1);

            // Counteract the default slide transition
            view.setTranslationX(-position * view.getWidth());
            // set Y position to swipe in from top
            float yPosition = position * view.getHeight();
            view.setTranslationY(yPosition);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

            ScaleAnimation flipDown = new ScaleAnimation(1.0f, 1.0f, -1.0f, 0.0f, 1, 1);
            flipDown.setDuration(500);
            flipDown.setFillAfter(true); // If fillAfter is true, the transformation that this animation performed will persist when it is finished.
            // view.startAnimation(flipDown);


        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            // Counteract the default slide transition
            view.setTranslationX(view.getWidth() * -position);

            //set Y position to swipe in from top
            float yPosition = position * view.getHeight();
            view.setTranslationY(yPosition);
            view.setScaleX(1);
            view.setScaleY(1);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

}

我想从顶部和顶部在这些布局之间切换屏幕;底部

<安卓x.cardview.widget.CardView
            app:cardCornerRadius="6dp"
            app:cardPreventCornerOverlap="true"
            app:cardUseCompatPadding="true"
            app:cardBackgroundColor="@color/White"
            安卓:layout_width="match_parent"
            安卓:layout_height="match_parent">

            <ImageView
                安卓:id="@+id/ivImage"
                安卓:layout_width="match_parent"
                安卓:layout_height="match_parent"
                安卓:contentDescription="@string/activity_images"
                安卓:scaleType="fitXY" />

            <LinearLayout
                安卓:id="@+id/layoutL"
                安卓:layout_weight="5.5"
                安卓:layout_marginStart="10dp"
                安卓:layout_marginEnd="10dp"
                安卓:layout_marginTop="8dp"
                安卓:orientation="vertical"
                安卓:layout_width="match_parent"
                安卓:layout_height="0dp">

                <TextView
                    安卓:id="@+id/tvTTitle"
                    安卓:layout_width="match_parent"
                    安卓:layout_height="wrap_content"
                    安卓:gravity="center_vertical"
                    安卓:padding="4dp"
                    安卓:textStyle="bold"
                    安卓:text="@string/Topic_Title"
                    安卓:textColor="@color/Black"
                    安卓:textSize="20sp" />

                <TextView
                    安卓:id="@+id/postDetails"
                    安卓:textAllCaps="false"
                    安卓:text="text"
                    安卓:textSize="12sp"
                    安卓:layout_marginStart="4dp"
                    安卓:textStyle="normal"
                    安卓:textColor="@color/Silver"
                    安卓:layout_width="match_parent"
                    安卓:layout_height="wrap_content"/>

                <TextView
                    安卓:id="@+id/tvTopicDesc"
                    安卓:layout_width="wrap_content"
                    安卓:layout_height="wrap_content"
                    安卓:padding="4dp"
                    安卓:lineSpacingExtra="2dp"
                    安卓:text="@string/invalid_email_contactno"
                    安卓:textAllCaps="false"
                    安卓:textColor="#6D6D6D"
                    安卓:textSize="15sp" />

            </LinearLayout>

        </安卓x.cardview.widget.CardView>

我想创建一个类似于给定GIF的布局,我尝试了很多动画,但效果并不理想


共 (1) 个答案

  1. # 1 楼答案

    尝试下面的解决方案,并将您的SecondView设置为Xml格式

    yourButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            final ObjectAnimator oa1 = ObjectAnimator.ofFloat(yourFirstView, "scaleY", 1f, 0f);
            final ObjectAnimator oa2 = ObjectAnimator.ofFloat(yourSecondView, "scaleY", 0f, 1f);
            oa1.setInterpolator(new DecelerateInterpolator());
            oa1.setDuration(1000);
            oa2.setInterpolator(new AccelerateDecelerateInterpolator());
            oa2.setDuration(1000);
            oa1.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    yourFirstView.setVisibility(View.GONE);
                    yourSecondView.setVisibility(View.VISIBLE);
                    oa2.start();
                }
            });
            oa1.start();
        }
    });
    

    输出

    enter image description here

    我希望这能帮助你