由于安卓应用很广泛,在工业中也常有一些应用,比如可以用安卓来去工业中的一些数据进行实现的监测,显示,同时可以做一些自动化控制,当然在这里,我不是做这些自动化控制方面的研究,只是做一个控件,液位指示,其实就是继承自progressbar,然后重新写一测量与绘制,算是对自定义控件进行一下复习。

  我们要做的最终就是下面这个效果:

在这里,我们要做到对这个指示器的以下属性可设置:

容器壁的厚度、容器壁的颜色、容器中液体的宽度、液体总高度、液体当前高度的颜色显示、液体未达到颜色显示、当前高度的文字指示、指示文字大小的显示。

对以上属性的可以设置,会使在实现应用中让显示更加直观人性化。下面就开始我们的指示器的制作。

1.先在项目的res目录下建一个resouce文件,用来定义自定义的属性,这些都会在下面给出的源码中给出,新人可以参考下,老家伙你就绕道吧^^:

 <?xml version="1.0" encoding="utf-8"?>
<resources> <declare-styleable name="JianWWIndicateProgress">
<attr name="progress_height" format="dimension" />
<attr name="progress_width" format="dimension" />
<attr name="progress_unreachedcolor" format="color" />
<attr name="progress_reached_color" format="color" />
<attr name="progress_reached_height" format="integer" />
<attr name="progress_cheek_width" format="dimension" />
<attr name="progress_cheek_color" format="color" />
<attr name="progress_reached_textsize" format="dimension" />
<attr name="progress_reached_textcolor" format="color" />
</declare-styleable> </resources>

2.继承progressbar,这里继承他主要是为了能够用progressbar的getProgress()方法得到当前的progress,与setProgress()方法等progress中提供的一些方法,便于对数据的一些处理。

package com.jianww.firstview;

import com.example.jwwcallback.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar; /**
* 作者:jww 邮箱:bluejww@163.com 时间:2016年3月8日
*/
public class JianWWIndicateProgress extends ProgressBar { private static final int unreached_color = 0Xaa0000ff;// 未到达的颜色
private static final int reached_color = 0Xaaff0000;// 到达颜色
private static final int progress_height = 150;// 容器中液位的默认高度
private static final int progress_width = 100;// 容器中液位的宽度
private static final int reached_height = 60;// 默认到达到达的高度
private static final int progress_cheek_width = 2;// 容器的边框宽度
private static final int progress_cheek_color = 0x660000ff;// 容器的边框颜色
private static final int progress_reached_textsize = 10;// 指示字体尺寸
private static final int progress_reached_textcolor = 0Xff00ff00;// 指示字体颜色 protected int unReachedColor;// 未到达的颜色
protected int reachedColor;// 到达颜色
protected int progressHeight;// 容器中液位的总高度
protected int progressWidth;// 容器中液面的宽度
protected int reachedHeight;// 默认液位到达的到达的高度
protected int cheekWidth;// 容器的边框宽度
protected int cheekColor;// 容器的边框颜色
protected int reachedTextsize;// 指示字体尺寸
protected int reachedTextcolor;// 指示字体颜色 protected float widthZoom;
protected float heightZoom; /**
* dp 2 px
*
*/
protected int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
} /**
* sp 2 px
*
*/
protected int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, getResources().getDisplayMetrics()); } private Paint paintCheek = new Paint();
private Paint paint = new Paint();
private float radio;
private float progressNowHeight; public JianWWIndicateProgress(Context context) {
this(context, null);
} public JianWWIndicateProgress(Context context, AttributeSet asets) {
this(context, asets, 0);
} public JianWWIndicateProgress(Context context, AttributeSet asets, int defStyle) {
super(context, asets, defStyle); obtainStyledAttributes(asets);
// paint.setTextSize(reachedTextsize);
// paint.setColor(reachedTextcolor); } /**
* 定义属性
*
* @param asets属性
*/
private void obtainStyledAttributes(AttributeSet asets) { final TypedArray typeArray = getContext().obtainStyledAttributes(asets, R.styleable.JianWWIndicateProgress); unReachedColor = typeArray.getColor(R.styleable.JianWWIndicateProgress_progress_unreachedcolor,
unreached_color);
reachedColor = typeArray.getColor(R.styleable.JianWWIndicateProgress_progress_reached_color, reached_color);// 到达颜色 progressHeight = (int) typeArray.getDimension(R.styleable.JianWWIndicateProgress_progress_height,
progress_height);
progressWidth = dp2px(
(int) typeArray.getDimension(R.styleable.JianWWIndicateProgress_progress_width, progress_width));// 容器的总宽度
reachedHeight = (int) typeArray.getDimension(R.styleable.JianWWIndicateProgress_progress_reached_height,
reached_height);// 到达的高度 cheekWidth = (int) typeArray.getDimension(R.styleable.JianWWIndicateProgress_progress_cheek_width,
progress_cheek_width);// 容器的边框宽度
cheekColor = typeArray.getColor(R.styleable.JianWWIndicateProgress_progress_cheek_color, progress_cheek_color); reachedTextsize = (int) typeArray.getDimension(R.styleable.JianWWIndicateProgress_progress_reached_textsize,
progress_reached_textsize);// 指示字体尺寸
reachedTextcolor = typeArray.getColor(R.styleable.JianWWIndicateProgress_progress_reached_textcolor,
progress_reached_textcolor);// 指示字体颜色 typeArray.recycle(); } /**
* onMeasure是对绘出的控件将来占的空间进行的安排,
*/
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); int totalWidth = measurdWidth(widthMeasureSpec);
int totalHeight = measurdHeight(heightMeasureSpec); setMeasuredDimension(totalWidth, totalHeight); } /**
*
* @param widthMeasureSpec
* @return 获取宽度尺寸
*/
private int measurdWidth(int widthMeasureSpec) {
int result = 0;
int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);
int widthSpaceMode = MeasureSpec.getMode(widthMeasureSpec); if (widthSpaceMode == MeasureSpec.EXACTLY) {
result = widthSpaceSize;
widthZoom = widthSpaceSize/(progressWidth+2*cheekWidth);
progressWidth = (int) (progressWidth * widthZoom); } else if (widthSpaceMode == MeasureSpec.UNSPECIFIED) {
result = Math.max(widthSpaceSize, getPaddingLeft() + getPaddingRight() + progressWidth + 2 * cheekWidth);
} else if (widthSpaceMode == MeasureSpec.AT_MOST) {
result = Math.min(widthSpaceSize, getPaddingLeft() + getPaddingRight() + progressWidth + 2 * cheekWidth);
} return result;
} /**
*
* @param heightMeasureSpec
* @return获取高度尺寸
*/
private int measurdHeight(int heightMeasureSpec) {
int result = 0;
int heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec);
int heightSpaceMode = MeasureSpec.getMode(heightMeasureSpec); if (heightSpaceMode == MeasureSpec.EXACTLY) {
result = heightSpaceSize;
heightZoom = heightSpaceSize/(progressHeight+2*cheekWidth);
progressHeight = (int) (progressHeight*heightZoom); } else if (heightSpaceMode == MeasureSpec.UNSPECIFIED) {
result = Math.max(heightSpaceSize, getPaddingTop() + getPaddingBottom() + progressHeight + 2 * cheekWidth);
} else if (heightSpaceMode == MeasureSpec.AT_MOST) {
result = Math.min(heightSpaceSize, getPaddingTop() + getPaddingBottom() + progressHeight + 2 * cheekWidth);
} return result;
} /**
* 绘制控件
*/ @Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas); radio = getProgress() * 1.0f / getMax();
progressNowHeight = (int) (progressHeight * radio);
// 存绘画前画布状态
canvas.save();
// 把画布移动到要绘制的点
canvas.translate(getPaddingLeft(), getPaddingRight()); // 绘制容器外壳
paintCheek.setColor(cheekColor);// 画笔颜色
paintCheek.setAntiAlias(true);// 是否过度
paintCheek.setStyle(Style.STROKE);// 空心
paintCheek.setStrokeWidth(cheekWidth);// 边框的宽度
canvas.drawRect(cheekWidth/2, cheekWidth/2, progressWidth + cheekWidth*3/2, progressHeight + cheekWidth*3/2,
paintCheek); // 绘总液位
paint.setColor(unReachedColor);
paint.setStyle(Style.FILL);
canvas.drawRect(cheekWidth, cheekWidth, progressWidth+cheekWidth, progressHeight+cheekWidth,
paint); // 绘当前液位
paint.setStyle(Style.FILL);
paint.setColor(reachedColor);
canvas.drawRect(cheekWidth, cheekWidth + progressHeight - progressNowHeight,
progressWidth + cheekWidth, progressHeight + cheekWidth, paint); // 绘液位指示
String text = getProgress() + "%";
paint.setTextSize(reachedTextsize);
paint.setColor(reachedTextcolor); float textHeight = sp2px(reachedTextsize)/2;
if(progressNowHeight >= progressHeight/2){
canvas.drawText(text, cheekWidth + progressWidth / 2, cheekWidth + progressHeight - progressNowHeight+textHeight, paint);
}else{
canvas.drawText(text, cheekWidth + progressWidth / 2, cheekWidth + progressHeight - progressNowHeight, paint); } canvas.restore(); } }

  3.就是在布局中的引用了

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:jwwprogress="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res/com.example.jwwcallback"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" > <com.jianww.firstview.JianWWIndicateProgress
android:id="@+id/jp_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:max="100"
app:progress_cheek_color="#660000ff"
app:progress_cheek_width="4dp"
app:progress_height="160dp"
app:progress_reached_color="#ff0000"
app:progress_reached_textcolor="#000000"
app:progress_reached_textsize="12sp"
app:progress_unreachedcolor="#4400ff00"
app:progress_width="40dp" /> </RelativeLayout>

  4.就是在acitivity中的初始化与使用。

package com.example.jwwmain;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random; import com.example.jwwcallback.R;
import com.jianww.firstview.JianWWIndicateProgress; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler; public class MainActivity extends Activity { private JianWWIndicateProgress jprogress;
private int nowProgress; private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) { int progress = jprogress.getProgress();
jprogress.setProgress(++progress); if (progress >= 100) {
jprogress.setProgress(0);
}
mHandler.sendEmptyMessageDelayed(100, 100);
};
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
} private void initView() {
jprogress = (JianWWIndicateProgress) findViewById(R.id.jp_progress); mHandler.sendEmptyMessage(100); }
}

  好了,写的比较粗糙,有什么大家可以一块讨论,功能可以实现,但有个别细节没有处理好。^^

360云盘代码分享:访问密码 9294

android-自定义控件之液位指示器的更多相关文章

  1. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...

  2. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  3. Android自定义控件之自定义属性

    前言: 上篇介绍了自定义控件的基本要求以及绘制的基本原理,本篇文章主要介绍如何给自定义控件自定义一些属性.本篇文章将继续以上篇文章自定义圆形百分比为例进行讲解.有关原理知识请参考Android自定义控 ...

  4. Android自定义控件之基本原理

    前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...

  5. Android自定义控件1

    概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...

  6. 一起来学习Android自定义控件1

    概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...

  7. [Xamarin.Android] 自定义控件

    [Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...

  8. android自定义控件实现TextView按下后字体颜色改变

    今天跟大家分享一下Android自定义控件入门,先介绍一个简单的效果TextView,按下改变字体颜色,后期慢慢扩展更强大的功能 直接看图片             第一张是按下后截的图,功能很简单, ...

  9. android 自定义控件(初篇)

    android 自定义控件 在写UI当中很多时候会用到自定义的控件,其实自定义控件就像是定义一个类进行调用就OK了.有些相关的感念可以查看API 下面就用个简单的例子来说明自定义控件: public ...

  10. Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)

    最近一直在学习自定义控件,搜了许多大牛们Blog里分享的小教程,也上GitHub找了一些类似的控件进行学习.发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧. 一.控件介绍: 进度条在App中非 ...

随机推荐

  1. [Android] keystore生成

    keytool -genkey -alias agg_keystore -keyalg RSA -validity 20000 -keystore agg.keystore keytool -expo ...

  2. Sa yo na ra

    总想记点些什么. 都快忘了当初是为什么来到这里呢... 2014年10月,友人给我介绍了一门编程竞赛ACM,并给我演示了一下A+B.于是我知道了ACM的含义. 2014年12月,开始水入门题. 201 ...

  3. asp.net 获取汉字字符串的拼音首字母,含多音字

    需求:在很多时候数据查询的时候,我们希望输入某个人姓名的拼音首字母进行查询,例如“潘长江”,输入“pcj”,就能搜索潘长江相关信息. 实现: #region 获取汉字转换拼音 首字母 public s ...

  4. test 2017-1-5

    //    dpm(drupal_get_filename('module','devel'));//    sites/all/modules/contrib/dev/devel/devel.mod ...

  5. [ubunut]打造Ubuntu下Java开发环境 (转)

    http://www.cnblogs.com/wufengtinghai/p/4542366.html 遇到困难: A Java Runtime Environment (JRE) or Java D ...

  6. express+gulp构建项目(五)swig模板

    这里的文件负责配置swig模板引擎. index.js var jsonHash = require('./json_file'); var staticTag = require("./t ...

  7. js 同for一样效果 (延迟)每秒循环一次 追加

    <script type="text/javascript"> var j = 1;        var timeID = null;        function ...

  8. WSB功能分解(在线考试系统)

    对在线考试系统进行WSB功能分解至三级子功能,并且预估每个子功能所需时间. 一级功能 二级功能 三级功能 预估花费时间(小时) 考试管理员功能模块 培训计划 查询 1.5 重置 1 新增计划 1.5 ...

  9. DevExpress实现为TextEdit设置水印文字

    本文实例展示了DevExpress实现为TextEdit设置水印文字的方法,是一个很实用的技巧.分享给大家供大家参考. 转自 http://blog.csdn.net/yh0503/article/d ...

  10. 关于ViewPager、ViewFilpper、ViewFlow三种实现水平向滑动方式的比较

    ViewPagerViewPager类提供了多界面切换的新效果.新效果有如下特征:[1] 当前显示一组界面中的其中一个界面.[2] 当用户通过左右滑动界面时,当前的屏幕显示当前界面和下一个界面的一部分 ...