支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能。
效果如下所示:
思路:
就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画
还有就是这是好几个圆,然后执行的动画有个延迟效果,其实这些动画是放在一起执行的,熟悉属性动画的知道已经给我们提供了同步执行动画和顺序执行动画的实现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仿支付宝咻一咻功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!