Android自定义View水波纹

简介: Android自定义View水波纹

根据正弦:y=Asin(ωx+φ)+h 画出静态的曲线。

再通过改变相位:ωx+φ,来实现动画。

不会制作.gif图,如图:从Android Studio截下来的。


image.png

/**
 * @ClassName WaveView
 * @Description TODO
 * @Author shufeng.jiang
 * @Date 2022/4/20 14:06
 */
public class WaveView extends View {
    /**
     *  y=Asin(ωx+φ)+h 周期:T=2π/ω
     */
    /* 画笔 */
    Paint paint1  = new Paint();
    public WaveView(Context context) {
        super(context);
    }
    public WaveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }
    public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }
    /* 控件宽 */
    float xAxis=0;
    /* 控件高 */
    float yAxis=0;
    /* 正弦函数的周期 */
    float mCycle=0;
    /* 曲线下移的距离 */
    float wavelevel=0;
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        xAxis = getWidth();      // 控件的宽
        yAxis = getHeight() ;    // 控件的高
        wavelevel = yAxis/2;    // wavelevel 为 y=Asin(ωx+φ)+h 的 h
        mCycle = (float) (2 * Math.PI / xAxis/1.5); // 根据宽度计算三角函数周期
        waveAnim();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        createShader(canvas);
    }
    float startXAxis=0;
    private void createShader(Canvas canvas){
        for(int i=0;i<xAxis;i++){
            float startYAxis =  (float) (100*Math.sin(mCycle*i+startXAxis)+wavelevel);
            float endYAxis = (float) (100*Math.sin(mCycle*(i+1)+startXAxis)+wavelevel);
           //  canvas.drawLine(i,  startYAxis, i+1,  endYAxis , paint1);    // 这样是绘制正弦曲线
            canvas.drawLine(i,  startYAxis, i+1,  yAxis, paint1);    // 这样将绘制正弦曲线以下的部分。
        }
    }
    private void initPaint(){
        paint1.setColor(Color.BLUE);    // 设置画笔颜色
        paint1.setStrokeWidth(4.0f);      // 设置画笔宽度
        paint1.setAntiAlias(true);       // 是否抗锯齿
       /** Paint.Style.STROKE 只绘制图形轮廓(描边) 
         *Paint.Style.FILL 只绘制图形内容 
         *Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容
       */
        paint1.setStyle(Paint.Style.STROKE);      
    }
    public void waveAnim() {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0F, 1.0f);
        valueAnimator.setDuration(110000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float aFloat = Float.valueOf(animation.getAnimatedValue().toString());
                //核心代码,重要的是在动画的过程中改变正弦波的相位,从 0 到 控件宽 无限变化就可以实现正弦波的移动
                startXAxis = getWidth() * aFloat;
                invalidate();
            }
        });
        valueAnimator.start();
    }
}

到次绘制完成!

第一次自定义View,各位大佬勿喷。目前写简书的意义就是做笔记,方便自己后期借鉴。


相关文章
|
1月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
27 1
|
2月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
106 0
|
1月前
|
XML 前端开发 Android开发
Android:UI:Drawable:View/ImageView与Drawable
通过本文的介绍,我们详细探讨了Android中Drawable、View和ImageView的使用方法及其相互关系。Drawable作为图像和图形的抽象表示,提供了丰富的子类和自定义能力,使得开发者能够灵活地实现各种UI效果。View和ImageView则通过使用Drawable实现了各种图像和图形的显示需求。希望本文能为您在Android开发中使用Drawable提供有价值的参考和指导。
40 2
|
1月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
1月前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
41 5
|
2月前
|
缓存 数据处理 Android开发
在 Android 中使用 RxJava 更新 View
【10月更文挑战第20天】使用 RxJava 来更新 View 可以提供更优雅、更高效的解决方案。通过合理地运用操作符和订阅机制,我们能够轻松地处理异步数据并在主线程中进行 View 的更新。在实际应用中,需要根据具体情况进行灵活运用,并注意相关的注意事项和性能优化,以确保应用的稳定性和流畅性。可以通过不断的实践和探索,进一步掌握在 Android 中使用 RxJava 更新 View 的技巧和方法,为开发高质量的 Android 应用提供有力支持。
|
2月前
|
缓存 调度 Android开发
Android 在子线程更新 View
【10月更文挑战第21天】在 Android 开发中,虽然不能直接在子线程更新 View,但通过使用 Handler、AsyncTask 或 RxJava 等方法,可以实现子线程操作并在主线程更新 View 的目的。在实际应用中,需要根据具体情况选择合适的方法,并注意相关的注意事项和性能优化,以确保应用的稳定性和流畅性。可以通过不断的实践和探索,进一步掌握在子线程更新 View 的技巧和方法,为开发高质量的 Android 应用提供支持。
43 2
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
29 2
|
Android开发
自定义android 4.0以上的对话框风格
做个笔记,这里是Dialog的风格,如果是用AlertDialog创建的,不能直接用。在styles.xml的写法: 22sp @color/font_green 1 true @st...
709 0