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

  • 相关阅读:
    my functions.h
    MFC中GDI之CBitmap(位图)
    MFC中GDI之CFont(字体)
    MFC中GDI之CBrush(画刷)
    MFC中SDI设置状态栏显示时间
    MFC中自定义消息
    MFC常用控件类
    MFC中改变窗口大小MoveWindow...
    MFC中建立关联变量的几种方式
    软件默认端口整理
  • 原文地址:https://www.cnblogs.com/jww-love-study/p/5277808.html
Copyright © 2011-2022 走看看