android 等级信号状态标识View绘制

1、前言

等级信号状态的View在现在的Android系统中非常的常见,比如手机右上角的电池状态的图标就非常的经典,有几种状态,到了快没电的时候有些还会闪烁提示用户充电;还有的就是一些地图App的GPS信号强度的提示,Wifi信号强度的也有一些,反正应用场景大概就是这样。

2、实现目标效果图

废话别说这么多,直接上干货看图说话

我这个实现的是4种状态的View

1、没有中间显示条的表示空状态

2、有一个红色小圆信号低的状态

3、有一个黄色椭圆的表示一般状态

4、充满绿条的表示良好的状态

在这个View种只给出三个等级的设置,当设置为一等级时,也就是显示只有一个红色的View,然后这个红色的小球隔一段时间闪一次,提示用户。其他等级就是一个简单的绘图显示。

3、实现思路

其实实现过程非常简单,只要简单的绘图就行了,画布类的canvas.drawRoundRect方法可以画圆角的长方形,所以可以用这个方法画出白色背景框,然后在绘制两个,一个黄色的和绿色的,只要控制一下大小和填充模式。红色的用一个canvas.drawCircle搞定,然后就剩下这个闪烁了,刚开始还不太好想怎么搞,其实我们开一个线程在后台,然后隔一个时间更新一下View的状态然后重新绘制一下就可以实现跳动的效果。

4、实现代码

package com.spring.circlview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

public class GpsSigntView extends View {

	public GpsSigntView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}
	public GpsSigntView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	public GpsSigntView(Context context) {
		super(context);
		init();
	}
	private void init(){
		mPaint = new Paint();
		//画笔平滑,不然边缘不堪入目
		mPaint.setAntiAlias(true);
		mPaint.setColor(Color.WHITE);
		//设置画笔不填充
		mPaint.setStyle(Style.STROKE);
		//描边的大小
		mPaint.setStrokeWidth(strokeWidth);
//		mPaint.setAlpha(0x88);
		//三个绘制的矩形范围
		rectF = new RectF(strokeWidth, strokeWidth, width-strokeWidth, height-strokeWidth);
		yellow = new RectF(strokeWidth*2,height*2/5, width-strokeWidth*2, height-strokeWidth*2);
		green = new RectF(strokeWidth*2,strokeWidth*2, width-strokeWidth*2, height-strokeWidth*2);
		//new TwinkleTask().execute(0);
	}

	private Paint mPaint ;
	private RectF rectF ;
	private RectF yellow ;
	private RectF green;
	private int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
	private int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
	private float radus = width/2;
	private float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());

	private int level1_color = Color.RED;

	private int level2_color = Color.YELLOW;

	private int level3_color = Color.GREEN;

	private int status = 1;

        private boolean run = true;

	public int getStatus() {
		return status;
	}
	public void setStatus(int status) {
		this.status = status;
	}
	int Interval = 500;

         //View附加的时候调用
	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		new TwinkleTask().execute(0);
	}
         //View脱离附加的时候调用
	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		run = false;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		//重置View的大小
		setMeasuredDimension(width, height);
	}

	//心跳线程,用来定时更新状态
	class TwinkleTask extends AsyncTask<Integer, Integer, Integer>{
		@Override
		protected Integer doInBackground(Integer... params) {
			while (run) {
				try {
					Thread.sleep(Interval);
					//不是一级以下不更新
					if(status<=1)
						publishProgress(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
                     return 0;
		}
		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			//更新跳动状态,然View在0级和一级之间切换
			status = (status+1)%2;
			invalidate();
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//黑背景不一定是必须的
		canvas.drawColor(Color.BLACK);
		mPaint.setColor(Color.WHITE);
		mPaint.setStyle(Style.STROKE);
		//最外层的白色圆角方形
		canvas.drawRoundRect(rectF, radus, radus, mPaint);
		//状态绘制
		switch (status) {
		case 0:
		{
		}
		break;
		case 1:
		{
			mPaint.setColor(level1_color);
			//设置画笔填充
			mPaint.setStyle(Style.FILL);
			//画一个红色小圆
			canvas.drawCircle(this.width/2, height-this.width/2, radus-strokeWidth*2, mPaint);
		}
		break;
		case 2:
		{
			mPaint.setColor(level2_color);
			//设置画笔填充
			mPaint.setStyle(Style.FILL);
			//绘制黄色的方形
			canvas.drawRoundRect(yellow, radus, radus, mPaint);
		}
		break;
		case 3:
		{
			mPaint.setColor(level3_color);
			//设置画笔填充
			mPaint.setStyle(Style.FILL);
			//填充绿色框
			canvas.drawRoundRect(green, radus, radus, mPaint);
		}
		break;
		}
	}

}

VIew的核心代码就是上面,非常简短,看看大家应该读能懂了

layout代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.spring.circlview.GpsSigntView
        android:id="@+id/level1"
    	android:layout_width="20dp"
    	android:layout_centerInParent="true"
    	android:layout_height="100dp"
    />
    <com.spring.circlview.GpsSigntView
        android:id="@+id/level2"
        android:layout_toRightOf="@+id/level1"
        android:layout_centerInParent="true"
    	android:layout_width="20dp"
    	android:layout_height="100dp"
    />
    <com.spring.circlview.GpsSigntView
        android:id="@+id/level3"
    	android:layout_width="20dp"
    	android:layout_toRightOf="@+id/level2"
    	android:layout_centerInParent="true"
    	android:layout_height="100dp"
    />  

</RelativeLayout>

Main文件调用代码

GpsSigntView level2 = (GpsSigntView) this.findViewById(R.id.level2);
		level2.setStatus(2);
		GpsSigntView level3 = (GpsSigntView) this.findViewById(R.id.level3);
		level3.setStatus(3);

项目文件就不用上传了吧。直接贴View的代码到项目种就可以用了。

android 等级信号状态标识View绘制

时间: 2024-10-19 09:12:36

android 等级信号状态标识View绘制的相关文章

android 电平信号状态识别View平局

1.前言 级信号状态View在今天的Android系统是常见.状态的图标就很的经典,有几种状态,到了快没电的时候有些还会闪烁提示用户充电:还有的就是一些地图App的GPS信号强度的提示.Wifi信号强度的也有一些,反正应用场景大概就是这样. 2.实现目标效果图 废话别说这么多,直接上干货看图说话 我这个实现的是4种状态的View 1.没有中间显示条的表示空状态 2.有一个红色小圆信号低的状态 3.有一个黄色椭圆的表示一般状态 4.充满绿条的表示良好的状态 在这个View种仅仅给出三个等级的设置,

Android应用自定义View绘制方法手册

背景 这篇迟迟难产的文章算是对2015前半年的一个交代吧,那时候有一哥们要求来一发Android Canvas相关总结,这哥们还打赏了,实在不好意思,可是这事一放就给放忘了,最近群里小伙伴催着说没更新博客,坐等更新啥的,随先有这么一篇Android应用开发超级基础的文章诞生了(因为这种文章最好写哈,就是用熟了就行).不得不说下这么久为何一直没更新博客的原因了,首先遇上了过年,我个人崇尚过节就该放下一切好好陪陪亲人,珍惜在一起的时光:其次今年开年很是蛋疼,不是不顺当就是深深的觉得被坑,所以心情也就

Android中View绘制流程以及invalidate()等相关方法分析

前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴望了解 Android 框架层的网友,推荐这本书,希望你们能够在Android开发里学到更多的知识 . 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为 根据之前设置的状态,判断是否需要重新计算视图大小(measure).是否重新需要安置视图的位置(layout).以及是否需要重绘 (d

Android中View绘制流程分析

创建Window 在Activity的attach方法中通过调用PolicyManager.makeNewWindo创建Window,将一个View add到WindowManager时,WindowManagerImpl创建一个ViewRoot来管理该窗口的根View.并通过ViewRoot.setView方法把该View传给ViewRoot. final void attach(Context context, ActivityThread aThread, Instrumentation

Android视图View绘制流程与源码分析(全)

来源:[工匠若水 http://blog.csdn.net/yanbober] 1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原理,记不记得最终分析结果就是下面的关系: 看见没有,如上图中id为content的内容就是整个View树的结构,所以对每个具体View对象的操作,其实就是个递归的实现. 前面<Android触摸屏事件派发机制详解与源码分析一(

Android应用层View绘制流程与源码分析

Android应用层View绘制流程与源码分析 1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原理,记不记得最终分析结果就是下面的关系: 看见没有,如上图中id为content的内容就是整个View树的结构,所以对每个具体View对象的操作,其实就是个递归的实现. 前面<Android触摸屏事件派发机制详解与源码分析一(View篇)>文章的3-1

Android View绘制机制

------------------------------------------------------------------------------ GitHub:lightSky    微博:    light_sky, 即时分享最新技术,欢迎关注 ------------------------------------------------------------------------------ 前言 该篇文章来自一个开源项目android-open-project-analy

1.Android 视图及View绘制分析笔记之setContentView

自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常,我们使用自定义View,需要了解最多的除了事件分发,就是View的绘制过程.然而关于View的绘制,涉及到的知识点纷繁复杂,这么多的代码知识,要梳理起来,肯定是先要找个头.那么平常我们用的最多的方法是哪个方法呢?当然是setContentView()! setContentView 首先我们直接在

Android View绘制及实践

概述 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为: - 判断是否需要重新计算视图大小(measure) - 判断是否重新需要安置视图的位置(layout) - 判断是否需要重绘(draw) 其整个流程图如下: 图片来自:Android 开源项目源码解析 公共技术点中的 View 绘制流程 在Android中View的整个生命周期,调用invalidate和requestLayout会触发一系列的方法,