android 仿摩拜单车共享单车进度条实现StepView
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6552712.html
先看效果图:
Step1:定义StepBean
定义五个状态,分别为:为完成、正在进行、已完成、终点完成、终点未完成。
public class StepBean{
public static final int STEP_UNDO = -1;//未完成
public static final int STEP_CURRENT = 0;//正在进行
public static final int STEP_COMPLETED = 1;//已完成
public static final int STEP_LAST_COMPLETED = 2;//终点完成
public static final int STEP_LAST_UNCOMPLETED = 3;//终点未完成
private String name;
private int state; public String getName(){
return name;
} public void setName(String name){
this.name = name;
} public int getState(){
return state;
} public void setState(int state){
this.state = state;
} public StepBean(){
} public StepBean(String name, int state){
this.name = name;
this.state = state;
}
}
Step2:自定义HorizontalStepsViewIndicator
public class HorizontalStepsViewIndicator extends View {
private int defaultStepIndicatorNum = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());//定义默认的高度
private float mCompletedLineHeight;//完成线的高度
private float mCircleRadius;//圆的半径 private Drawable mCompleteIcon;//完成的默认图片
private Drawable mAttentionIcon;//正在进行的默认图片
private Drawable mDefaultIcon;//默认的背景图
private Drawable mLastCompleteIcon;//终点未完成图片
private Drawable mLastUnCompleteIcon;//终点完成图片 private float mCenterY;//该view的Y轴中间位置
private float mLeftY;//左上方的Y位置
private float mRightY;//右下方的位置 private List<StepBean> mStepBeanList ;//当前有几步流程
private int mStepNum = 0;
private float mLinePadding;//两条连线之间的间距 private List<Float> mCircleCenterPointPositionList;//定义所有圆的圆心点位置的集合
private Paint mUnCompletedPaint;//未完成Paint
private Paint mCompletedPaint;//完成paint
private int mUnCompletedLineColor = ContextCompat.getColor(getContext(), R.color.uncompleted_color);//定义默认未完成线的颜色
private int mCompletedLineColor = ContextCompat.getColor(getContext(), R.color.completed_color);//定义默认完成线的颜色
private PathEffect mEffects;
private int mComplectingPosition;//正在进行position private Path mPath;
private OnDrawIndicatorListener mOnDrawListener;
private int screenWidth; /**
* 设置监听
* @param onDrawListener
*/
public void setOnDrawListener(OnDrawIndicatorListener onDrawListener){
mOnDrawListener = onDrawListener;
} /**
* get圆的半径 get circle radius
* @return
*/
public float getCircleRadius(){
return mCircleRadius;
} public HorizontalStepsViewIndicator(Context context){
this(context, null);
} public HorizontalStepsViewIndicator(Context context, AttributeSet attrs){
this(context, attrs, 0);
} public HorizontalStepsViewIndicator(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
init();
} private void init(){
mStepBeanList = new ArrayList<>();
mPath = new Path();
mEffects = new DashPathEffect(new float[]{8, 8, 8, 8}, 1);
mCircleCenterPointPositionList = new ArrayList<>();//初始化 mUnCompletedPaint = new Paint();
mCompletedPaint = new Paint();
mUnCompletedPaint.setAntiAlias(true);
mUnCompletedPaint.setColor(mUnCompletedLineColor);
mUnCompletedPaint.setStyle(Paint.Style.STROKE);
mUnCompletedPaint.setStrokeWidth(2);
mCompletedPaint.setAntiAlias(true);
mCompletedPaint.setColor(mCompletedLineColor);
mCompletedPaint.setStyle(Paint.Style.STROKE);
mCompletedPaint.setStrokeWidth(2);
mUnCompletedPaint.setPathEffect(mEffects);
mCompletedPaint.setStyle(Paint.Style.FILL); mCompletedLineHeight = 0.03f * defaultStepIndicatorNum;//已经完成线的宽高
mCircleRadius = 0.28f * defaultStepIndicatorNum;//圆的半径
mLinePadding = 1.0f * defaultStepIndicatorNum;//线与线之间的间距 mCompleteIcon = ContextCompat.getDrawable(getContext(), R.drawable.complted);//已经完成的icon
mAttentionIcon = ContextCompat.getDrawable(getContext(), R.drawable.attention);//正在进行的icon
mDefaultIcon = ContextCompat.getDrawable(getContext(), R.drawable.default_icon);//未完成的icon
mLastCompleteIcon= ContextCompat.getDrawable(getContext(), R.drawable.last_complted);//终点已完成的icon
mLastUnCompleteIcon= ContextCompat.getDrawable(getContext(), R.drawable.last_uncomplted);//终点未完成的icon
} @Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int width = defaultStepIndicatorNum * 2;
if(MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(widthMeasureSpec)){
screenWidth = MeasureSpec.getSize(widthMeasureSpec);
}
int height = defaultStepIndicatorNum;
if(MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(heightMeasureSpec)){
height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
}
width = (int) (mStepNum * mCircleRadius * 2 - (mStepNum - 1) * mLinePadding);
setMeasuredDimension(width, height);
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
super.onSizeChanged(w, h, oldw, oldh);
//获取中间的高度,目的是为了让该view绘制的线和圆在该view垂直居中
mCenterY = 0.5f * getHeight();
//获取左上方Y的位置,获取该点的意义是为了方便画矩形左上的Y位置
mLeftY = mCenterY - (mCompletedLineHeight / 2);
//获取右下方Y的位置,获取该点的意义是为了方便画矩形右下的Y位置
mRightY = mCenterY + mCompletedLineHeight / 2; mCircleCenterPointPositionList.clear();
for(int i = 0; i < mStepNum; i++){
//先计算全部最左边的padding值(getWidth()-(圆形直径+两圆之间距离)*2)
float paddingLeft = (screenWidth - mStepNum * mCircleRadius * 2 - (mStepNum - 1) * mLinePadding) / 2;
//add to list
mCircleCenterPointPositionList.add(paddingLeft + mCircleRadius + i * mCircleRadius * 2 + i * mLinePadding);
} /**
* set listener
*/
if(mOnDrawListener!=null){
mOnDrawListener.ondrawIndicator();
}
} @Override
protected synchronized void onDraw(Canvas canvas){
super.onDraw(canvas);
if(mOnDrawListener!=null){
mOnDrawListener.ondrawIndicator();
}
mUnCompletedPaint.setColor(mUnCompletedLineColor);
mCompletedPaint.setColor(mCompletedLineColor);
//-----------------------画线-------draw line-----------------------------------------------
for(int i = 0; i < mCircleCenterPointPositionList.size() -1; i++){
//前一个ComplectedXPosition
final float preComplectedXPosition = mCircleCenterPointPositionList.get(i);
//后一个ComplectedXPosition
final float afterComplectedXPosition = mCircleCenterPointPositionList.get(i + 1);
if(i <= mComplectingPosition&&mStepBeanList.get(0).getState()!=StepBean.STEP_UNDO){//判断在完成之前的所有点
//判断在完成之前的所有点,画完成的线,这里是矩形,很细的矩形,类似线,为了做区分,好看些
canvas.drawRect(preComplectedXPosition + mCircleRadius - 10, mLeftY, afterComplectedXPosition - mCircleRadius + 10, mRightY, mCompletedPaint);
} else{
mPath.moveTo(preComplectedXPosition + mCircleRadius, mCenterY);
mPath.lineTo(afterComplectedXPosition - mCircleRadius, mCenterY);
canvas.drawPath(mPath, mUnCompletedPaint);
}
}
//-----------------------画线-------draw line----------------------------------------------- //-----------------------画图标-----draw icon-----------------------------------------------
for(int i = 0; i < mCircleCenterPointPositionList.size(); i++){
final float currentComplectedXPosition = mCircleCenterPointPositionList.get(i);
Rect rect = new Rect((int) (currentComplectedXPosition - mCircleRadius), (int) (mCenterY - mCircleRadius), (int) (currentComplectedXPosition + mCircleRadius), (int) (mCenterY + mCircleRadius));
StepBean stepsBean = mStepBeanList.get(i);
if(stepsBean.getState()==StepBean.STEP_UNDO){
mDefaultIcon.setBounds(rect);
mDefaultIcon.draw(canvas);
}else if(stepsBean.getState()==StepBean.STEP_CURRENT){
mCompletedPaint.setColor(Color.WHITE);
canvas.drawCircle(currentComplectedXPosition, mCenterY, mCircleRadius * 1.1f, mCompletedPaint);
mAttentionIcon.setBounds(rect);
mAttentionIcon.draw(canvas);
}else if(stepsBean.getState()==StepBean.STEP_COMPLETED){
mCompleteIcon.setBounds(rect);
mCompleteIcon.draw(canvas);
}else if(stepsBean.getState()==StepBean.STEP_LAST_COMPLETED){
mLastCompleteIcon.setBounds(rect);
mLastCompleteIcon.draw(canvas);
}else if(stepsBean.getState()==StepBean.STEP_LAST_UNCOMPLETED){
mLastUnCompleteIcon.setBounds(rect);
mLastUnCompleteIcon.draw(canvas);
}
}
//-----------------------画图标-----draw icon-----------------------------------------------
} /**
* 得到所有圆点所在的位置
* @return
*/
public List<Float> getCircleCenterPointPositionList()
{
return mCircleCenterPointPositionList;
} /**
* 设置流程步数
* @param stepsBeanList 流程步数
*/
public void setStepNum(List<StepBean> stepsBeanList) {
this.mStepBeanList = stepsBeanList;
mStepNum = mStepBeanList.size(); if(mStepBeanList!=null&&mStepBeanList.size()>0){
for(int i = 0;i<mStepNum;i++){
StepBean stepsBean = mStepBeanList.get(i);
if(stepsBean.getState()==StepBean.STEP_COMPLETED){
mComplectingPosition = i;
}
}
}
requestLayout();
} /**
* 设置未完成线的颜色
* @param unCompletedLineColor
*/
public void setUnCompletedLineColor(int unCompletedLineColor){
this.mUnCompletedLineColor = unCompletedLineColor;
} /**
* 设置已完成线的颜色
* @param completedLineColor
*/
public void setCompletedLineColor(int completedLineColor){
this.mCompletedLineColor = completedLineColor;
} /**
* 设置默认图片
* @param defaultIcon
*/
public void setDefaultIcon(Drawable defaultIcon){
this.mDefaultIcon = defaultIcon;
} /**
* 设置已完成图片
* @param completeIcon
*/
public void setCompleteIcon(Drawable completeIcon){
this.mCompleteIcon = completeIcon;
} public void setLastCompleteIcon(Drawable lastcompleteIcon){
this.mLastCompleteIcon = lastcompleteIcon;
} public void setLastUnCompleteIcon(Drawable lastUnCompleteIcon){
this.mLastUnCompleteIcon = lastUnCompleteIcon;
} /**
* 设置正在进行中的图片
* @param attentionIcon
*/
public void setAttentionIcon(Drawable attentionIcon){
this.mAttentionIcon = attentionIcon;
} /**
* 设置对view监听
*/
public interface OnDrawIndicatorListener{
void ondrawIndicator();
}
}
Step3:自定义HorizontalStepView
public class HorizontalStepView extends LinearLayout implements HorizontalStepsViewIndicator.OnDrawIndicatorListener{
private RelativeLayout mTextContainer;
private HorizontalStepsViewIndicator mStepsViewIndicator;
private List<StepBean> mStepBeanList;
private int mComplectingPosition;
private int mUnComplectedTextColor = ContextCompat.getColor(getContext(), R.color.uncompleted_text_color);//定义默认未完成文字的颜色;
private int mComplectedTextColor = ContextCompat.getColor(getContext(), R.color.completed_color);//定义默认完成文字的颜色;
private int mTextSize = 14;//default textSize
private TextView mTextView; public HorizontalStepView(Context context){
this(context, null);
} public HorizontalStepView(Context context, AttributeSet attrs){
this(context, attrs, 0);
} public HorizontalStepView(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
init();
} private void init(){
View rootView = LayoutInflater.from(getContext()).inflate(R.layout.widget_horizontal_stepsview, this);
mStepsViewIndicator = (HorizontalStepsViewIndicator) rootView.findViewById(R.id.steps_indicator);
mStepsViewIndicator.setOnDrawListener(this);
mTextContainer = (RelativeLayout) rootView.findViewById(R.id.rl_text_container);
} /**
* 设置显示的文字
* @param stepsBeanList
* @return
*/
public HorizontalStepView setStepViewTexts(List<StepBean> stepsBeanList) {
mStepBeanList = stepsBeanList;
mStepsViewIndicator.setStepNum(mStepBeanList);
return this;
} /**
* 设置未完成文字的颜色
* @param unComplectedTextColor
* @return
*/
public HorizontalStepView setStepViewUnComplectedTextColor(int unComplectedTextColor) {
mUnComplectedTextColor = unComplectedTextColor;
return this;
} /**
* 设置完成文字的颜色
* @param complectedTextColor
* @return
*/
public HorizontalStepView setStepViewComplectedTextColor(int complectedTextColor) {
this.mComplectedTextColor = complectedTextColor;
return this;
} /**
* 设置StepsViewIndicator未完成线的颜色
* @param unCompletedLineColor
* @return
*/
public HorizontalStepView setStepsViewIndicatorUnCompletedLineColor(int unCompletedLineColor) {
mStepsViewIndicator.setUnCompletedLineColor(unCompletedLineColor);
return this;
} /**
* 设置StepsViewIndicator完成线的颜色
* @param completedLineColor
* @return
*/
public HorizontalStepView setStepsViewIndicatorCompletedLineColor(int completedLineColor) {
mStepsViewIndicator.setCompletedLineColor(completedLineColor);
return this;
} /**
* 设置StepsViewIndicator默认图片
* @param defaultIcon
*/
public HorizontalStepView setStepsViewIndicatorDefaultIcon(Drawable defaultIcon) {
mStepsViewIndicator.setDefaultIcon(defaultIcon);
return this;
} /**
* 设置StepsViewIndicator已完成图片
* @param completeIcon
*/
public HorizontalStepView setStepsViewIndicatorCompleteIcon(Drawable completeIcon) {
mStepsViewIndicator.setCompleteIcon(completeIcon);
return this;
} /**
* 设置StepsViewIndicator正在进行中的图片
* @param attentionIcon
*/
public HorizontalStepView setStepsViewIndicatorAttentionIcon(Drawable attentionIcon) {
mStepsViewIndicator.setAttentionIcon(attentionIcon);
return this;
} public HorizontalStepView setStepsViewIndicatorLastCompleteIcon(Drawable lastCompleteIcon) {
mStepsViewIndicator.setLastCompleteIcon(lastCompleteIcon);
return this;
} public HorizontalStepView setStepsViewIndicatorLastUnCompleteIcon(Drawable lastUnCompleteIcon) {
mStepsViewIndicator.setLastUnCompleteIcon(lastUnCompleteIcon);
return this;
} /**
* set textSize
* @param textSize
* @return
*/
public HorizontalStepView setTextSize(int textSize) {
if(textSize > 0) {
mTextSize = textSize;
}
return this;
} @Override
public void ondrawIndicator() {
if(mTextContainer != null) {
mTextContainer.removeAllViews();
List<Float> complectedXPosition = mStepsViewIndicator.getCircleCenterPointPositionList();
if(mStepBeanList != null && complectedXPosition != null && complectedXPosition.size() > 0) {
for(int i = 0; i < mStepBeanList.size(); i++) {
mTextView = new TextView(getContext());
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSize);
mTextView.setText(mStepBeanList.get(i).getName());
int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mTextView.measure(spec, spec);
// getMeasuredWidth
int measuredWidth = mTextView.getMeasuredWidth();
mTextView.setX(complectedXPosition.get(i) - measuredWidth / 2);
mTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); if(i <= mComplectingPosition) {
mTextView.setTypeface(null);
mTextView.setTextColor(mComplectedTextColor);
} else{
mTextView.setTextColor(mUnComplectedTextColor);
}
mTextContainer.addView(mTextView);
}
}
}
}
}
Step4:如何使用?
在布局文件xml中:
<cn.comnav.utrain.ui.widget.HorizontalStepView
android:id="@+id/hsv_step_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="@+id/ll_role"
android:layout_marginBottom="40dp"
/>
在Activity中的使用,部分代码截取:
private List<StepBean> stepsBeanList;
private HorizontalStepView mHorizontalStepView;
mHorizontalStepView=(HorizontalStepView)findViewById(R.id.hsv_step_view); stepsBeanList = new ArrayList<>();
StepBean stepBean0=null;
StepBean stepBean1=null;
StepBean stepBean2=null;
StepBean stepBean3=null;
switch (stepIndex){
case 1:
stepBean0 = new StepBean("手机绑定",1);
stepBean1 = new StepBean("实名认证",0);
stepBean2 = new StepBean("学时充值",-1);
stepBean3 = new StepBean("开始用车",3);
break;
case 2:
stepBean0 = new StepBean("手机绑定",1);
stepBean1 = new StepBean("实名认证",1);
stepBean2 = new StepBean("学时充值",0);
stepBean3 = new StepBean("开始用车",3);
break;
case 3:
stepBean0 = new StepBean("手机绑定",1);
stepBean1 = new StepBean("实名认证",1);
stepBean2 = new StepBean("学时充值",1);
stepBean3 = new StepBean("开始用车",2);
break;
}
stepsBeanList.add(stepBean0);
stepsBeanList.add(stepBean1);
stepsBeanList.add(stepBean2);
stepsBeanList.add(stepBean3);
mHorizontalStepView.setStepViewTexts(stepsBeanList);
如果此文对您有帮助,微信打赏我一下吧~
android 仿摩拜单车共享单车进度条实现StepView的更多相关文章
- 我的Android进阶之旅------>Android自定义View实现带数字的进度条(NumberProgressBar)
今天在Github上面看到一个来自于 daimajia所写的关于Android自定义View实现带数字的进度条(NumberProgressBar)的精彩案例,在这里分享给大家一起来学习学习!同时感谢 ...
- Android 高手进阶,自己定义圆形进度条
背景介绍 在Android 开发中,我们常常遇到各种各样绚丽的控件,所以,依靠我们Android本身所带的控件是远远不够的,许多时候须要我们自定义控件,在开发的过程中.我们公司遇到了一种须要自己写的一 ...
- Android自定义控件系列之应用篇——圆形进度条
一.概述 在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇.链接:http://www.cnblogs.com/jerehedu/p/4360066.html 这一篇博文中,我们将 ...
- 让android系统中任意一个view变成进度条
1.效果 2.进度条背景drawable文件 结束后可以恢复原背景. <?xml version="1.0" encoding="utf-8"?> ...
- Android中的常用控件之进度条(ProgressBar)
ProgressBar的常用属性:style,进度条的样式,默认为圆形,用style="?android:attr/progressBarStyleHorizontal"可以将进度 ...
- 仿UC浏览器图片加载进度条
前几天用UC浏览器看新闻(无意中给UC打了广告),看到它的图片加载进度条,正好最近有时间,所以就自己写了一个. 效果图如下 进度条的底色和填充颜色都可以调整. 首先中间的笑脸作为一个整体,其实现代码如 ...
- Android 三种方式实现自定义圆形进度条ProgressBar
一.通过动画实现 定义res/anim/loading.xml如下: <?xml version="1.0" encoding="UTF-8"?> ...
- Android UI系列-----时间、日期、Toasts和进度条Dialog
您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...
- Android 自学之进度条ProgressBar
进度条(ProgressBar)也是UI界面中的一种非常使用的组件,通常用于向用户显示某个耗时完成的百分比.因此进度条可以动态的显示进度,因此避免长时间地执行某个耗时操作时,让用户感觉程序失去了响应, ...
随机推荐
- Runtime of Objective-C
[0] Outline -- [1] 版本和平台 -- [2] 与Runtime System交互 -- [3] 方法的动态决议 -- [4] 消息转发 -- [5] 类型编码 -- [6 ...
- Servlet生命周期方法,request.getRequestDispatcher
1,request.getRequestDispatcher 方法全称javax.servlet.ServletRequest.getRequestDispatcher(String) 2,在web. ...
- SpringMvc项目中使用GoogleKaptcha 生成验证码
前言:google captcha 是google生成验证码的一个工具类,其原理是将随机生成字符串保存到session中,同时以图片的形式返回给页面,之后前台页面提交到后台进行对比. 1.jar包准备 ...
- 【Scala】Scala之Control Structures
一.前言 前面学习了Scala的Numbers,接着学习Scala的Control Structures(控制结构). 二.Control Structures Scala中的控制结构与Java中的颇 ...
- Vmware虚拟机安装Ubuntu 16.04 LTS(长期支持)版本+VMware tools安装
今天用VMware虚拟机安装了Ubuntu 16.04,过程用点繁琐,顺便又安装了VMware tools,这样就可以全屏显示Ubuntu系统了,下面是具体的安装过程! 第一步:准备工作 1.下载Ub ...
- [工作总结] QA小鸟一年了
夏至又至,在北京360的一年过去了.作为一名QA,我时常感到迷惑,如何靠大部分的手工测试+少部分的自动化测试来保证产品功能的质量.对于开发完成后,给到我手上的文件和功能说明,我很少有信心说能够通过自己 ...
- C++编程练习(12)----“有向图的拓扑排序“
设G={V,E}是一个具有 n 个顶点的有向图,V中的顶点序列 v1,v2,......,vn,满足若从顶点 vi 到 vj 有一条路径,则在顶点序列中顶点 vi 必在顶点 vj 之前.则称这样的顶点 ...
- java 多线程安全问题-同步代码块
/* 多线程的安全问题: while(true) { if(tick>0) { //线程0,1,2,3在余票为1时,都停滞在这里,之后分别获得CPU执行权,打印出0,-1,-2等错票 Syste ...
- MATLAB 单变量函数一阶及N阶求导
1 对一维函数的求导及求特定函数处的变量值 %%最简单的一阶单变量函数进行求导 function usemyfunArray() %主函数必须位于最上方 clc clear syms x %syms ...
- testNG实现test失败后重复执行,
test失败自动执行大大提高测试结果的准确性, 1.修改testNG源码实现test失败自动执行, 首先获取testng的源码, 获取源代码,构建过程: $ git clone git://githu ...