【问题标题】:Android animation flip cover and ease up (open book animation)Android 动画翻盖和放松(翻书动画)
【发布时间】:2015-08-28 16:30:14
【问题描述】:

那里的按钮/图片很少。点击我想要这样的动画:

(图像打开方式类似)书籍封面打开,相关活动/片段以动画形式轻松打开并全屏显示。

有什么想法吗?

cook app iOS 中发生类似情况,cook app 链接:https://itunes.apple.com/us/app/cook/id687560846?mt=8

P.S : 我添加了动画,gif 加载完成后会不间断运行。

【问题讨论】:

    标签: android animation android-animation


    【解决方案1】:

    您可以使用标准 android animator 实现此动画,并将动画书作为一组多个 ImageViews - 每个用于页面表示:Cover、BackCover、FirstPage。并在动画完成后启动活动或显示片段。

    动画:

    • x 和 y 比例尺,ObjectAnimator.ofFloat(mCover, "scaleY", ...)
    • x 和 y 变换,ObjectAnimator.ofFloat(mCover, "x", ...)
    • y-旋转ObjectAnimator.ofFloat(mCover, "rotationY", ...)

    看我的例子

    (当然,此示例需要一些优化/修复,但为了更好地理解就足够了):

    public class MainActivity extends AppCompatActivity {
    
        private ImageView mPage1;
        private ImageView mCover;
        private ImageView mCoverFullScreen;
    
        private AnimatorSet mAnimIncrease;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mCoverFullScreen = (ImageView) findViewById(R.id.cover_full_screen);
            mPage1 = (ImageView) findViewById(R.id.page1);
            mCover = (ImageView) findViewById(R.id.cover);
            mCover.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mAnimIncrease.start();
                }
            });
    
            mCoverFullScreen.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mCover.getMeasuredHeight() <= 0 || mCoverFullScreen.getMeasuredHeight() <= 0) {
                        return;
                    }
                    if (Build.VERSION.SDK_INT >= 16) {
                        mCoverFullScreen.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        mCoverFullScreen.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
    
                    initAnimator(1000);
                }
            });
        }
    
        private void initAnimator(long animationDuration) {
    
            mAnimIncrease = new AnimatorSet();
            TimeInterpolator interpolator = new LinearInterpolator();
    
            float deltaX = mCover.getMeasuredWidth() / 2f;
            float deltaY = mCoverFullScreen.getY() - mCover.getY();
            float scale = mCoverFullScreen.getMeasuredHeight() / (float) mCover.getMeasuredHeight();
            float scaleMiddle = (scale + 1) / 2f;
    
            float xStart = mCover.getX();
            float xEnd = xStart + deltaX;
            float xMiddle = xStart + deltaX * interpolator.getInterpolation(0.5f);
            float xScaledEnd = xStart + deltaX * scale;
    
            float yStart = mCover.getY();
            float yEnd = yStart + deltaY;
            float yMiddle = yStart + deltaY * interpolator.getInterpolation(0.5f);
    
            AnimatorSet coverFrontSet = new AnimatorSet();
            coverFrontSet.setDuration(animationDuration / 2);
            coverFrontSet.playTogether(
                    ObjectAnimator.ofFloat(mCover, "rotationY", 0f, -90f),
                    ObjectAnimator.ofFloat(mCover, "pivotX", 0f),
                    ObjectAnimator.ofFloat(mCover, "x", xStart, xMiddle),
                    ObjectAnimator.ofFloat(mCover, "y", yStart, yMiddle),
                    ObjectAnimator.ofFloat(mCover, "scaleY", 1, scaleMiddle),
                    ObjectAnimator.ofFloat(mCover, "scaleX", 1, scaleMiddle)
            );
            coverFrontSet.addListener(new AnimatorListenerStub() {
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    mCover.setImageResource(R.drawable.cover);
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mCover.setImageResource(R.drawable.cover_back);
                }
            });
    
            AnimatorSet coverBackSet = new AnimatorSet();
            coverBackSet.setDuration(animationDuration / 2);
            coverBackSet.playTogether(
                    ObjectAnimator.ofFloat(mCover, "rotationY", -90f, -180f),
                    ObjectAnimator.ofFloat(mCover, "pivotX", 0f),
                    ObjectAnimator.ofFloat(mCover, "x", xMiddle, xEnd),
                    ObjectAnimator.ofFloat(mCover, "y", yMiddle, yEnd),
                    ObjectAnimator.ofFloat(mCover, "scaleY", scaleMiddle, scale),
                    ObjectAnimator.ofFloat(mCover, "scaleX", scaleMiddle, scale)
            );
    
            AnimatorSet coverSet = new AnimatorSet();
            coverSet.play(coverBackSet).after(coverFrontSet);
    
            AnimatorSet page1Set = new AnimatorSet();
            page1Set.setDuration(animationDuration);
            page1Set.playTogether(
                    ObjectAnimator.ofFloat(mPage1, "scaleX", 1, scale),
                    ObjectAnimator.ofFloat(mPage1, "scaleY", 1, scale),
                    ObjectAnimator.ofFloat(mPage1, "x", xStart, xScaledEnd)
            );
    
            mAnimIncrease.play(coverSet).with(page1Set);
            mAnimIncrease.setInterpolator(interpolator);
        }
    }
    

    和布局:

    <RelativeLayout 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"
                    tools:context=".MainActivity"
        >
    
        <ImageView
            android:id="@+id/page1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/page1"
            />
    
        <ImageView
            android:id="@+id/cover"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/cover"
            />
    
        <ImageView
            android:id="@+id/cover_full_screen"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </RelativeLayout>
    

    【讨论】:

    • 谢谢 Alexander,这是一个很好的解决方法,但我需要在平板电脑上使用它,但打开盖子会在屏幕外(完全不可见)几秒钟,有什么办法吗?跨度>
    • @Haris 这就是标准旋转 Y 动画的工作方式。我可以建议您 2 个解决方案: 1.(更简单)将您的动画分为两部分 - [1](打开并增加到一半)和 [2](只是增加)。 2.实现自定义动画以应用自定义rotationY动画。不幸的是,我不知道如何处理第二种解决方案:)。我希望这会对你有所帮助。
    • 谢谢,是的,我正在尝试实施第一个解决方案
    • @Oleksandr 解决方案正在工作,但如何应用关闭书动画?
    • @NooruddinLakhani 你应该交换动画的第三和第四个参数并且可能改变动画的顺序。很遗憾,没有时间提供扩展答案。
    【解决方案2】:

    您应该能够使用 android.graphics.Movie 类来显示(和运行)动画 gif。

    你可以在这里找到一些关于课程的帮助:http://developer.android.com/reference/android/graphics/Movie.html

    但可能有更多帮助的是这里的一个工作示例:http://androidosbeginning.blogspot.com.au/2010/09/gif-animation-in-android.html

    【讨论】:

    • 谢谢,我不想做gif,我要活动过渡动画。
    猜你喜欢
    • 2015-07-02
    • 2011-03-22
    • 2012-04-13
    • 2011-09-18
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多