高仿支付宝咻一咻功能

高仿支付宝咻一咻功能,全部使用属性动画完成


效果如下:




实现方法分析:

1.按钮的动画:按钮的点击监听使用onTouchListener,监听action_down和action_up两个事件,按下时缩小按钮,放开时先放大再缩小到原来的大小。

2.循环缩放的外圈:外圈首先使用Imageview显示在xml布局中,然后通过属性动画设置无限循环的缩放,当用户发生按钮点击时,隐藏外圈并且发散波纹,用户停止点击后3秒(使用handler发送延时消息,显示外圈,并且继续执行无限循环的缩放动画)。

3.扩散波纹:通过add动态生成的Imageview到frameLayout中,然后对imageview设置透明度和方法的动画,实现了波纹的扩散,在动画结束时,remove掉frameLaout中添加进去的Imageview。


以下为实现代码


自定义控件的代码:

public class XiuView extends FrameLayout {

    /**
     * 按钮
     */
    private ImageView iv_btn;

    /**
     * 循环外圈
     */
    private ImageView iv_out_circle;

    /**
     * 装波纹的容器
     */
    private FrameLayout fl_move_circle;

    /**
     * 按钮点击监听
     */
    private OnBtnPressListener onBtnPressListener;

    public void setOnBtnPressListener(OnBtnPressListener onBtnPressListener) {
        this.onBtnPressListener = onBtnPressListener;
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            iv_out_circle.setVisibility(VISIBLE);
            startOutCircleAnim();
        }
    };

    public XiuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    /**
     * 初始化控件个监听按钮
     */
    private void initView() {
        View v = LayoutInflater.from(getContext()).inflate(R.layout.xiu_view, null, false);
        addView(v, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        iv_btn = (ImageView) findViewById(R.id.iv_btn);
        iv_out_circle = (ImageView) findViewById(R.id.iv_out_circle);
        fl_move_circle = (FrameLayout) findViewById(R.id.fl_move_circle);
        iv_btn.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN://手指按钮
                        //手指又按下,取消掉显示循环波纹的消息
                        handler.removeMessages(1);
                        pressDown();
                        break;
                    case MotionEvent.ACTION_UP://手指抬起
                        //取消掉循环的波纹
                        iv_out_circle.setVisibility(GONE);
                        pressUp();
                        addMoveCircle();
                        //发送延时消息,3秒后继续显示循环波纹
                        handler.sendEmptyMessageDelayed(1, 3000);
                        if (onBtnPressListener != null) {
                            onBtnPressListener.btnClick();
                        }
                        break;
                }
                return true;
            }
        });
        startOutCircleAnim();
    }

    /**
     * 发散波纹
     */
    private void addMoveCircle() {
        final ImageView imageView = new ImageView(getContext());
        LayoutParams lp = new LayoutParams(dip2px(getContext(), 100), dip2px(getContext(), 100));
        lp.gravity = Gravity.CENTER;
        imageView.setLayoutParams(lp);
        imageView.setImageResource(R.mipmap.outcircle);
        fl_move_circle.addView(imageView);
        ObjectAnimator outCircleAnimX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 5f);
        ObjectAnimator outCircleAnimY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 5f);
        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(imageView, "alpha", 0.6f, 0);
        outCircleAnimX.setDuration(1500);
        outCircleAnimY.setDuration(1500);
        alphaAnim.setDuration(1500);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(outCircleAnimX, outCircleAnimY, alphaAnim);
        animatorSet.start();
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //移除掉刚才添加的波纹
                fl_move_circle.removeView(imageView);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

    /**
     * 开始循环的放大缩小波纹
     */
    private void startOutCircleAnim() {
        ObjectAnimator outCircleAlpha = ObjectAnimator.ofFloat(iv_out_circle, "alpha", 0.2f, 0.6f);
        outCircleAlpha.setDuration(1000);

        ObjectAnimator outCircleAnimX = ObjectAnimator.ofFloat(iv_out_circle, "scaleX", 1f, 1.18f, 1f);
        ObjectAnimator outCircleAnimY = ObjectAnimator.ofFloat(iv_out_circle, "scaleY", 1f, 1.18f, 1f);
        outCircleAnimX.setDuration(2000);
        outCircleAnimY.setDuration(2000);
        outCircleAnimX.setRepeatCount(ValueAnimator.INFINITE);
        outCircleAnimY.setRepeatCount(ValueAnimator.INFINITE);
        outCircleAnimX.setInterpolator(new LinearInterpolator());
        outCircleAnimY.setInterpolator(new LinearInterpolator());
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(outCircleAnimX, outCircleAnimY, outCircleAlpha);
        animatorSet.start();
    }

    /**
     * 按下按钮
     */
    private void pressDown() {
        AnimatorSet animatorSet = new AnimatorSet();
        ObjectAnimator scaleXIn = ObjectAnimator.ofFloat(iv_btn, "scaleX", 1f, 0.94f);
        scaleXIn.setDuration(400);
        scaleXIn.setInterpolator(new LinearInterpolator());
        ObjectAnimator scaleYIn = ObjectAnimator.ofFloat(iv_btn, "scaleY", 1f, 0.94f);
        scaleYIn.setDuration(400);
        scaleYIn.setInterpolator(new LinearInterpolator());
        animatorSet.playTogether(scaleXIn, scaleYIn);
        animatorSet.start();
    }

    /**
     * 抬起按钮
     */
    private void pressUp() {
        AnimatorSet animatorSet1 = new AnimatorSet();
        ObjectAnimator scaleXOut = ObjectAnimator.ofFloat(iv_btn, "scaleX", 0.94f, 1.06f, 1f);
        scaleXOut.setDuration(500);
        scaleXOut.setInterpolator(new LinearInterpolator());
        ObjectAnimator scaleYOut = ObjectAnimator.ofFloat(iv_btn, "scaleY", 0.94f, 1.06f, 1f);
        scaleYOut.setDuration(500);
        scaleYOut.setInterpolator(new LinearInterpolator());
        animatorSet1.playTogether(scaleXOut, scaleYOut);
        animatorSet1.start();
    }

    /**
     * 根据手机的分辨率从 dip 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 按钮点击监听
     */
    public interface OnBtnPressListener {
        void btnClick();
    }

    /**
     * 模拟点击
     */
    public void onceClick(){
        //取消掉循环的波纹
        iv_out_circle.setVisibility(GONE);
        pressDown();
        pressUp();
        addMoveCircle();
    }
}

自定义控件对应的xml布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent">

    <FrameLayout
        android:id="@+id/fl_move_circle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent" />

    <ImageView
        android:id="@+id/iv_out_circle"
        android:layout_width="120dp"
        android:layout_height="120dp "
        android:layout_gravity="center"
        android:alpha="0.6"
        android:src="@mipmap/outcircle" />

    <ImageView
        android:id="@+id/iv_btn"
        android:layout_width="110dp"
        android:layout_height="110dp"
        android:layout_gravity="center"
        android:src="@mipmap/circle" />
</FrameLayout>


下面为使用到的素材

按钮的图标:circle.png


外圈图片:outcircle.png



控件使用的xml布局:

<com.tzj.tzjcustomview.xiuview.XiuView
        android:layout_marginTop="50dp"
        android:id="@+id/xiu_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值