Android 自定义控件 loding小球

2024-08-30 16:32

本文主要是介绍Android 自定义控件 loding小球,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以下为参照博客    http://blog.csdn.net/guimianhao9833/article/details/74858472 


首先看下效果图:

步骤:
1.继承view,并需要三个构造函数。
public MyView(Context context) {//注意不要默认实现,记得修改。
    this(context, null);
}public MyView(Context context, AttributeSet attrs) {//注意不要默认实现,记得修改。
    this(context, attrs, 0);
}public MyView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);
    //初始化工作
    init(context, attrs);
}
初始化工作init:
1)在attrs.xml中定义控件需要的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <attr name="color" format="color"/>
        <attr name="text" format="string"/>
    </declare-styleable>
</resources>
2)自定义控件一般都需要定义相关的属性,我们获取它并对它进行相关的设置;
由效果图可知,这个自定义控件需要定义一个画笔用来画图形路径;
需要定义一个画笔用来画文字;
需要Path用来定义闭合波浪路径;
为了实现控件无线循环的动画效果,需要对其进行相关的监听动作并实时刷新。
private void init(Context context, AttributeSet attrs) {//1.定义需要的属性
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);
    //颜色和文字
    color = a.getColor(R.styleable.MyView_color, Color.rgb(238,121,66));
    text = a.getString(R.styleable.MyView_text);
    //记得调用这个方法回收
    a.recycle();
    //2.1定义图形及路径填充画笔的相关值(抗锯齿、填充、防抖动)
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setColor(color);
    mPaint.setDither(true);
    //2.2定义文字画笔的相关值(抗锯齿、白色、粗体)
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setColor(Color.WHITE);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);
    //2.3定义闭合波浪路径
    path = new Path();
    //3.实现无线循环的动画效果
    //ValueAnimator定时器,属性动画ObjectAnimator就是它的一个子类
    ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
    //让动画无限重复,每次从头开始,一个周期1000毫秒
    animator.setDuration(1000);
    animator.setRepeatCount(ValueAnimator.INFINITE);
    animator.setRepeatMode(ValueAnimator.RESTART);
    //补上一个线性插值器,使得动画流畅
    animator.setInterpolator(new LinearInterpolator());
    //监听获得过程值,实时进行刷新
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Override
        public void onAnimationUpdate(ValueAnimator animation) {currentPercent = animation.getAnimatedFraction();
            //刷新
            invalidate();
        }});
    //动画开始
    animator.start();
}
 2.onDraw方法,重中之重!
绘制流程:

1)绘制底部蓝色的文字
2)绘制闭合的波浪路径,颜色为蓝色
3)绘制白色的文字
4)根据已有的波浪路径去裁剪文字,使得文字上半部门为蓝色,文字下半部门为白色
(因为先绘制在下部,后绘制的在上部)
5)在已有的画布canvas上画一个圆,也就是裁剪成圆形
@Override
protected void onDraw(Canvas canvas) {//super.onDraw(canvas);
    //1.画底部蓝色的字
    textPaint.setColor(color);
    drawCenterText(canvas, textPaint, "");
    //2.画上层白色的字
    textPaint.setColor(Color.WHITE);
    //3.生成闭合波浪路径
    path = getActionPath(currentPercent);
    //4.剪裁文字
    canvas.clipPath(path);
    //5.剪裁成圆形(SRC 源像素)
    canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mPaint);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    //6.画波浪(DST 目标像素)
    canvas.drawPath(path, mPaint);
    mPaint.setXfermode(null);
    drawCenterText(canvas, textPaint, "");
}
生成闭合的波浪路径的方法getActionPath:
这个波浪可以由 二阶贝塞尔曲线。如下的例子,起点为(100,100),然后移动相对于起点的两个位置变化为(150,0),(200,100)。
Path path=new Path();
path.moveTo(100,100);
path.rQuadTo(50,-100,100,0);
               图解:

1)画两个周期的波浪
2)画右侧的直线
3)画下边的直线
private Path getActionPath(float percent) {Path path = new Path();
    int x = -mWidth;
    //1.当前x点坐标(根据动画进度水平推移,一个动画周期推移的距离为一个mWidth    x += percent * mWidth;
    //2.波形的起点
    path.moveTo(x, mHeight / 2);
    //控制点的相对宽度
    int kongzhiWidth = mWidth / 4;
    //控制点的相对高度=mHeight的二十分之3
    int kongzhiHeight = mHeight / 20 * 3;
    //3.画第一个周期,一个周期为一上一下
    path.rQuadTo(kongzhiWidth, kongzhiHeight, kongzhiWidth * 2, 0);
    path.rQuadTo(kongzhiWidth, -kongzhiHeight, kongzhiWidth * 2, 0);
    //画第二个周期,如此循环下去
    path.rQuadTo(kongzhiWidth, kongzhiHeight, kongzhiWidth * 2, 0);
    path.rQuadTo(kongzhiWidth, -kongzhiHeight, kongzhiWidth * 2, 0);
    //4.画右侧的直线
    path.lineTo(x + mWidth * 2, mHeight);
    //5.画下边的直线
    path.lineTo(x, mHeight);
    //自动闭合补出左边的直线
    path.close();
    return path;
}
   画中间的文字drawCenterText:
private void drawCenterText(Canvas canvas, Paint textPaint, String text) {//画一个规定位置的矩形
    Rect rect = new Rect(0, 0, mWidth, mHeight);
    //由于默认是位于左边的,所以这样设置到中间来。
    textPaint.setTextAlign(Paint.Align.CENTER);
    Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
    float top = fontMetrics.top;
    float bottom = fontMetrics.bottom;

    int centerY = (int) (rect.centerY() - top / 2 - bottom / 2);
    canvas.drawText(text, rect.centerX(), centerY, textPaint);
}
3.onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    if (widthMode == MeasureSpec.EXACTLY) {mWidth = widthSize;
    }if (heightMode == MeasureSpec.EXACTLY) {mHeight = heightSize;
    }setMeasuredDimension(mWidth, mHeight);
    textSize = mWidth / 2;
    textPaint.setTextSize(textSize);
}
自定义控件,要好好学哦。

这篇关于Android 自定义控件 loding小球的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121338

相关文章

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超