Android 自定义view仿支付宝咻一咻功能
作者:coderinchina 发布时间:2023-06-01 07:42:09
标签:android,支付宝,咻一咻
支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能。
效果如下所示:
思路:
就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画
还有就是这是好几个圆,然后执行的动画有个延迟效果,其实这些动画是放在一起执行的,熟悉属性动画的知道已经给我们提供了同步执行动画和顺序执行动画的实现api,也会会有人说这几个view就是在onDraw()方法中画几个圆,可能会说我还要继承容器view去onLayout()方法中这些子view添加在某个特定的区域,当然这也是可以的,其实简单的就是以图片为中心(图片imageview在父view的中心),然后画圆,指定每个字view的宽和高就行了,具体看代码:
package com.zhifubaoxiuyixiu.view;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import java.util.ArrayList;
/**
* Created by admin on 2016/12/29.
*/
public class ZhifubaoFrameLayout extends FrameLayout {
private int rippleColor = Color.parseColor("#0099CC");//水波纹的颜色
private int radius = 0;//水波纹圆的半径
private long anim_duration = 3000;//动画执行的时间
private int water_ripple_count = 6;
private int scale = 6;//动画缩放比例
private long animDelay;//动画延迟的时间
private Paint paint;
private AnimatorSet animatorSet;
private ArrayList<Animator> animatorList;
private FrameLayout.LayoutParams rippleParams;
private ArrayList<WateRipple> rippleViewList=new ArrayList<WateRipple>();
private boolean isAnimRunning = false;
public ZhifubaoFrameLayout(Context context) {
this(context,null);
}
public ZhifubaoFrameLayout(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public ZhifubaoFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
addChildView();
initAnim();
}
/**
* 初始化动画
*/
private void initAnim() {
animatorSet = new AnimatorSet();
animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
animatorList=new ArrayList<Animator>();
for(int i=0;i<rippleViewList.size();i++){//几个水波纹
final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(rippleViewList.get(i), "ScaleX", 1.0f, scale);
scaleXAnimator.setRepeatCount(ObjectAnimator.INFINITE);
scaleXAnimator.setRepeatMode(ObjectAnimator.RESTART);
scaleXAnimator.setStartDelay(i * animDelay);
scaleXAnimator.setDuration(anim_duration);
animatorList.add(scaleXAnimator);
final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(rippleViewList.get(i), "ScaleY", 1.0f, scale);
scaleYAnimator.setRepeatCount(ObjectAnimator.INFINITE);
scaleYAnimator.setRepeatMode(ObjectAnimator.RESTART);
scaleYAnimator.setStartDelay(i * animDelay);
scaleYAnimator.setDuration(anim_duration);
animatorList.add(scaleYAnimator);
final ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rippleViewList.get(i), "Alpha", 1.0f, 0f);
alphaAnimator.setRepeatCount(ObjectAnimator.INFINITE);
alphaAnimator.setRepeatMode(ObjectAnimator.RESTART);
alphaAnimator.setStartDelay(i * animDelay);
alphaAnimator.setDuration(anim_duration);
animatorList.add(alphaAnimator);
}
animatorSet.playTogether(animatorList);
}
/**
* 添加水波纹子view
*/
private void addChildView() {
radius = 32;
animDelay=350;
rippleParams=new FrameLayout.LayoutParams((int)(2*(radius)),(int)(2*(radius)));
rippleParams.gravity = Gravity.CENTER;
for(int i=0;i<water_ripple_count;i++){//几个水波纹
WateRipple rippleView=new WateRipple(getContext(),paint);
addView(rippleView,rippleParams);
rippleViewList.add(rippleView);
}
}
/**
* 初始化画笔
*/
private void initPaint() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(rippleColor);
paint.setStyle(Paint.Style.FILL);
}
/**
* 开启动画
*/
public void startRippleAnimation(){
if(!isRunning()){
for(WateRipple wateRipple:rippleViewList){
wateRipple.setVisibility(VISIBLE);
}
animatorSet.start();
isAnimRunning=true;
}
}
/**
* 动画停止运行
*/
public void stopAnimation(){
if(isRunning()){
animatorSet.cancel();
isAnimRunning=false;
}
}
/**
* 判断是否动画在运行
* @return
*/
public boolean isRunning(){
return isAnimRunning;
}
/**
* ui不可见时关闭动画
* @param visibility
*/
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if(visibility==View.INVISIBLE||visibility ==View.GONE){
stopAnimation();
}
}
}
每个水波纹view
package com.zhifubaoxiuyixiu.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
/**
* Created by admin on 2016/12/29.
*/
public class WateRipple extends View {
private Paint mPaint;
public WateRipple(Context context, Paint paint){
super(context);
if(paint==null){
this.mPaint = new Paint();
}else{
this.mPaint = paint;
}
setVisibility(View.INVISIBLE);//刚开始设置不可见
}
public WateRipple(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int radius=(Math.min(getWidth(),getHeight()))/2;
canvas.drawCircle(radius,radius,radius,mPaint);
}
}
圆形图片:
package com.zhifubaoxiuyixiu.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;
import com.zhifubaoxiuyixiu.R;
/**
* Created by admin on 2016/12/29.
*/
public class CircleView extends View {
private BitmapShader bitmapShaderp ;
private ShapeDrawable shapeDrawable;
public CircleView(Context context) {
this(context,null);
}
public CircleView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initBitmap();
}
private void initBitmap() {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.grid);
shapeDrawable = new ShapeDrawable(new OvalShape());
bitmapShaderp = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
shapeDrawable.getPaint().setShader(bitmapShaderp);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
shapeDrawable.setBounds(0,0,getWidth(),getHeight());
shapeDrawable.draw(canvas);
}
}
布局文件:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.zhifubaoxiuyixiu.view.ZhifubaoFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
>
<com.zhifubaoxiuyixiu.view.CircleView
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerInParent="true"
android:id="@+id/imageView"
android:layout_gravity="center"
android:src="@mipmap/grid"/>
</com.zhifubaoxiuyixiu.view.ZhifubaoFrameLayout>
</RelativeLayout>
使用:
package com.zhifubaoxiuyixiu;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import com.zhifubaoxiuyixiu.view.CircleView;
import com.zhifubaoxiuyixiu.view.ZhifubaoFrameLayout;
public class MainActivity extends Activity {
private CircleView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (CircleView) findViewById(R.id.imageView);
final ZhifubaoFrameLayout root = (ZhifubaoFrameLayout) findViewById(R.id.root);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
root.startRippleAnimation();
}
});
}
}
以上所述是小编给大家介绍的Android 自定义view仿支付宝咻一咻功能网站的支持!
来源:http://blog.csdn.net/coderinchina/article/details/53926832


猜你喜欢
- 本文实例为大家分享了如何使用ItemTouchHelper实现侧滑删除和拖拽的具体代码,供大家参考,具体内容如下1. 定义一个简单bean类
- 一、为什么要编码不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解
- 一、介绍Android的大部分自定义软键盘主要是通过android自带控件KeyboardView实现的。那么,有没有其他简单易上手的方法来
- 一、配置文件内容mybatis.xml就是Mybatis的全局配置文件。全局配置文件需要在头部使用约束文件。<?xml version
- 1. 文件上传a. 看看@FIEL注解的属性/** * 上传文件时使用该注解 设置文件相关参数 */@Retention(Retention
- Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常
- 前言有位朋友,某天突然问东哥:在 Java 中,防止重复提交最简单的方案是什么?这句话中包含了两个关键信息,第一:防止重复提交;第二:最简单
- 图像滤波在opencv中可以有多种实现形式自定义滤波如使用3×3的掩模:对图像进行处理.使用函数filter2D()实现#include&l
- 本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示。广义上讲,Java中的随机数的有三种产生方式:(01). 通过System
- 将Program类的删除,将里面的静态类Main修改后放入服务类中:partial class Server1 : ServiceBase&
- 前言关于链表这一块,写了多篇博客,学习了顺序表、单链表、及其一些练习题顺序表:传送门:顺序表单链表:传送门:单链表1
- SpringBoot切面拦截@PathVariable参数及抛出异常的全局处理微信小程序的接口验证防止非法请求,登录的时候获取openId生
- 问题描述:在用fabric集成后编译出现如下错误,Error:Cause: hostname in certificate didn'
- 简介Spring Security 是为了基于Spring的应用程序提供的声明式安全保护的安全性框架。Spring Security 提供了
- 近年来,二维码的使用越来越风生水起,笔者最近手头也遇到了一个需要使用二维码扫码登录网站的活,所以研究了一下这一套机制,并用代码实现了整个流程
- Spring中有很多继承于aware中的接口,这些接口到底是做什么用到的。aware,翻译过来是知道的,已感知的,意识到的,所以这些接口从字
- 本文主要介绍Java中的rmi的基本使用1:项目架构api:主要是接口的定义,url地址,端口号rmiconsumer:rmi服务的调用者r
- Java提供一种机制叫做序列化,通过有序的格式或者字节序列持久化java对象,其中包含对象的数据,还有对象的类型,和保存在对象中
- 一、前言1.1 实现目标服务A调用服务B1和B2(B1和B2提供同种服务),当服务B1/B2在停止和重新发布阶段,或B1/B2有一个服务故障
- Android 设置Edittext获取焦点并弹出软键盘/** * EditText获取焦点并显示软键盘 */