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

相关文章

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Android实现悬浮按钮功能

《Android实现悬浮按钮功能》在很多场景中,我们希望在应用或系统任意界面上都能看到一个小的“悬浮按钮”(FloatingButton),用来快速启动工具、展示未读信息或快捷操作,所以本文给大家介绍... 目录一、项目概述二、相关技术知识三、实现思路四、整合代码4.1 Java 代码(MainActivi

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否