zoukankan      html  css  js  c++  java
  • android-自定义控件之液位指示器

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

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

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

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

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

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

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <resources>
     3 
     4     <declare-styleable name="JianWWIndicateProgress">
     5         <attr name="progress_height" format="dimension" />
     6         <attr name="progress_width" format="dimension" />
     7         <attr name="progress_unreachedcolor" format="color" />
     8         <attr name="progress_reached_color" format="color" />
     9         <attr name="progress_reached_height" format="integer" />
    10         <attr name="progress_cheek_width" format="dimension" />
    11         <attr name="progress_cheek_color" format="color" />
    12         <attr name="progress_reached_textsize" format="dimension" />
    13         <attr name="progress_reached_textcolor" format="color" />
    14     </declare-styleable>
    15 
    16 </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

  • 相关阅读:
    element ui 表单清空
    element ui 覆盖样式 方法
    element ui 修改表单值 提交无效
    element ui 抽屉里的表单输入框无法修改值
    element ui 抽屉首次显示 闪烁
    css 左侧高度 跟随右侧内容高度 自适应
    PICNUF框架
    elementui 抽屉组件标题 出现黑色边框
    vue 子组件跨多层调用父组件中方法
    vue 编辑table 数据 未点击提交,table里的数据就发生了改变(深拷贝处理)
  • 原文地址:https://www.cnblogs.com/jww-love-study/p/5277808.html
Copyright © 2011-2022 走看看