当前位置:阳光沙滩 >Android > 查看文章

1.android自己控件-环形的进度条

其实这没什么难度的,是吧!只要小手一抖就出來了!

 

很久没有写东西了,忙哇!况且,写的东西貌似没什么太难的,如果真要写一篇好文章,的确需要时间去准备!

 

好吧,现在就写一个环形进度条吧!

2015-11-17_021814

。。。。。或许称之为环形进度圈圈更好玩,嘻嘻!

2.创建一个环形进度的布局文件

只需要一个ImageView和一个TextView即可,简单是吧!我把代码贴一下!

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv_circle"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_centerInParent="true" />

    <TextView
        android:id="@+id/tv_ratio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="百分比" />

</RelativeLayout>

3.创建一个类,去继承RelativeLayout

然后实现构造方法,还是在代码里详细说明一下吧,嘻嘻!

package com.sunofbeaches.circleprogress;

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.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * @项目名称:CircleProgress
 * @包名:com.sunofbeaches.circleprogress
 * @类名:CircleProgress.java
 * @作者:sunofbeaches.com
 * @创建时间:2015-11-17上午1:37:56
 * @描述:TODO
 * 
 * @svn版本:$Rev$
 * @更新人:$Author$
 * @更新时间:$Date$
 * @更新描述:TODO:
 */

public class CircleProgress extends RelativeLayout {

	private ImageView mIv;
	private TextView mTv;

	private RectF mOval;

	// 控制是否可用
	private boolean mProgressEnable;

	// 进度
	private int mProgress;

	// 最大值
	private int mMax = 0;

	// 画笔
	Paint mPaint = new Paint();

	// 弧线颜色
	private int CIRCLE_LINE_COLOR = Color.parseColor("#ff0000");
	// 弧线大小
	private int CIRCLE_LINE_SIEZ = 1;

	public CircleProgress(Context context) {
		this(context, null);// 确保调用到第二个构造方法
	}

	public CircleProgress(Context context, AttributeSet attrs) {
		super(context, attrs);

		// 挂载界面
		View view = View.inflate(context, R.layout.circle_layout, this);// 这里要注意this哦,挂到同一组

		// 找到对应的控件
		mIv = (ImageView) view.findViewById(R.id.iv_circle);
		mTv = (TextView) view.findViewById(R.id.tv_ratio);

	}

	public void setProgressEnable(boolean enable) {
		this.mProgressEnable = enable;
	}

	public void setProcess(int progress) {
		this.mProgress = progress;
		invalidate();// 不要忘记调用invalidate方法哦!
	}

	public void setMax(int max) {
		this.mMax = max;
	}

	public void setText(String text) {
		mTv.setText(text);
	}

	// 覆写onDraw方法
	@Override
	protected void onDraw(Canvas canvas) {

		if (mProgressEnable) {// 如果可用才进行画

			if (mOval == null) {
				// 画弧线的第一个参数:也就是在一个矩形里的画一个圆

				// 因为把这个圆画在ImageView里头,所以直接获取ImageView的各边位置即可,也就是在其内部画圆

				float left = mIv.getLeft() + CIRCLE_LINE_SIEZ;
				float top = mIv.getTop() + CIRCLE_LINE_SIEZ;
				float right = mIv.getRight() - CIRCLE_LINE_SIEZ;
				float bottom = mIv.getBottom() - CIRCLE_LINE_SIEZ;

				mOval = new RectF(left, top, right, bottom);
			}

			float startAngle = -90;// 开始的角度,这里的角度,水平方向,也就是x轴方向为零度

			// 如果为0则设其为100
			if (mMax == 0) {
				mMax = 100;
			}
			float sweepAngle = mProgress * 360 * 1f / mMax + 0.5f;// 扫过的角度,相信聪明的你一定能理解的哈!
			boolean useCenter = false;// 是否绕中心画,自己体会一下,修改测试一下吧,不好描述(后面我录制一个动画吧),嘻嘻!
			// 画笔一个view只要支就可以了,在前面创建了
			/**
			 * 参数意思:不解释了,直接看写的代码也能看懂的哈!
			 * 
			 * @param oval
			 *            The bounds of oval used to define the shape and size
			 *            of the arc
			 * 
			 * @param startAngle
			 *            Starting angle (in degrees) where the arc begins
			 * @param sweepAngle
			 *            Sweep angle (in degrees) measured clockwise
			 * @param useCenter
			 *            If true, include the center of the oval in the arc,
			 *            and close it if it is being stroked. This will draw a
			 *            wedge
			 * @param paint
			 *            The paint used to draw the arc
			 */

			// 画扇形---->相关设置----->弧线

			// 设置抵抗锯齿
			mPaint.setAntiAlias(true);

			// 设置样式
			mPaint.setStyle(Style.STROKE);

			// 设置大小
			mPaint.setStrokeWidth(CIRCLE_LINE_SIEZ);// 也就是弧线的粗度,前面定义的常量

			// 设置弧线颜色
			mPaint.setColor(CIRCLE_LINE_COLOR);

			canvas.drawArc(mOval, startAngle, sweepAngle, useCenter, mPaint);

		}

		super.onDraw(canvas);
	}
}

 

4.复制上面这个类的全路径类名到主布局文件上

当然,在那个布局文件使用就复制到那里,这里呢,在主布局文件里演示,所以我就复制到那里啦!

 

对了,一定要注意哦,要设置一个背景哦,要不,,呵呵,不会调用onDraw方法,也就是看不到画出來的效果哦,要设置背景!

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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" >

    <com.sunofbeaches.circleprogress.CircleProgress
        android:id="@+id/cp_circle_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#ffffff" />

</RelativeLayout>

 

5. 编写调用的方法啦

废话不多说,直接上代码,后面我录制动画來说明相关的属性哈!

package com.sunofbeaches.circleprogress;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener {

	private CircleProgress mCircleProgress;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 找到circleProgress
		mCircleProgress = (CircleProgress) this
				.findViewById(R.id.cp_circle_progress);

		// 设置点击监听
		mCircleProgress.setOnClickListener(this);

	}

	@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;
	}

	@Override
	public void onClick(View v) {

		if (v == mCircleProgress) {
			mCircleProgressClick();
		}

	}

	private void mCircleProgressClick() {
		new AsyncTask<Void, Integer, Void>() {

			@Override
			protected Void doInBackground(Void... params) {

				// 模拟一下
				for (int i = 0; i <= 100; i++) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					publishProgress(i);
				}

				return null;
			}

			@Override
			protected void onPreExecute() {
				// 事先准备,设置可用
				mCircleProgress.setProgressEnable(true);
			}

			@Override
			protected void onProgressUpdate(Integer... values) {
				// 更新UI
				mCircleProgress.setProcess(values[0]);

				// 设置百分比
				mCircleProgress.setText(values[0] + "%");

			}

		}.execute();// 执行

	}

}

 

解析:关于boolean useCenter = true/false;

这两个有什么不同呢,看一个效果就知道啦!看官准备啦,下面:

属性值为:true的时候

true

属性值为:false的时候

false

 

好啦,已经凌晨两点半了,我想我要睡一会儿了,嘻嘻!亲爱的小伙伴们,晚安哦!

7K
为您推荐
各种观点