需要图片集和源码请点赞关注收藏后评论区留言~~~
一、给图像添加水波特效
除了给图片添加静态装饰物,有时还想添加动态的特效,比如说水波涟漪特效。水波特效要求一个同心圆持续向外扩散,圆圈在数秒之内从圆心扩散到视图边缘,从而实现了涟漪扩散动画,这个持续扩散的操作可通过定时机制来实现,简单地说,结合处理器工具Handler与任务工具Runnable由处理器对象定时执行刷新任务即可完成水波动画。
视频如下 也可前往我的主页观看
水波动画
效果图如下 如果读者觉得水波变化速度太快,可以自行调整水波的扩散速度,具体在widget包下的RippleImageView类中修改 修改里面的postDealyed里面的参数时间即可
public void run() { mRadius += mIncrease; if (mRadius*mRadius > (mWidth*mWidth/4 + mHeight*mHeight/4)) { // 水波半径已超出对角线 mRadius = 0; mIncrease = Utils.dip2px(mContext, 5); } else { // 水波半径未超出对角线 mIncrease += Utils.dip2px(mContext, 1); mHandler.postDelayed(this, 500); // 延迟50毫秒后再次启动水波刷新任务 } postInvalidate(); // 立即刷新视图(线程安全方式) } };
代码如下
Java主类
package com.example.picture; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import com.example.picture.widget.RippleImageView; public class ImageRippleActivity extends AppCompatActivity { private RippleImageView riv_scene; // 声明一个水波图像对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_ripple); riv_scene = findViewById(R.id.riv_scene); riv_scene.setOnClickListener(v -> riv_scene.startRipple()); initRippleSpinner(); // 初始化水波特效下拉框 } // 初始化水波特效下拉框 private void initRippleSpinner() { ArrayAdapter<String> rippleAdapter = new ArrayAdapter<>(this, R.layout.item_select, rippleNameArray); Spinner sp_ripple = findViewById(R.id.sp_ripple); sp_ripple.setPrompt("请选择水波特效"); sp_ripple.setAdapter(rippleAdapter); sp_ripple.setOnItemSelectedListener(new RippleSelectedListener()); sp_ripple.setSelection(0); } private String[] rippleNameArray = {"白色", "红色", "绿色", "蓝色", "黄色", "青色", "紫色"}; private int[] rippleColoArray = {0x99ffffff, 0x99ff0000, 0x9900ff00, 0x990000ff, 0x99ffff00, 0x9900ffff, 0x99ff00ff}; class RippleSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { riv_scene.setRippleColor(rippleColoArray[arg2]); // 设置水波的颜色 riv_scene.startRipple(); // 开始播放水波动画 } public void onNothingSelected(AdapterView<?> arg0) {} } }
RipperImageView类
package com.example.picture.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; import android.widget.ImageView; import com.example.picture.util.Utils; public class RippleImageView extends ImageView { private Context mContext; // 声明一个上下文对象 private Paint mPaint = new Paint(); // 声明一个画笔对象 private int mWidth, mHeight; // 视图宽度、视图高度 private int mRadius; // 水波的半径 private int mIncrease; // 半径的增量 private Handler mHandler = new Handler(Looper.myLooper()); // 声明一个处理器对象 public RippleImageView(Context context) { this(context, null); } public RippleImageView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mIncrease = Utils.dip2px(mContext, 5); mPaint.setColor(0x99ffffff); // 设置画笔颜色 } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = getMeasuredWidth(); // 获取视图的实际宽度 mHeight = getMeasuredHeight(); // 获取视图的实际高度 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mRadius > 0) { canvas.drawCircle(mWidth/2, mHeight/2, mRadius, mPaint); // 画水波 } } // 设置水波的颜色 public void setRippleColor(int color) { mPaint.setColor(color); // 设置画笔颜色 } // 开始播放水波动画 public void startRipple() { mRadius = 0; mHandler.post(mRipple); // 立即启动水波刷新任务 } // 定义一个水波刷新任务 private Runnable mRipple = new Runnable() { @Override public void run() { mRadius += mIncrease; if (mRadius*mRadius > (mWidth*mWidth/4 + mHeight*mHeight/4)) { // 水波半径已超出对角线 mRadius = 0; mIncrease = Utils.dip2px(mContext, 5); } else { // 水波半径未超出对角线 mIncrease += Utils.dip2px(mContext, 1); mHandler.postDelayed(this, 500); // 延迟50毫秒后再次启动水波刷新任务 } postInvalidate(); // 立即刷新视图(线程安全方式) } }; }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="5dp" android:gravity="center" android:text="水波特效样式:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_ripple" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:spinnerMode="dialog" /> </LinearLayout> <com.example.picture.widget.RippleImageView android:id="@+id/riv_scene" android:layout_width="match_parent" android:layout_height="270dp" android:src="@drawable/ylxs" /> </LinearLayout>
创作不易 觉得有帮助请 点赞关注收藏~~~