Android一点 仿淘宝购物车动画

来源:互联网 发布:上海js考试成绩查询 编辑:程序博客网 时间:2024/04/27 23:48

首先看看ios上的淘宝购物车的动画效果ios淘宝购物车动画

这里写图片描述

我们实现的效果
这里写图片描述

看特效是分为两个界面,一个是主view,一个是弹出层。弹出层是用dialog实现的,只是加入了弹出的动画,这里就不分析了,我们主要看主view的动画是怎么实现的,初看好像只是缩放了一点,但是又带着点其它炫耀的动画,其实也是通过旋转、偏移等动画组合的效果。看看动画具体的实现,
1、进入的动画

/**         * 缩放xy,但是y缩放的比例比较小         */        ObjectAnimator fViewScaleXAnim=ObjectAnimator.ofFloat(this,"scaleX",1.0f,0.8f);        fViewScaleXAnim.setDuration(350);        ObjectAnimator fViewScaleYAnim=ObjectAnimator.ofFloat(this,"scaleY",1.0f,0.9f);        fViewScaleYAnim.setDuration(350);        /**         * 重点特效         * 通过x的双重旋转         */        ObjectAnimator fViewRotationXAnim = ObjectAnimator.ofFloat(this, "rotationX", 0f, 10f);        fViewRotationXAnim.setDuration(200);        ObjectAnimator fViewResumeAnim = ObjectAnimator.ofFloat(this, "rotationX", 10f, 0f);        fViewResumeAnim.setDuration(150);        fViewResumeAnim.setStartDelay(200);        /**         * y需要的偏移量         */        ObjectAnimator fViewTransYAnim=ObjectAnimator.ofFloat(this,"translationY",0,-0.01f* height);        fViewTransYAnim.setDuration(350);

2、退出的动画(退出动画是和进入动画相反的)

 ObjectAnimator fViewScaleXAnim=ObjectAnimator.ofFloat(this,"scaleX",0.8f,1.0f);        fViewScaleXAnim.setDuration(350);        ObjectAnimator fViewScaleYAnim=ObjectAnimator.ofFloat(this,"scaleY",0.9f,1.0f);        fViewScaleYAnim.setDuration(350);        ObjectAnimator fViewRotationXAnim = ObjectAnimator.ofFloat(this, "rotationX", 0f, 10f);        fViewRotationXAnim.setDuration(200);        ObjectAnimator fViewResumeAnim = ObjectAnimator.ofFloat(this, "rotationX", 10f, 0f);        fViewResumeAnim.setDuration(150);        fViewResumeAnim.setStartDelay(200);        ObjectAnimator fViewTransYAnim=ObjectAnimator.ofFloat(this,"translationY",-0.01f* height,0);        fViewTransYAnim.setDuration(350);

2、下面开始封装开发我们的ShopAnimatorView(仿淘宝购物车动画View)

ShopAnimatorView.java
package com.flyjun.shopanimator.view;import android.animation.Animator;import android.animation.Animator.AnimatorListener;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.content.Context;import android.util.AttributeSet;import android.view.WindowManager;import android.widget.RelativeLayout;public class ShopAnimatorView extends RelativeLayout{    private int width;    private int height;    private AnimatorSet showAnim;    private AnimatorSet hiddenAnim;    private onShopAnimatorListener shopAnimatorListener;    public ShopAnimatorView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        // TODO Auto-generated constructor stub        this.init();    }    public ShopAnimatorView(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        this.init();    }    public ShopAnimatorView(Context context) {        super(context);        // TODO Auto-generated constructor stub        this.init();    }    /**     * 初始化操作     */    private void init(){        WindowManager wm = (WindowManager) getContext()                .getSystemService(Context.WINDOW_SERVICE);        width = wm.getDefaultDisplay().getWidth();        height = wm.getDefaultDisplay().getHeight();        initShowAnim();        initHiddenAnim();    }    /**     * 进场动画     */    private void initShowAnim(){        /**         * 缩放xy,但是y缩放的比例比较小         */        ObjectAnimator fViewScaleXAnim=ObjectAnimator.ofFloat(this,"scaleX",1.0f,0.8f);        fViewScaleXAnim.setDuration(350);        ObjectAnimator fViewScaleYAnim=ObjectAnimator.ofFloat(this,"scaleY",1.0f,0.9f);        fViewScaleYAnim.setDuration(350);        /**         * 重点特效         * 通过x的双重旋转         */        ObjectAnimator fViewRotationXAnim = ObjectAnimator.ofFloat(this, "rotationX", 0f, 10f);        fViewRotationXAnim.setDuration(200);        ObjectAnimator fViewResumeAnim = ObjectAnimator.ofFloat(this, "rotationX", 10f, 0f);        fViewResumeAnim.setDuration(150);        fViewResumeAnim.setStartDelay(200);        /**         * y需要的偏移量         */        ObjectAnimator fViewTransYAnim=ObjectAnimator.ofFloat(this,"translationY",0,-0.01f* height);        fViewTransYAnim.setDuration(350);        showAnim=new AnimatorSet();        showAnim.playTogether(fViewScaleXAnim,fViewRotationXAnim,fViewResumeAnim,fViewTransYAnim,fViewScaleYAnim);        /**         * 动画开始时可以 显示弹出层         */        showAnim.addListener(new AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                // TODO Auto-generated method stub                if(shopAnimatorListener != null){                    shopAnimatorListener.onShowView();                }            }            @Override            public void onAnimationRepeat(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationEnd(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationCancel(Animator animation) {                // TODO Auto-generated method stub            }        });    }    /**     * 退出动画     */    private void initHiddenAnim(){        ObjectAnimator fViewScaleXAnim=ObjectAnimator.ofFloat(this,"scaleX",0.8f,1.0f);        fViewScaleXAnim.setDuration(350);        ObjectAnimator fViewScaleYAnim=ObjectAnimator.ofFloat(this,"scaleY",0.9f,1.0f);        fViewScaleYAnim.setDuration(350);        ObjectAnimator fViewRotationXAnim = ObjectAnimator.ofFloat(this, "rotationX", 0f, 10f);        fViewRotationXAnim.setDuration(200);        ObjectAnimator fViewResumeAnim = ObjectAnimator.ofFloat(this, "rotationX", 10f, 0f);        fViewResumeAnim.setDuration(150);        fViewResumeAnim.setStartDelay(200);        ObjectAnimator fViewTransYAnim=ObjectAnimator.ofFloat(this,"translationY",-0.01f* height,0);        fViewTransYAnim.setDuration(350);        hiddenAnim=new AnimatorSet();        hiddenAnim.playTogether(fViewScaleXAnim,fViewRotationXAnim,fViewResumeAnim,fViewTransYAnim,fViewScaleYAnim);        /**         * 动画开始时可以 关闭弹出层         */        hiddenAnim.addListener(new AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                // TODO Auto-generated method stub                if(shopAnimatorListener != null){                    shopAnimatorListener.onCancelView();                }            }            @Override            public void onAnimationRepeat(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationEnd(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationCancel(Animator animation) {                // TODO Auto-generated method stub            }        });    }    /**     * 开始进入动画     */    public void startShowAnim(){        showAnim.start();    }    /**     * 开始退出动画     */    public void startHiddenAnim(){        hiddenAnim.start();    }    /**     * 设置什么显示弹出层和关闭弹出层的监听器     */    public void setOnShopAnimatorListener(onShopAnimatorListener shopAnimatorListener){        this.shopAnimatorListener=shopAnimatorListener;    }    public interface onShopAnimatorListener{        public void onShowView();        public void onCancelView();    }}

3、弹出层的封装(实现用的是dialog)

ShopAnimatorDialog.java
package com.flyjun.shopanimator.view;import com.flyjun.shopanimator.R;import android.app.Dialog;import android.content.Context;import android.content.DialogInterface;import android.os.Bundle;import android.view.Gravity;import android.view.View;import android.view.Window;import android.view.WindowManager;public abstract class ShopAnimatorDialog extends Dialog{    private Context context;    private ShopAnimatorView shopAnimatorView;    public ShopAnimatorDialog(Context context,ShopAnimatorView shopAnimatorView) {        super(context);        // TODO Auto-generated constructor stub        this.context=context;        this.shopAnimatorView=shopAnimatorView;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        requestWindowFeature(Window.FEATURE_NO_TITLE);        super.onCreate(savedInstanceState);        init();    }    private void init(){        /**         * 弹出的动画         */        getWindow().setWindowAnimations(R.style.MyDialogAnimation);        setCanceledOnTouchOutside(false);        /**         * 设置在dialog关闭时恢复动画         */        this.setOnCancelListener(new OnCancelListener() {            @Override            public void onCancel(DialogInterface dialog) {                // TODO Auto-generated method stub                shopAnimatorView.startHiddenAnim();            }        });        setContentView(getContentView());        android.view.WindowManager.LayoutParams ll=getWindow().getAttributes();        ll.width=WindowManager.LayoutParams.MATCH_PARENT;        ll.gravity=Gravity.BOTTOM;        getWindow().setAttributes(ll);    }    /**     * 返回ContentView(视图view)     * @return     */    public abstract View getContentView();    public void showDialog(){        if(!isShowing()){            show();        }    }    public void cancelDialog(){        if(isShowing()){            cancel();        }    }}

弹出层动画

<style name="MyDialogAnimation">        <!--进入 -->        <item name="android:windowEnterAnimation">@anim/dialog_enter_anim</item>        <!--退出-->        <item name="android:windowExitAnimation">@anim/dialog_exit_anim</item>    </style>
dialog_enter_anim.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">      <translate        android:fromYDelta="100%"        android:toYDelta="0"        android:duration="300"></translate> </set> 
dialog_exit_anim.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">      <translate        android:fromYDelta="0"        android:toYDelta="100%"        android:duration="300"/> </set>  

4、demo代码,测试的代码就变得简单了
主view的布局

<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"    android:background="@android:color/background_dark"    >    <com.flyjun.shopanimator.view.ShopAnimatorView         android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/shopLayout"        android:background="@android:color/white">        <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello"         android:textSize="20sp"        />         <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="加入购物车"         android:id="@+id/add"        android:layout_alignParentBottom="true"        android:layout_marginBottom="10dp"/>    </com.flyjun.shopanimator.view.ShopAnimatorView></RelativeLayout>
MainActivity.java
package com.flyjun.shopanimator;import com.flyjun.shopanimator.view.ShopAnimatorView;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {    private ShopAnimatorView shopAnimatorView;    private TestDialog testDialog;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 隐藏标题栏                requestWindowFeature(Window.FEATURE_NO_TITLE);                // 隐藏状态栏                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                        WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(R.layout.activity_main);        this.shopAnimatorView=(ShopAnimatorView) findViewById(R.id.shopLayout);        this.testDialog=new TestDialog(this, shopAnimatorView);        findViewById(R.id.add).setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // TODO Auto-generated method stub                shopAnimatorView.startShowAnim();                testDialog.showDialog();            }        });    }    @Override    public void onBackPressed() {        // TODO Auto-generated method stub//      super.onBackPressed();//      shopAnimatorView.startHiddenAnim();        testDialog.cancelDialog();    }}

测试的弹出层

TestDialog.java
package com.flyjun.shopanimator;import com.flyjun.shopanimator.view.ShopAnimatorDialog;import com.flyjun.shopanimator.view.ShopAnimatorView;import android.content.Context;import android.os.Bundle;import android.view.Gravity;import android.view.View;import android.view.WindowManager;public class TestDialog extends ShopAnimatorDialog{    public TestDialog(Context context, ShopAnimatorView shopAnimatorView) {        super(context, shopAnimatorView);        // TODO Auto-generated constructor stub    }    @Override    public View getContentView() {        // TODO Auto-generated method stub        return View.inflate(getContext(), R.layout.test_dialog, null);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        findViewById(R.id.close).setOnClickListener(new android.view.View.OnClickListener() {            @Override            public void onClick(View v) {                // TODO Auto-generated method stub                cancelDialog();            }        });    }}

仿淘宝购物车动画完成,厉害了Flyjun哥!!!

通过ShopAnimatorView的封装和ShopAnimatorDialog弹出层的封装,对于不同的业务和界面都可以轻松的实现了

0 0
原创粉丝点击