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的代码到项目种就可以用了。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。