Android(安卓)自定义View——自定义ProgressBar
Android中给我们提供了多个样式的ProgressBar,SeekBar,RatingBaar等进度条,但是我们这些样式都满足不了我们的要求,这时我们就可以使用自定义View来定义我们自己想要的形式的进度条。
这里讲解三种样式的进度条,由于博主还米有学习过动画,所以这里不添加动画效果。想要学习自定义控件的可以先参考这篇文章>《Android 自定义View——自定义View控件 》。
形式一
效果:
控件的定义
1. 定义一个MyProgressCircle的类继承View类。
2. 定义一个MyProgressCircle(Context context, AttributeSet attrs)的构造器。
3. 重写其onMesure和onDraw方法。
4. 在onDraw方法中绘制进度条。
以上是自定义控件的基本步骤,我们先看代码,然后逐步讲解:
public class MyProgressCircle extends View { private int width;//设置高 private int height;//设置高 //设置画笔 private Paint mPaintBackground; private Paint mPaintCurrent; private Paint mPaintText; //设置进度 private int maxProgress=100; private int currentProgress=0; public int getMaxProgress() { return maxProgress; } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } public int getCurrentProgress() { return currentProgress; } public void setCurrentProgress(int currentProgress) { this.currentProgress = currentProgress; invalidate();//实时更新进度 } public MyProgressCircle(Context context, AttributeSet attrs) { super(context, attrs); //绘制未下载时背景圆的画笔 mPaintBackground = new Paint(); mPaintBackground.setAntiAlias(true); mPaintBackground.setColor(Color.LTGRAY); //绘制下载时显示进度圆的画笔 mPaintCurrent = new Paint(); mPaintCurrent.setAntiAlias(true); mPaintCurrent.setColor(Color.GRAY); //绘制显示下载进度文字的画笔 mPaintText = new Paint(); mPaintText.setAntiAlias(true); mPaintText.setColor(Color.BLACK); mPaintText.setTextAlign(Paint.Align.CENTER); mPaintText.setTextSize(100); } public MyProgressCircle(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height);//设置宽和高 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(width / 2, height / 2, 300, mPaintBackground); canvas.drawCircle(width/2, height/2, currentProgress*300f/maxProgress, mPaintCurrent); canvas.drawText(currentProgress*100f/maxProgress+"%", width/2, height/2, mPaintText); }}
这里就只是绘制了两个圆形,但是这两个圆形是有联系的。背景圆代表的进度的最大值,当前圆是代表的是当前的进度。当当前进度改变时,当前圆也是要变化的,我们从刚才的效果中可以看到当前圆变化的是半径,所以我们在绘制时,将其半径设置为:currentProgress*300f/maxProgress。这个应该是比较好理解的。
控件的使用
然后我们在Activity中使用一下,模拟下载。
1. 在布局中定义添加控件。
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始进度"/> <com.example.administrator.mywidgetdemo.widget.MyProgressCircle android:id="@+id/myprogress" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>
- 在Activity使用通过点击按钮开始下载。
public class MainActivity extends Activity { private MyProgressCircle myProgressCircle; private Button mButtonStart; private static final int PROGRESS_ONE = 0X0001; //定义一个进度 private int progress; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case PROGRESS_ONE: progress++; if(progress<=100){ myProgressCircle.setCurrentProgress(progress); sendEmptyMessageDelayed(PROGRESS_ONE, 100); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonStart = (Button) findViewById(R.id.button_start); //获取控件的对象 myProgressCircle = (MyProgressCircle) findViewById(R.id.myprogress); mButtonStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessageDelayed(PROGRESS_ONE, 1000); } }); }}
形式二
效果:
控件的定义
1. 定义一个MyProgressCircle的类继承View类。
2. 定义一个MyProgressCircle(Context context, AttributeSet attrs)的构造器。
3. 重写其onMesure和onDraw方法。
4. 在onDraw方法中绘制进度条。
以上是自定义控件的基本步骤,我们先看代码,然后逐步讲解:
public class MyProgressArc extends View { private int width;//设置高 private int height;//设置高 //设置画笔 private Paint mPaintBackground; private Paint mPaintCurrent; private Paint mPaintText; //设置进度 private int maxProgress=100; private int currentProgress=0; public int getMaxProgress() { return maxProgress; } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } public int getCurrentProgress() { return currentProgress; } public void setCurrentProgress(int currentProgress) { this.currentProgress = currentProgress; invalidate();//实时更新进度 } public MyProgressArc(Context context) { super(context); } public MyProgressArc(Context context, AttributeSet attrs) { super(context, attrs); mPaintBackground = new Paint(); mPaintBackground.setAntiAlias(true); mPaintBackground.setStyle(Paint.Style.STROKE); mPaintBackground.setColor(Color.LTGRAY); mPaintBackground.setStrokeWidth(60); mPaintCurrent = new Paint(); mPaintCurrent.setAntiAlias(true); mPaintCurrent.setStyle(Paint.Style.STROKE); mPaintCurrent.setColor(Color.GRAY); mPaintCurrent.setStrokeWidth(60); mPaintText = new Paint(); mPaintText.setAntiAlias(true); mPaintText.setColor(Color.BLACK); mPaintText.setTextAlign(Paint.Align.CENTER); mPaintText.setTextSize(100); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height);//设置宽和高 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); RectF rect = new RectF(width/2-300, height/2-300, width/2+300, height/2+300); canvas.drawArc(rect,currentProgress*360f/maxProgress,360f-currentProgress*360f/maxProgress, false, mPaintBackground); canvas.drawArc(rect, 0,currentProgress*360f/maxProgress, false, mPaintCurrent); canvas.drawText(currentProgress*100f/maxProgress+"%", width/2, height/2, mPaintText); }}
这里就只是绘制了两个椭圆,但是这两个椭圆是有联系的。背景椭圆代表的进度的最大值,当前椭圆是代表的是当前的进度。当当前进度改变时,当前椭圆也是要变化的,我们从刚才的效果中可以看到椭圆变化的是旋转的角度。背景椭圆的角度在不断的减小,减小的数量是currentProgress*360f/maxProgress,基数是360度,当前椭圆角度在不断增大,增大的角度是currentProgress*360f/maxProgress,基数是0度。
控件的使用
然后我们在Activity中使用一下,模拟下载。
1. 在布局中定义添加控件。
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始进度"/> <com.example.administrator.mywidgetdemo.widget.MyProgressArc android:id="@+id/myprogress" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>
- 在Activity使用通过点击按钮开始下载。
public class MainActivity extends Activity { private MyProgressArc myProgressArc; private Button mButtonStart; private static final int PROGRESS_TWO = 0X0002; //定义一个进度 private int progress; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case PROGRESS_TWO: progress++; if(progress<=100){ myProgressArc.setCurrentProgress(progress); sendEmptyMessageDelayed(PROGRESS_TWO, 100); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonStart = (Button) findViewById(R.id.button_start); myProgressArc = (MyProgressArc) findViewById(R.id.myprogress); mButtonStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessageDelayed(PROGRESS_TWO, 1000); } }); }}
形式三
效果:
控件的定义
1. 定义一个MyProgressCircle的类继承View类。
2. 定义一个MyProgressCircle(Context context, AttributeSet attrs)的构造器。
3. 重写其onMesure和onDraw方法。
4. 在onDraw方法中绘制进度条。
以上是自定义控件的基本步骤,我们先看代码,然后逐步讲解:
public class MyProgressRect extends View { private int width;//设置高 private int height;//设置高 //设置画笔 private Paint mPaintBackground; private Paint mPaintCurrent; private Paint mPaintText; //设置进度 private int maxProgress = 100; private int currentProgress = 0; private float currentProgressHeight; public int getMaxProgress() { return maxProgress; } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } public int getCurrentProgress() { return currentProgress; } public void setCurrentProgress(int currentProgress) { this.currentProgress = currentProgress; invalidate();//实时更新进度 } public MyProgressRect(Context context) { super(context); } public MyProgressRect(Context context, AttributeSet attrs) { super(context, attrs); mPaintBackground = new Paint(); mPaintBackground.setAntiAlias(true); mPaintBackground.setStyle(Paint.Style.FILL); mPaintBackground.setColor(Color.LTGRAY); mPaintBackground.setStrokeWidth(60); mPaintCurrent = new Paint(); mPaintCurrent.setAntiAlias(true); mPaintCurrent.setStyle(Paint.Style.FILL); mPaintCurrent.setColor(Color.GRAY); mPaintCurrent.setStrokeWidth(60); mPaintText = new Paint(); mPaintText.setAntiAlias(true); mPaintText.setColor(Color.BLACK); mPaintText.setTextAlign(Paint.Align.CENTER); mPaintText.setTextSize(100); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height);//设置宽和高 } @Override protected void onDraw(Canvas canvas) { //定义水柱的高度。 currentProgressHeight = currentProgress*600f/ maxProgress; super.onDraw(canvas); canvas.drawRect(width / 2 - 300, height / 2 - 300, width / 2 + 300,(height / 2 + 300) - (currentProgressHeight), mPaintBackground); canvas.drawRect(width / 2 - 300, (height / 2 + 300) - (currentProgressHeight), width / 2 + 300, height / 2 + 300, mPaintCurrent); canvas.drawText(currentProgress * 100f / maxProgress + "%", width / 2, height / 2, mPaintText); }}
这里就只是绘制了两个矩形,但是这两个矩形是有联系的。背景矩形代表的进度的最大值,当前矩形是代表的是当前的进度。当当前进度改变时,当前矩形和背景矩形也要变化的,我们从刚才的效果中可以看到变化的是高度。背景矩形的高度在不断的减小,当前矩形的高度在不断地增大,变化数都是currentProgressHeight,值为currentProgress*600f/ maxProgress。
控件的使用
然后我们在Activity中使用一下,模拟下载。
1. 在布局中定义添加控件。
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始进度"/> <com.example.administrator.mywidgetdemo.widget.MyProgressRect android:id="@+id/myprogress" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>
- 在Activity使用通过点击按钮开始下载。
public class MainActivity extends Activity { private MyProgressRect myProgressRect; private Button mButtonStart; private static final int PROGRESS_RECT = 0X0003; //定义一个进度 private int progress; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case PROGRESS_RECT: progress++; if (progress <= 100) { myProgressRect.setCurrentProgress(progress); sendEmptyMessageDelayed(PROGRESS_RECT, 100); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonStart = (Button) findViewById(R.id.button_start); myProgressRect = (MyProgressRect) findViewById(R.id.myprogress); mButtonStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessageDelayed(PROGRESS_RECT, 1000); } }); }}
更多相关文章
- Android中设置半个屏幕大小且居中的按钮布局 (layout_weight属性
- android开发老罗教学视频
- android的动画相关参数说明
- Android(安卓)踩坑——FloatingActionButton自动添加边距
- Android开发艺术探索笔记 第四章 View的工作原理
- Android四大控件之Activity详解:实践篇
- Android(安卓)中自定义View的应用.
- Android圆形进度条控件-CircleSeekBar
- Android控件系列之ProgressBar&在Android中利用Handler处理多线