热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

StepView自定义控件功能实现

功能介绍支持更多步全屏适配,支持横屏可精细化步进操作,如下支持小点先行当然可以更多定制操作,下面给出所有源代码,代码很简单,根据需要修

功能介绍


  1. 支持更多步
  2. 全屏适配,支持横屏
  3. 可精细化步进操作,如下支持小点先行

当然可以更多定制操作,下面给出所有源代码,代码很简单,根据需要修改。


效果图


第一步第二步第三步
第一步第二步第三步

支持小点先行

小点先行
修改i <&#61; step_number即可

if (i <&#61; step_number) {dotPaint.setColor(color_ffb93E);} else {dotPaint.setColor(color_666666);}

支持更多步

更多


arrays

<string-array name&#61;"change_phonenumber_step_name"><item>身份验证</item><item>设置新手机号</item><item>更换成功</item>
</string-array>

xml

<com.xxx.xxx.xxx.view.ChangePhoneNumberStepViewandroid:layout_width&#61;"match_parent"android:id&#61;"&#64;&#43;id/changep_honenumber_stepview"android:layout_height&#61;"100dp"phonecontrol:step_array_ids&#61;"&#64;array/change_phonenumber_step_name"tools:step_number&#61;"0">

ps &#xff1a;修改tools:step_number 可直接预览查看效果


源代码

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.LinearLayout;/*** 文件名&#xff1a;ChangePhoneNumberStepView* 描 述&#xff1a;* 作 者&#xff1a;maqi* 时 间&#xff1a;2022/4/11 11:03*/
public class ChangePhoneNumberStepView extends LinearLayout {private int step_array_ids;private int step_number;private String[] step_array_ids_strings;private int fatherWidth;private int fatherHeight;private RectF fatherRectF;private Paint dotPaint;private TextPaint textPaint;private Context mContext;private int color_666666;private int color_999999;private int color_ffb93E;private int color_4DFFB93E;private int textsize;private int padding;private int dotmargin;private int dotboard;private int dotmaxboard;private int dotminwidth;public interface StepListener {void step(int step_number);void complete();}private StepListener stepListener;public void setStepListener(StepListener stepListener) {this.stepListener &#61; stepListener;}public ChangePhoneNumberStepView(Context context) {super(context);mContext &#61; context;}public ChangePhoneNumberStepView(Context context, &#64;Nullable AttributeSet attrs) {super(context, attrs);mContext &#61; context;TypedArray a &#61; context.obtainStyledAttributes(attrs, R.styleable.changephonenumberstepview);step_array_ids &#61; a.getResourceId(R.styleable.changephonenumberstepview_step_array_ids, R.array.change_phonenumber_step_name);step_array_ids_strings &#61; context.getResources().getStringArray(step_array_ids);step_number &#61; a.getInteger(R.styleable.changephonenumberstepview_step_number, 0);a.recycle();init();}public ChangePhoneNumberStepView(Context context, &#64;Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext &#61; context;TypedArray a &#61; context.obtainStyledAttributes(attrs, R.styleable.changephonenumberstepview);step_array_ids &#61; a.getResourceId(R.styleable.changephonenumberstepview_step_array_ids, R.array.change_phonenumber_step_name);step_array_ids_strings &#61; context.getResources().getStringArray(step_array_ids);step_number &#61; a.getInteger(R.styleable.changephonenumberstepview_step_number, 0);a.recycle();init();}private void init() {setWillNotDraw(false);Log.d("sssss", "step_number " &#43; step_number);Log.d("sssss", "step_array_ids_strings " &#43; step_array_ids_strings[0]);textsize &#61; dp2px(mContext, 14);padding &#61; dp2px(mContext, 40);dotmargin &#61; dp2px(mContext, 20);/*大点 边框*/dotboard &#61; dp2px(mContext, 4);/*点直径*/dotmaxboard &#61; dp2px(mContext, 12);/*小点直径*/dotminwidth &#61; dp2px(mContext, 8);initPaint();}private void initPaint() {color_666666 &#61; mContext.getResources().getColor(R.color.color_666666);color_999999 &#61; mContext.getResources().getColor(R.color.color_999999);color_ffb93E &#61; mContext.getResources().getColor(R.color.color_FFB93E);color_4DFFB93E &#61; mContext.getResources().getColor(R.color.color_4DFFB93E);dotPaint &#61; new Paint();dotPaint.setStyle(Paint.Style.FILL);dotPaint &#61; new Paint(color_ffb93E);textPaint &#61; new TextPaint();textPaint.setColor(color_999999);textPaint.setTextSize(textsize);}public static int dp2px(Context context, float dpVal) {return (int) TypedValue.applyDimension(1, dpVal, context.getResources().getDisplayMetrics());}private float getTextH(TextPaint pFont, String text) {Rect rect &#61; new Rect();pFont.getTextBounds(text, 0, text.length(), rect);return rect.height();}private float getTextW(TextPaint pFont, String text) {return pFont.measureText(text);}public int getStep_number() {return step_number;}public void next() {if (step_number < step_array_ids_strings.length - 1) {this.step_number&#43;&#43;;if (null !&#61; stepListener) {stepListener.step(step_number);}if (step_number &#61;&#61; step_array_ids_strings.length - 1)if (null !&#61; stepListener) {stepListener.complete();}} else {if (null !&#61; stepListener) {stepListener.complete();}}invalidate();}&#64;Overridepublic void draw(Canvas canvas) {super.draw(canvas);float width &#61; fatherRectF.width();float height &#61; fatherRectF.height();int length &#61; step_array_ids_strings.length;float delta/*大球间隙*/ &#61; (width - padding * 2/*边距*/ - dotmaxboard - 2 * dotboard) / (length - 1);int mindotSize &#61; 3;float deltamin &#61; (delta - padding /*边距*/ - dotminwidth * mindotSize) / mindotSize;float y &#61; height / 2f - dotmaxboard / 2f;canvas.save();canvas.translate(padding &#43; dotmaxboard / 2 &#43; dotboard, 0);for (int i &#61; 0; i < length; i&#43;&#43;) {if (i <&#61; step_number) {//外环dotPaint.setColor(color_4DFFB93E);canvas.drawCircle(delta * i, y, dotmaxboard / 2f &#43; dotboard, dotPaint);//内环dotPaint.setColor(color_ffb93E);canvas.drawCircle(delta * i, y, dotmaxboard / 2f, dotPaint);//大环文字textPaint.setColor(color_ffb93E);String name &#61; step_array_ids_strings[i];float textW &#61; getTextW(textPaint, name);float textH &#61; getTextH(textPaint, name);canvas.drawText(name, delta * i - textW / 2f, y &#43; textH &#43; padding / 2f, textPaint);} else {//外环dotPaint.setColor(color_999999);canvas.drawCircle(delta * i, y, dotmaxboard / 2f &#43; dotboard, dotPaint);//内环dotPaint.setColor(color_666666);canvas.drawCircle(delta * i, y, dotmaxboard / 2f, dotPaint);//大环文字textPaint.setColor(color_999999);String name &#61; step_array_ids_strings[i];float textW &#61; getTextW(textPaint, name);float textH &#61; getTextH(textPaint, name);canvas.drawText(name, delta * i - textW / 2f, y &#43; textH &#43; padding / 2f, textPaint);}}for (int i &#61; 0; i < length - 1; i&#43;&#43;) {if (i < step_number) {dotPaint.setColor(color_ffb93E);} else {dotPaint.setColor(color_666666);}//环间 小点for (int j &#61; 1; j <&#61; mindotSize; j&#43;&#43;) {canvas.drawCircle(padding / 2f &#43; delta * i &#43; deltamin * j, y, dotminwidth / 2f, dotPaint);}}canvas.restore();}&#64;Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode &#61; MeasureSpec.getMode(widthMeasureSpec);int heightMode &#61; MeasureSpec.getMode(heightMeasureSpec);int widthSize &#61; MeasureSpec.getSize(widthMeasureSpec);int heightSize &#61; MeasureSpec.getSize(heightMeasureSpec);if (heightMode &#61;&#61; MeasureSpec.EXACTLY) {fatherHeight &#61; heightSize;}if (widthMode &#61;&#61; MeasureSpec.EXACTLY) {fatherWidth &#61; widthSize;}fatherRectF &#61; new RectF(0, 0, fatherWidth, fatherHeight);Log.d("ssss", "heightMode " &#43; heightMode);Log.d("ssss", "widthMode " &#43; widthMode);Log.d("ssss", "widthSize " &#43; widthSize);Log.d("ssss", "heightSize " &#43; heightSize);setMeasuredDimension(widthSize, heightSize);}
}

推荐阅读
  • 开发笔记:深入解析Android自定义控件——Button的72种变形技巧
    开发笔记:深入解析Android自定义控件——Button的72种变形技巧 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 在探讨如何在Android的TextView中实现多彩文字与多样化字体效果时,本文提供了一种不依赖HTML技术的解决方案。通过使用SpannableString和相关的Span类,开发者可以轻松地为文本添加丰富的样式和颜色,从而提升用户体验。文章详细介绍了实现过程中的关键步骤和技术细节,帮助开发者快速掌握这一技巧。 ... [详细]
author-avatar
EIght_16
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有