千家信息网

Android如何实现流光和光影移动效果

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章将为大家详细讲解有关Android如何实现流光和光影移动效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。概述:开发过程中,看到有些界面用到一道光线在屏幕中
千家信息网最后更新 2025年01月18日Android如何实现流光和光影移动效果

这篇文章将为大家详细讲解有关Android如何实现流光和光影移动效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

概述:

开发过程中,看到有些界面用到一道光线在屏幕中掠过的效果,觉得挺炫的。所以查找相关资料自己实现了一遍。

先上个预览图:

实现思路:

简单来说就是在一个view中绘制好一道光影,并不断改变光影在view中的位置。

1.首先我们先了解一下光影怎么绘制

在了解如何绘制之前,我们先看一下LinearGradient的构造方法

 /**     * Create a shader that draws a linear gradient along a line.     *     * @param x0           The x-coordinate for the start of the gradient line     * @param y0           The y-coordinate for the start of the gradient line     * @param x1           The x-coordinate for the end of the gradient line     * @param y1           The y-coordinate for the end of the gradient line     * @param colors       The sRGB colors to be distributed along the gradient line     * @param positions    May be null. The relative positions [0..1] of     *                     each corresponding color in the colors array. If this is null,     *                     the the colors are distributed evenly along the gradient line.     * @param tile         The Shader tiling mode     *      *      * 翻译过来:     * x0,y0为渐变起点,x1,y1为渐变的终点     *      * colors数组为两点间的渐变颜色值,positions数组取值范围是0~1     * 传入的colors[]长度和positions[]长度必须相等,一一对应关系,否则报错     * position传入null则代表colors均衡分布     *      * tile有三种模式     * Shader.TileMode.CLAMP:    边缘拉伸模式,它会拉伸边缘的一个像素来填充其他区域     * Shader.TileMode.MIRROR:    镜像模式,通过镜像变化来填充其他区域     * Shader.TileMode.REPEAT:重复模式,通过复制来填充其他区域     */LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,            @Nullable float[] positions, @NonNull TileMode tile)

colors[]和positions[]的说明结合下图,这样理解起来应该就比较明朗了

回到正题,如何绘制光影。我们看到的那道光可以参照下图:

根据分析得到我们的着色器是线性着色器(其他着色器请查询相关api):

LinearGradient(a的x坐标, a的y坐标, c的x坐标, c的y坐标, new int[]{Color.parseColor("#00FFFFFF"), Color.parseColor("#FFFFFFFF"), Color.parseColor("#00FFFFFF")}, new float[]{0f, 0.5f, 1f}, Shader.TileMode.CLAMP)

2.给画笔上色。设置着色器mPaint.setShader(mLinearGradient)

3.给定一个数值范围利用数值生成器ValueAnimator产生数值,监听数值变化。每次回调都将该数值传入光影的起点和终点并进行绘制

代码如下:

/** * author: caoyb * created on: 2021/12/20 15:13 * description: */public class ConfigLoadingView extends View {    private Paint mPaint;    private Path mPath;    private LinearGradient mLinearGradient;    private ValueAnimator mValueAnimator;    public ConfigLoadingView(Context context) {        this(context, null);    }    public ConfigLoadingView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public ConfigLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        mPaint = new Paint();        mPath = new Path();    }    private void initPointAndAnimator(int w, int h) {        Point point1 = new Point(0, 0);        Point point2 = new Point(w, 0);        Point point3 = new Point(w, h);        Point point4 = new Point(0, h);        mPath.moveTo(point1.x, point1.y);        mPath.lineTo(point2.x, point2.y);        mPath.lineTo(point3.x, point3.y);        mPath.lineTo(point4.x, point4.y);        mPath.close();                // 斜率k        float k = 1f * h / w;        // 偏移        float offset = 1f * w / 2;                // 0f - offset * 2 为数值左边界(屏幕外左侧), w + offset * 2为数值右边界(屏幕外右侧)                // 目的是使光影走完一遍,加一些时间缓冲,不至于每次光影移动的间隔都那么急促        mValueAnimator = ValueAnimator.ofFloat(0f - offset * 2, w + offset * 2);        mValueAnimator.setRepeatCount(-1);        mValueAnimator.setInterpolator(new LinearInterpolator());        mValueAnimator.setDuration(1500);        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float value = (float) animation.getAnimatedValue();                mLinearGradient = new LinearGradient(value, k * value, value + offset, k * (value + offset),                        new int[]{Color.parseColor("#00FFFFFF"), Color.parseColor("#1AFFFFFF"), Color.parseColor("#00FFFFFF")}, null, Shader.TileMode.CLAMP);                mPaint.setShader(mLinearGradient);                invalidate();            }        });        mValueAnimator.start();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        initPointAndAnimator(widthSize, heightSize);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawPath(mPath, mPaint);    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        mValueAnimator.cancel();    }}

注意点:

LinearGradient里参数之一:
color[]参数只能是16进制的RGB数值,不能传R.color.xxx。R.color.xxx虽然是int型,但拿到的是资源ID,并不是16进制RGB

关于"Android如何实现流光和光影移动效果"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

光影 数值 坐标 模式 效果 移动 区域 屏幕 篇文章 流光 一道 下图 参数 数组 更多 终点 范围 起点 边缘 进制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 国家积极开发 网络技术研发 阿里云js公共库服务器 sql数据库密码查询 铜陵职业技术学院网络安全守则 木马程序盗窃服务器管理员帐号 台湾版我的世界服务器云服务器 彩虹6号官方数据库 国土数据库命名规则 湖南本地软件开发市场价 即墨区微信小程序软件开发 数据库海关 软件开发pm如何管理 网络安全法 软件开发 温州桌面软件开发亿连信 数据库的数字转文本的方法 小学生网络安全的措施和方法 丹江口互联网软件开发经验丰富 给服务器添加白名单 万方数据库期刊全文库官网 魔兽怀旧服怎么开定制服务器 系统集成里需要有软件开发吗 保凯科技软件开发有限公司 幻速网络技术有限公司 wps数据库检索时如何精确日期 坦克世界服务器准星哪里设置 数据库增加一列代码 数据库表编码是什么意思 软件开发标准员岗位职责 政府公用网络安全吗 胜达软件开发
0