Android App开发之图像加工中给图像添加水波动态特效(附源码和演示视频 简单易懂)

简介: Android App开发之图像加工中给图像添加水波动态特效(附源码和演示视频 简单易懂)

需要图片集和源码请点赞关注收藏后评论区留言~~~

一、给图像添加水波特效

除了给图片添加静态装饰物,有时还想添加动态的特效,比如说水波涟漪特效。水波特效要求一个同心圆持续向外扩散,圆圈在数秒之内从圆心扩散到视图边缘,从而实现了涟漪扩散动画,这个持续扩散的操作可通过定时机制来实现,简单地说,结合处理器工具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>

创作不易 觉得有帮助请 点赞关注收藏~~~

相关文章
|
10天前
|
开发框架 小程序 前端开发
圈子社交app前端+后端源码,uniapp社交兴趣圈子开发,框架php圈子小程序安装搭建
本文介绍了圈子社交APP的源码获取、分析与定制,PHP实现的圈子框架设计及代码编写,以及圈子小程序的安装搭建。涵盖环境配置、数据库设计、前后端开发与接口对接等内容,确保平台的安全性、性能和功能完整性。通过详细指导,帮助开发者快速搭建稳定可靠的圈子社交平台。
108 18
|
19天前
|
PHP
全新uniapp小说漫画APP小说源码/会员阅读/月票功能
价值980的uniapp小说漫画APP小说源码/会员阅读/月票功能
75 20
|
17天前
|
JSON 缓存 前端开发
HarmonyOS NEXT 5.0鸿蒙开发一套影院APP(附带源码)
本项目基于HarmonyOS NEXT 5.0开发了一款影院应用程序,主要实现了电影和影院信息的展示功能。应用包括首页、电影列表、影院列表等模块。首页包含轮播图与正在热映及即将上映的电影切换显示;电影列表模块通过API获取电影数据并以网格形式展示,用户可以查看电影详情;影院列表则允许用户选择城市后查看对应影院信息,并支持城市选择弹窗。此外,项目中还集成了Axios用于网络请求,并进行了二次封装以简化接口调用流程,同时添加了请求和响应拦截器来处理通用逻辑。整体代码结构清晰,使用了组件化开发方式,便于维护和扩展。 该简介概括了提供的内容,但请注意实际开发中还需考虑UI优化、性能提升等方面的工作。
77 11
|
14天前
|
前端开发 算法 安全
一站式搭建相亲交友APP丨交友系统源码丨语音视频聊天社交软件平台系统丨开发流程步骤
本文详细介绍了一站式搭建相亲交友APP的开发流程,涵盖需求分析、技术选型、系统设计、编码实现、测试、部署上线及后期维护等环节。通过市场调研明确平台定位与功能需求,选择适合的技术栈(如React、Node.js、MySQL等),设计系统架构和数据库结构,开发核心功能如用户注册、匹配算法、音视频聊天等,并进行严格的测试和优化,确保系统的稳定性和安全性。最终,通过云服务部署上线,并持续维护和迭代,提供一个功能完善、安全可靠的社交平台。
81 6
|
17天前
|
移动开发 小程序 前端开发
使用php开发圈子系统特点,如何获取圈子系统源码,社交圈子运营以及圈子系统的功能特点,圈子系统,允许二开,免费源码,APP 小程序 H5
开发一个圈子系统(也称为社交网络或社群系统)可以是一个复杂但非常有趣的项目。以下是一些关键特点和步骤,帮助你理解如何开发、获取源码以及运营一个圈子系统。
92 3
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
56 19
|
22天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
68 3
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
62 14
|
1月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
1月前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
36 5
下一篇
开通oss服务