Android 仿摩拜單車(chē)共享單車(chē)進(jìn)度條實(shí)現(xiàn)StepView效果
先看效果圖:
Step1:定義StepBean
定義五個(gè)狀態(tài),分別為:為完成、正在進(jìn)行、已完成、終點(diǎn)完成、終點(diǎn)未完成。
public class StepBean{ public static final int STEP_UNDO = -1;//未完成 public static final int STEP_CURRENT = 0;//正在進(jìn)行 public static final int STEP_COMPLETED = 1;//已完成 public static final int STEP_LAST_COMPLETED = 2;//終點(diǎn)完成 public static final int STEP_LAST_UNCOMPLETED = 3;//終點(diǎn)未完成 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());//定義默認(rèn)的高度 private float mCompletedLineHeight;//完成線的高度 private float mCircleRadius;//圓的半徑 private Drawable mCompleteIcon;//完成的默認(rèn)圖片 private Drawable mAttentionIcon;//正在進(jìn)行的默認(rèn)圖片 private Drawable mDefaultIcon;//默認(rèn)的背景圖 private Drawable mLastCompleteIcon;//終點(diǎn)未完成圖片 private Drawable mLastUnCompleteIcon;//終點(diǎn)完成圖片 private float mCenterY;//該view的Y軸中間位置 private float mLeftY;//左上方的Y位置 private float mRightY;//右下方的位置 private List<StepBean> mStepBeanList ;//當(dāng)前有幾步流程 private int mStepNum = 0; private float mLinePadding;//兩條連線之間的間距 private List<Float> mCircleCenterPointPositionList;//定義所有圓的圓心點(diǎn)位置的集合 private Paint mUnCompletedPaint;//未完成Paint private Paint mCompletedPaint;//完成paint private int mUnCompletedLineColor = ContextCompat.getColor(getContext(), R.color.uncompleted_color);//定義默認(rèn)未完成線的顏色 private int mCompletedLineColor = ContextCompat.getColor(getContext(), R.color.completed_color);//定義默認(rèn)完成線的顏色 private PathEffect mEffects; private int mComplectingPosition;//正在進(jìn)行position private Path mPath; private OnDrawIndicatorListener mOnDrawListener; private int screenWidth; /** * 設(shè)置監(jiān)聽(tīng) * @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;//已經(jīng)完成線的寬高 mCircleRadius = 0.28f * defaultStepIndicatorNum;//圓的半徑 mLinePadding = 1.0f * defaultStepIndicatorNum;//線與線之間的間距 mCompleteIcon = ContextCompat.getDrawable(getContext(), R.drawable.complted);//已經(jīng)完成的icon mAttentionIcon = ContextCompat.getDrawable(getContext(), R.drawable.attention);//正在進(jìn)行的icon mDefaultIcon = ContextCompat.getDrawable(getContext(), R.drawable.default_icon);//未完成的icon mLastCompleteIcon= ContextCompat.getDrawable(getContext(), R.drawable.last_complted);//終點(diǎn)已完成的icon mLastUnCompleteIcon= ContextCompat.getDrawable(getContext(), R.drawable.last_uncomplted);//終點(diǎn)未完成的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(jié)的位置,獲取該點(diǎn)的意義是為了方便畫(huà)矩形左上的Y位置 mLeftY = mCenterY - (mCompletedLineHeight / 2); //獲取右下方Y(jié)的位置,獲取該點(diǎn)的意義是為了方便畫(huà)矩形右下的Y位置 mRightY = mCenterY + mCompletedLineHeight / 2; mCircleCenterPointPositionList.clear(); for(int i = 0; i < mStepNum; i++){ //先計(jì)算全部最左邊的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); //-----------------------畫(huà)線-------draw line----------------------------------------------- for(int i = 0; i < mCircleCenterPointPositionList.size() -1; i++){ //前一個(gè)ComplectedXPosition final float preComplectedXPosition = mCircleCenterPointPositionList.get(i); //后一個(gè)ComplectedXPosition final float afterComplectedXPosition = mCircleCenterPointPositionList.get(i + 1); if(i <= mComplectingPosition&&mStepBeanList.get(0).getState()!=StepBean.STEP_UNDO){//判斷在完成之前的所有點(diǎn) //判斷在完成之前的所有點(diǎn),畫(huà)完成的線,這里是矩形,很細(xì)的矩形,類(lèi)似線,為了做區(qū)分,好看些 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); } } //-----------------------畫(huà)線-------draw line----------------------------------------------- //-----------------------畫(huà)圖標(biāo)-----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); } } //-----------------------畫(huà)圖標(biāo)-----draw icon----------------------------------------------- } /** * 得到所有圓點(diǎn)所在的位置 * @return */ public List<Float> getCircleCenterPointPositionList() { return mCircleCenterPointPositionList; } /** * 設(shè)置流程步數(shù) * @param stepsBeanList 流程步數(shù) */ 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(); } /** * 設(shè)置未完成線的顏色 * @param unCompletedLineColor */ public void setUnCompletedLineColor(int unCompletedLineColor){ this.mUnCompletedLineColor = unCompletedLineColor; } /** * 設(shè)置已完成線的顏色 * @param completedLineColor */ public void setCompletedLineColor(int completedLineColor){ this.mCompletedLineColor = completedLineColor; } /** * 設(shè)置默認(rèn)圖片 * @param defaultIcon */ public void setDefaultIcon(Drawable defaultIcon){ this.mDefaultIcon = defaultIcon; } /** * 設(shè)置已完成圖片 * @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; } /** * 設(shè)置正在進(jìn)行中的圖片 * @param attentionIcon */ public void setAttentionIcon(Drawable attentionIcon){ this.mAttentionIcon = attentionIcon; } /** * 設(shè)置對(duì)view監(jiān)聽(tīng) */ 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);//定義默認(rèn)未完成文字的顏色; private int mComplectedTextColor = ContextCompat.getColor(getContext(), R.color.completed_color);//定義默認(rèn)完成文字的顏色; 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); } /** * 設(shè)置顯示的文字 * @param stepsBeanList * @return */ public HorizontalStepView setStepViewTexts(List<StepBean> stepsBeanList) { mStepBeanList = stepsBeanList; mStepsViewIndicator.setStepNum(mStepBeanList); return this; } /** * 設(shè)置未完成文字的顏色 * @param unComplectedTextColor * @return */ public HorizontalStepView setStepViewUnComplectedTextColor(int unComplectedTextColor) { mUnComplectedTextColor = unComplectedTextColor; return this; } /** * 設(shè)置完成文字的顏色 * @param complectedTextColor * @return */ public HorizontalStepView setStepViewComplectedTextColor(int complectedTextColor) { this.mComplectedTextColor = complectedTextColor; return this; } /** * 設(shè)置StepsViewIndicator未完成線的顏色 * @param unCompletedLineColor * @return */ public HorizontalStepView setStepsViewIndicatorUnCompletedLineColor(int unCompletedLineColor) { mStepsViewIndicator.setUnCompletedLineColor(unCompletedLineColor); return this; } /** * 設(shè)置StepsViewIndicator完成線的顏色 * @param completedLineColor * @return */ public HorizontalStepView setStepsViewIndicatorCompletedLineColor(int completedLineColor) { mStepsViewIndicator.setCompletedLineColor(completedLineColor); return this; } /** * 設(shè)置StepsViewIndicator默認(rèn)圖片 * @param defaultIcon */ public HorizontalStepView setStepsViewIndicatorDefaultIcon(Drawable defaultIcon) { mStepsViewIndicator.setDefaultIcon(defaultIcon); return this; } /** * 設(shè)置StepsViewIndicator已完成圖片 * @param completeIcon */ public HorizontalStepView setStepsViewIndicatorCompleteIcon(Drawable completeIcon) { mStepsViewIndicator.setCompleteIcon(completeIcon); return this; } /** * 設(shè)置StepsViewIndicator正在進(jìn)行中的圖片 * @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中的使用,部分代碼截?。?/p>
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("手機(jī)綁定",1); stepBean1 = new StepBean("實(shí)名認(rèn)證",0); stepBean2 = new StepBean("學(xué)時(shí)充值",-1); stepBean3 = new StepBean("開(kāi)始用車(chē)",3); break; case 2: stepBean0 = new StepBean("手機(jī)綁定",1); stepBean1 = new StepBean("實(shí)名認(rèn)證",1); stepBean2 = new StepBean("學(xué)時(shí)充值",0); stepBean3 = new StepBean("開(kāi)始用車(chē)",3); break; case 3: stepBean0 = new StepBean("手機(jī)綁定",1); stepBean1 = new StepBean("實(shí)名認(rèn)證",1); stepBean2 = new StepBean("學(xué)時(shí)充值",1); stepBean3 = new StepBean("開(kāi)始用車(chē)",2); break; } stepsBeanList.add(stepBean0); stepsBeanList.add(stepBean1); stepsBeanList.add(stepBean2); stepsBeanList.add(stepBean3); mHorizontalStepView.setStepViewTexts(stepsBeanList);
以上所述是小編給大家介紹的Android 仿摩拜單車(chē)共享單車(chē)進(jìn)度條實(shí)現(xiàn)StepView效果,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Android通過(guò)ViewModel保存數(shù)據(jù)實(shí)現(xiàn)多頁(yè)面的數(shù)據(jù)共享功能
- Android開(kāi)發(fā)之5.0activity跳轉(zhuǎn)時(shí)共享元素的使用方法
- Android數(shù)據(jù)共享 sharedPreferences 的使用方法
- android與asp.net服務(wù)端共享session的方法詳解
- 詳解Android(共享元素)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)開(kāi)發(fā)實(shí)踐
- Android開(kāi)發(fā)中多進(jìn)程共享數(shù)據(jù)簡(jiǎn)析
- Android設(shè)備間實(shí)現(xiàn)藍(lán)牙(Bluetooth)共享上網(wǎng)
- Android實(shí)現(xiàn)不同apk間共享數(shù)據(jù)的方法(2種方法)
- android編程實(shí)現(xiàn)設(shè)置、打開(kāi)wifi熱點(diǎn)共享供他人連接的方法
- Android編程實(shí)現(xiàn)兩個(gè)Activity之間共享數(shù)據(jù)及互相訪問(wèn)的方法
- android不同activity之間共享數(shù)據(jù)解決方法
- Android 7.0應(yīng)用之間如何共享文件
相關(guān)文章
Android使用MediaRecorder實(shí)現(xiàn)錄像功能
這篇文章主要為大家詳細(xì)介紹了Android使用MediaRecorder實(shí)現(xiàn)錄像功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Eclipse打開(kāi)時(shí)“發(fā)現(xiàn)了以元素''d:skin''”開(kāi)頭的無(wú)效內(nèi)容。此處不應(yīng)含有子元素的解決方法
這篇文章主要介紹了Eclipse打開(kāi)時(shí)“發(fā)現(xiàn)了以元素'd:skin'”開(kāi)頭的無(wú)效內(nèi)容。此處不應(yīng)含有子元素的解決方法,涉及Android sdk中devices.xml文件的修改,需要的朋友可以參考下2016-01-01Android Studio設(shè)置、改變字體和主題的方法
這篇文章主要介紹了Android Studio設(shè)置、改變字體和主題的方法,需要的朋友可以參考下2018-03-03Android視圖控件架構(gòu)分析之View、ViewGroup
這篇文章主要為大家詳細(xì)介紹了Android視圖控件架構(gòu)分析之View、ViewGroup,感興趣的朋友可以參考一下2016-05-05Android自定義ViewGroup之CustomGridLayout(一)
這篇文章主要為大家詳細(xì)介紹了Android自定義ViewGroup之CustomGridLayout的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-09-09Android自定義Button并設(shè)置不同背景圖片的方法
這篇文章主要介紹了Android自定義Button并設(shè)置不同背景圖片的方法,涉及Android自定義控件的功能實(shí)現(xiàn)與布局相關(guān)技巧,需要的朋友可以參考下2016-01-01Android開(kāi)發(fā)使用RecyclerView添加點(diǎn)擊事件實(shí)例詳解
這篇文章主要為大家介紹了Android開(kāi)發(fā)使用RecyclerView添加點(diǎn)擊事件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Android寫(xiě)一個(gè)實(shí)時(shí)輸入框功能
這篇文章主要介紹了Android寫(xiě)一個(gè)實(shí)時(shí)輸入框功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Android FaceDetector實(shí)現(xiàn)人臉檢測(cè)功能
這篇文章主要為大家詳細(xì)介紹了Android FaceDetector實(shí)現(xiàn)人臉檢測(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05