带进度边框的自定义TextView
来源:互联网 发布:ipad客户端办公软件 编辑:程序博客网 时间:2024/05/23 02:03
带进度边框的自定义TextView
下文中有些Progress笔误写成了Process。就不改了
效果图:
继承TextView进行自定义View。并增加几个自定义的属性。
- 进度条的颜色
- 进度条背景颜色
- 进度条宽度
values下面新建一个attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="ProgressView"> <attr name="backgroundColor" format="color"/> <attr name="progressColor" format="color"/> <attr name="progressWidth" format="dimension"></attr> </declare-styleable> </resources>
然后获取属性:
TypedArray mTypedArray=context.obtainStyledAttributes(attrs,R.styleable.ProgressView); progressColor=mTypedArray.getColor(R.attr.progressColor, Color.GREEN); backgroundColor=mTypedArray.getColor(R.attr.backgroundColor, Color.TRANSPARENT); progressWidth=mTypedArray.getDimension(R.attr.progressWidth, 5);
在layout的XML中使用
<com.example.processtextview.ProcessTextView android:id="@+id/myTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" custom:backgroundColor ="@color/whitesmoke" custom:progressColor ="@color/orange" custom:progressWidth ="4dp" />
2.
在原有的基础上,在TextView的矩形边框处,绘制4根线作为进度条的背景。
然后根据Process来绘制进度。
示例代码:
ProcessTextView
package com.example.processtextview;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.Path;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.TextView;public class ProcessTextView extends TextView { private int progressColor; private int backgroundColor; private float progressWidth; private double progress = 0; private final Paint progressPaint; private final Paint backgroundPaint; private Canvas canvas; private int canvasWidth, canvasHight; public ProcessTextView(Context context) { this(context, null); } public ProcessTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ProcessTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.ProcessTextView); try { progressColor = mTypedArray.getColor( R.styleable.ProcessTextView_progressColor, Color.GREEN); backgroundColor = mTypedArray.getColor( R.styleable.ProcessTextView_backgroundColor, Color.TRANSPARENT); progressWidth = mTypedArray.getDimension( R.styleable.ProcessTextView_progressWidth, 5); } finally { mTypedArray.recycle(); } backgroundPaint = new Paint(); backgroundPaint.setColor(backgroundColor); backgroundPaint.setStrokeWidth(progressWidth); backgroundPaint.setAntiAlias(true); backgroundPaint.setStyle(Style.STROKE); progressPaint = new Paint(); progressPaint.setColor(progressColor); progressPaint.setStrokeWidth(progressWidth); progressPaint.setAntiAlias(true); progressPaint.setStyle(Style.STROKE); // 把内边距设为进度条宽度,防止遮盖文字 this.setPadding((int) progressWidth, (int) progressWidth, (int) progressWidth, (int) progressWidth); } @Override protected void onDraw(Canvas canvas) { this.canvas = canvas; super.onDraw(canvas); this.canvasWidth = canvas.getWidth(); this.canvasHight = canvas.getHeight(); drawBackgroundProcess(); drawProcess(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); } protected void drawBackgroundProcess() { Path backgroundPath = new Path(); backgroundPath.moveTo(0, progressWidth / 2); backgroundPath.lineTo(canvasWidth - progressWidth / 2, progressWidth / 2); backgroundPath.lineTo(canvasWidth - progressWidth / 2, canvasHight - progressWidth / 2); backgroundPath.lineTo(progressWidth / 2, canvasHight - progressWidth / 2); backgroundPath.lineTo(progressWidth / 2, 0); canvas.drawPath(backgroundPath, backgroundPaint); } protected void drawProcess() { if(this.progress<0) return; if(this.progress>100) this.progress=100; Path processPath = new Path(); processPath.moveTo(0, progressWidth / 2); //根据不同情况来设定path if (this.progress <= (50 * canvasWidth) / (canvasWidth + canvasHight)) {// 只需要画顶边 processPath.lineTo((float) ((canvasWidth + canvasHight)*this.progress/50), progressWidth / 2); } else if (this.progress > (50 * canvasWidth) / (canvasWidth + canvasHight) && this.progress <= 50) {//画到右边 processPath.lineTo(canvasWidth - progressWidth / 2, progressWidth / 2); processPath.lineTo(canvasWidth - progressWidth / 2, (float) ((canvasWidth + canvasHight)*this.progress/50-canvasWidth)); } else if (this.progress > 50 && this.progress <= 50 + (50 * canvasWidth) / (canvasWidth + canvasHight)) {//画到底边 processPath.lineTo(canvasWidth - progressWidth / 2, progressWidth / 2); processPath.lineTo(canvasWidth - progressWidth / 2, canvasHight - progressWidth / 2); processPath.lineTo((float) (2*canvasWidth+canvasHight-(canvasWidth + canvasHight)*this.progress/50), canvasHight - progressWidth / 2); } else {//画到左边 processPath.lineTo(canvasWidth - progressWidth / 2, progressWidth / 2); processPath.lineTo(canvasWidth - progressWidth / 2, canvasHight - progressWidth / 2); processPath.lineTo(progressWidth / 2, canvasHight - progressWidth / 2); processPath.lineTo(progressWidth / 2, (float) (2*canvasWidth+2*canvasHight-(canvasWidth + canvasHight)*this.progress/50)); } canvas.drawPath(processPath, progressPaint); } // Setter And Getter public int getProgressColor() { return progressColor; } public void setProgressColor(int progressColor) { this.progressColor = progressColor; } public int getBackgroundColor() { return backgroundColor; } public void setBackgroundColor(int backgroundColor) { this.backgroundColor = backgroundColor; } public float getProgressWidth() { return progressWidth; } public void setProgressWidth(float progressWidth) { this.progressWidth = progressWidth; } public double getProgress() { return progress; } public void setProgress(double progress) { this.progress = progress; this.postInvalidate(); } // Util Method below public static int convertDpToPx(float dp, Context context) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); }}
MainActivity
package com.example.processtextview;import android.os.Bundle;import android.os.Handler;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity { Handler mHandler =new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ProcessTextView processView=(ProcessTextView) findViewById(R.id.myTextView); Button bt=(Button)findViewById(R.id.button1); bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Thread back=new Thread(new Runnable() { @Override public void run() { int i=0; while(i<100){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } processView.setProgress(i++); Log.e("WhatEver", "Process:"+i); } } }); back.start(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }}
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.example.processtextview" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <!--android:padding="4dip" --> <com.example.processtextview.ProcessTextView android:id="@+id/myTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:textSize="20sp" custom:backgroundColor ="@color/whitesmoke" custom:progressColor ="@color/orange" custom:progressWidth ="4dip" /> <Button android:id="@+id/button1" style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/myTextView" android:layout_alignParentBottom="true" android:layout_marginBottom="32dp" android:layout_marginLeft="74dp" android:text="Start" /></RelativeLayout>
后记:
1,如果想做一个可以应用在任意矩形View组件上的进度条,比如Button,ImageView等。则可以换一个思路,再做一个单独的View来绘制进度条和进度条背景。而在构造函数中将需要包围进度条的组件传递进去。虽然操作麻烦点,但是可以很好地适用与各种组件。比如点击按钮后产生进度加载的效果。
2,如果组件的图形上不是一个矩形,而是一个比如带圆角矩形,或者圆形。这个绘制还是继承比较好一点,然后根据它绘制圆角的方式,在外围追加一个进度条。
0 0
- 带进度边框的自定义TextView
- Android自定义控件 -- 带边框的TextView
- 带边框的TextView
- 带边框的TextView
- android开发之自定义带边框的TextView
- android开发之自定义带边框的TextView
- android开发之自定义带边框的TextView
- 带边框的文本框TextView
- 【转】带边框的TextView
- Android UI设计之<四>自定义TextView属性,实现带边框效果的TextView
- New UI-带边框的TextView
- Android: TextView with border 带边框的TextView
- Android: TextView with border 带边框的TextView Border
- 自定义带shape的TextView
- 自定义TextView之 给你的TextView添加边框
- Android自定义带进度的刻度条
- 自定义View(带进度的圆形进度条)
- 自定义一个带边框 透明的Panel
- Git报错insufficient permission for adding an object to repository database .git/objects
- 新浪微博开发二(底部菜单栏的实现)
- POJ 2109 Power of Cryptography
- 美国麻省理工教授亲授科研学习方法(上)
- linux下重启oracle
- 带进度边框的自定义TextView
- C#获取CPU个数
- C语言: 指针强制类型转换
- Swift基础语法: 22 - Swift的函数类型, 嵌套函数
- svn提交异常"svn: 丢失了预定增加的"
- 计算机科学知识和技能评估
- PHP内核探索之变量(6)- 后续内核探索系列大纲备忘
- 数据库索引的作用和优点缺点
- UIView 大小大于8192时drawRect就没效果了,android也有这个问题