Android 控件进阶修炼-仿360手机卫士波浪球进度控件
概述
详细
一、概述
像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域。
今天我这用图片bitmap的方式,大概的方法原理是:
(1)首先用clipPath裁剪园区域,
(2)然后用4张图来不断绘制到画布上,再用偏移量来控制移动的速度,从而形成波浪动态效果。
(3)有一点需要注意的是,裁剪圆的时候用到的clipPath这个方法,在android 4.1,和4.2等某些系统上,裁剪出来不是圆,而是矩形,针对这些系统 需要在manifest.xml文件的activity中
将硬件加速关掉,因为默认是开启的。即添加这个:android:hardwareAccelerated="false"
二、效果演示图
手机上的效果:


三、核心实现代码
(1)自定义波浪View的实现:
package com.czm.mysinkingview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Region.Op;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.FrameLayout;
/**
* 水波浪球形进度View
* @author caizhiming
*
*/
public class MySinkingView extends FrameLayout { ....
.... @Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
int width = getWidth();
int height = getHeight(); //裁剪成圆区域
Path path = new Path();
canvas.save();
path.reset();
canvas.clipPath(path);
path.addCircle(width / 2, height / 2, width / 2, Direction.CCW);
canvas.clipPath(path, Op.REPLACE);
if (mFlag == Status.RUNNING) {
if (mScaledBitmap == null) {
mBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.wave2);
mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth(), getHeight(), false);
mBitmap.recycle();
mBitmap = null;
mRepeatCount = (int) Math.ceil(getWidth() / mScaledBitmap.getWidth() + 0.5) + 1;
}
for (int idx = 0; idx < mRepeatCount; idx++) {
canvas.drawBitmap(mScaledBitmap, mLeft + (idx - 1) * mScaledBitmap.getWidth(), (1-mPercent) * getHeight(), null);
}
String str = (int) (mPercent * 100) + "%";
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Style.FILL);
canvas.drawText(str, (getWidth() - mPaint.measureText(str)) / 2, getHeight() / 2 + mTextSize / 2, mPaint);
mLeft += mSpeed;
if (mLeft >= mScaledBitmap.getWidth())
mLeft = 0;
// 绘制外圆环
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(4);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.rgb(33, 211, 39));
canvas.drawCircle(width / 2, height / 2, width / 2 - 2, mPaint);
postInvalidateDelayed(20);
}
canvas.restore();
} }
(2)布局文件的实现:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context=".MainActivity" >
<com.czm.mysinkingview.MySinkingView
android:id="@+id/sinking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<ImageView
android:id="@+id/image"
android:layout_width="400dp"
android:layout_height="400dp"
android:src="@drawable/charming2" />
</com.czm.mysinkingview.MySinkingView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_test"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text="体验" /> </LinearLayout>
</RelativeLayout>
(3)如何使用自定义波浪View:
package com.czm.mysinkingview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
/**
* 使用并测试用例页
*
* @author caizhiming
*/
public class MainActivity extends Activity {
private MySinkingView mSinkingView;
private float percent = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSinkingView = (MySinkingView) findViewById(R.id.sinking);
findViewById(R.id.btn_test).setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
test();
}
});
percent = 0.56f;
mSinkingView.setPercent(percent);
} private void test() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
percent = 0;
while (percent <= 1) {
mSinkingView.setPercent(percent);
percent += 0.01f;
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
percent = 0.56f;
mSinkingView.setPercent(percent);
// mSinkingView.clear();
}
});
thread.start();
}
}
四、项目代码目录结构图

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
Android 控件进阶修炼-仿360手机卫士波浪球进度控件的更多相关文章
- Android 自定义View修炼-仿360手机卫士波浪球进度的实现
像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域. 今天我这用图片bitmap的方式,大概的方法原理是: (1)首先用 ...
- ANDROID——仿360手机卫士的旋转打分控件
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简介 灵感源自360手机卫,主要功能就是实现显示评分或等级的效果.并稍微改良了一下,有更好 ...
- 仿360手机卫士界面效果android版源码
仿360手机卫士界面效果android版,这个今天一大早在源码天堂的那个网站上看到了一个那个网站最新更新的一个源码,所以就分享给大学习一下吧,布局还挺不错的,而且也很简单的,我就不把我修改的那个分享出 ...
- Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...
- Android仿360手机卫士悬浮窗效果
请看下图: 首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下 ...
- Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...
- Android静默安装实现方案,仿360手机助手秒装和智能安装功能
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/47803149 之前有非常多朋友都问过我.在Android系统中如何才干实现静默安装 ...
- Android手机安全软件的恶意程序检测靠谱吗--LBE安全大师、腾讯手机管家、360手机卫士恶意软件检测方法研究
转载请注明出处,谢谢. Android系统开放,各大论坛活跃,应用程序分发渠道广泛,这也就为恶意软件的传播提供了良好的环境.好在手机上安装了安全软件,是否能有效的检测出恶意软件呢?下边针对LBE安全大 ...
- 由360手机卫士谈起——让你的service获取最高权限。
近日来,我在倒腾360手机卫士的时候,发现,你无论是把他数据清空,还是把它强行停止以后,甚至是把它卸载以后,它的service都没有被Android的系统干掉,依然是岿然不动了.我就感到了纳闷了,后来 ...
随机推荐
- Go语言之进阶篇请求报文格式分析
1. 请求报文格式分析 示例: package main import ( "fmt" "net" ) func main() { //监听 listener, ...
- Linux下线程同步的几种方法
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1. 初始化锁 int pthrea ...
- scrapy框架系列 (4) Scrapy Shell
Scrapy Shell Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据 ...
- vs2010使用svn--浅谈AnkhSvn
(1)建立本地的服务器版本.Subversion->Add to Subversion 此功能的作用是从将新创建的工程添加到svn服务器上 (2)从svn检出 Subversion->Op ...
- ORM数据库框架 greenDAO SQLite MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- android 框架层 常用类介绍
名称 功能描述 示意图 activitymanager 管理应用程序的周期并提供常用的回退功能 window manager 窗口管理者 content provider 用于访问另一个的数据,或者共 ...
- java多线程之间的顺序问题
java 多线程: 这样写有问题的:这样写可以的: package com.test; import java.util.concurrent.CountDownLatch; import java. ...
- Sublime Es6教程2-基本语法
2.基本语法 let, const, forEach,for of class, extends, super arrow functions, template string, destructur ...
- Python 各种测试框架简介
转载:https://blog.csdn.net/yockie/article/details/47415265 一.doctest doctest 是一个 Python 发行版自带的标准模块.本篇将 ...
- nova network工作原理及配置
1. nova network简介 网络管理和配置是云计算中一项非常重要的功能.nova自带的nova-network实现了一些基本的网络模型,允许虚拟机之间的相互通信及虚拟机对internet的访问 ...