今天我和大家来交流一下自定义View,之前的在工作中很多控件都是找大神做好的来用,一者是没时间,项目比较着急上线,再者是自己之前一直没有研究过,前段时间所有的项目都完成的差不多了,空出来时间就久了不少自定View,那么今天就和大家一起来探讨一下SeekBar 拖动条。

开始写之前我们先来看看android官方的SeekBar都有哪些特性

大家都知道做到音频播放和音乐播放时,我们会用SeekBar来做控制进度或者限制进度 ,看一下官方API,继承自ProgressBar,

SeekBar是ProgressBar的扩展,在其基础上增加了一个可拖动的thumb。

今天我们要做的是把Thumb自定成可以显示文字的部分

首先我们要知道自定义View的几个步骤

1、自定义View的属性

2、获取属性值

3、重写OnMesure方法,用于测量View的宽高 (非必要)

4、重写Ondraw方法 绘制

看过以上步骤那么久开始吧

一、自定义View属性

从效果来看,我们需要定义这些属性值

tickBarHeight 拖动条高度     tickBarColor 拖动条默认颜色     circleButtonColor 文字按钮颜色   circleButtonTextColor 文字颜色

circleButtonTextSize 文字大小circleButtonRadius按钮半径progressHeight 进度条高度progressColor 进度条颜色

selectProgress 进度默认值 startProgress 进度开始值 maxProgress 进度最大值 isShowButtonText显示文字标志

isShowButton 显示按钮标志 isRound 是否是圆角

在values目录下 创建attrs.xml

添加以上属性定义

<declare-styleable name="NumTipSeekBar">

<attr name="tickBarHeight" format="dimension" />
        <attr name="tickBarColor" format="color" />
        <attr name="circleButtonColor" format="color" />
        <attr name="circleButtonTextColor" format="color" />
        <attr name="circleButtonTextSize" format="dimension" />
        <attr name="circleButtonRadius" format="dimension" />
        <attr name="progressHeight" format="dimension" />
        <attr name="progressColor" format="color" />
        <attr name="selectProgress" format="integer" />
        <attr name="startProgress" format="integer" />
        <attr name="maxProgress" format="integer" />
        <attr name="isShowButtonText" format="boolean" />
        <attr name="isShowButton" format="boolean" />
        <attr name="isRound" format="boolean" />
    </declare-styleable>

前面是属性名,后面的format是格式,数据值类型

二、接下来就是获取属性

自定义一个TipSeekBar类继承View

然后定义上述属性的对应的成员变量

public TipSeekBar(Context context) {
        this(context, null);
    }

public TipSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public TipSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

三个构造方法

private void init(Context context, AttributeSet attrs) {

TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.NumTipSeekBar);
        mTickBarHeight = attr.getDimensionPixelOffset(R.styleable
                .NumTipSeekBar_tickBarHeight, getDpValue(8));
        mTickBarColor = attr.getColor(R.styleable.NumTipSeekBar_tickBarColor, getResources()
                .getColor(R.color.orange_f6));
        mCircleButtonColor = attr.getColor(R.styleable.NumTipSeekBar_circleButtonColor,
                getResources().getColor(R.color.white));
        mCircleButtonTextColor = attr.getColor(R.styleable.NumTipSeekBar_circleButtonTextColor,
                getResources().getColor(R.color.white));
        mCircleButtonTextSize = attr.getDimension(R.styleable
                .NumTipSeekBar_circleButtonTextSize, getDpValue(16));
        mCircleButtonRadius = attr.getDimensionPixelOffset(R.styleable
                .NumTipSeekBar_circleButtonRadius, getDpValue(16));
        mProgressHeight = attr.getDimensionPixelOffset(R.styleable
                .NumTipSeekBar_progressHeight, getDpValue(20));
        mProgressColor = attr.getColor(R.styleable.NumTipSeekBar_progressColor,
                getResources().getColor(R.color.white));
        mSelectProgress = attr.getInt(R.styleable.NumTipSeekBar_selectProgress, 0);
        mStartProgress = attr.getInt(R.styleable.NumTipSeekBar_startProgress, 0);
        mMaxProgress = attr.getInt(R.styleable.NumTipSeekBar_maxProgress, 10);
        mIsShowButtonText = attr.getBoolean(R.styleable.NumTipSeekBar_isShowButtonText, false);
        mIsShowButton = attr.getBoolean(R.styleable.NumTipSeekBar_isShowButton, true);
        mIsRound = attr.getBoolean(R.styleable.NumTipSeekBar_isRound, true);
        initView();
        attr.recycle(); //一定要记得释放,避免引起内存泄露
    }

private void initView() {
        mProgressPaint = new Paint();
        mProgressPaint.setColor(mProgressColor);
        mProgressPaint.setStyle(Paint.Style.FILL);
        mProgressPaint.setAntiAlias(true);

mCircleButtonPaint = new Paint();
        mCircleButtonPaint.setColor(mCircleButtonColor);
        mCircleButtonPaint.setStyle(Paint.Style.FILL);
        mCircleButtonPaint.setAntiAlias(true);

mCircleButtonTextPaint = new Paint();
        mCircleButtonTextPaint.setTextAlign(Paint.Align.CENTER);
        mCircleButtonTextPaint.setColor(mCircleButtonTextColor);
        mCircleButtonTextPaint.setStyle(Paint.Style.FILL);
        mCircleButtonTextPaint.setTextSize(mCircleButtonTextSize);
        mCircleButtonTextPaint.setAntiAlias(true);

mTickBarPaint = new Paint();
        mTickBarPaint.setColor(mTickBarColor);
        mTickBarPaint.setStyle(Paint.Style.FILL);
        mTickBarPaint.setAntiAlias(true);

mTickBarRecf = new RectF();//View绘制区域的矩形,进度条区域
        mProgressRecf = new RectF();//进度条区域矩形
        mCircleRecf = new RectF();//按钮区域矩形
    }

属性以获取到

三、绘制

第三步本来是计算控件的宽高,但是由于我们这里的定义了View的宽高,所以这边就不重写onMesure方法,但是我建议大家在写自定义View的时候最好是加上这个

重写,自己计算一下View的高度

接下来就是绘制 重写onMesure

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        initValues(width, height);
        if (mIsRound) {
            canvas.drawRoundRect(mTickBarRecf, mProgressHeight / 2, mProgressHeight / 2,
                    mTickBarPaint);
            canvas.drawRoundRect(mProgressRecf, mProgressHeight / 2, mProgressHeight / 2,
                    mProgressPaint);
        } else {
            canvas.drawRect(mTickBarRecf, mTickBarPaint);
            canvas.drawRect(mProgressRecf, mProgressPaint);
        }
//        canvas.drawArc(mCircleRecf, 0, 360, true, mCircleButtonPaint);
        if (mIsShowButton) {
            canvas.drawCircle(mCirclePotionX, mViewHeight / 2, mCircleButtonRadius,
                    mCircleButtonPaint);
        }
        if (mIsShowButtonText) {
            Paint.FontMetricsInt fontMetrics = mCircleButtonTextPaint.getFontMetricsInt();
            int baseline = (int) ((mCircleRecf.bottom + mCircleRecf.top - fontMetrics.bottom -
                    fontMetrics
                            .top) / 2);
            // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()
            canvas.drawText(String.valueOf((mSelectProgress+progressIncrement)+progressText), mCircleRecf.centerX
                            (), baseline,
                    mCircleButtonTextPaint);
        }
    }

这里需要计算一下几个值

三个矩形的位置

这个示意图希望大家能看明白

我来说一下tickbar矩形位置计算

第一点左上角就是就是位于View的x1,y1 x1很容易 getPaddingLeft () ,没有设置paddingLeft就是0 y1的话需要计算一下 整个View的高度减去tickbar的高度,然后再除2就是距离View顶部的高度,即为tickbar的起始Y

第二点右下角x2,y2 x2 同样getPaddingLeft ()+viewWidth,y2= mTickBarHeight / 2 + mViewHeight / 2;

剩下的两个矩形就和容易了,自己分析一下,画一下图就可以得出计算公式

重要的部分来了,就是拖动按钮事件逻辑处理

onTouchEvent()重写

这里有两种情况,拖动

1、按住拖动,2点击View的某个位置改变进度条

所以需要对这个两个动作进行处理

其实这部分计算比较简单,因为进度条的高度位置是不变的,只是X在变化,那么只要获取x的位置,同时计算一下相对于整个宽度的比率就可以得出

回调一下setSelectProgress() 重新绘制一下

当然这里还要写一个回调接口,就是手触摸up时你可以做其他的逻辑处理

写到这里基本上就大功告成,代码我打包好,大家自行下载研究吧。

http://download.csdn.net/detail/luckty/9832067

希望有问题大家随时提问和交流

3QU

附上下载地址:http://download.csdn.net/detail/luckty/9832067

自定义SeekBar 带文字相关推荐

  1. android 自定义 seekbar,Android自定义控件 带文字提示的SeekBar

    封面 1.写在前面 SeekBar控件在开发中还是比较常见的,比如音视频进度.音量调节等,但是原生控件有时还不能满足我们的需求,今天就来学习一下如何自定义SeekBar控件,本文主要实现了一个带文字指 ...

  2. 自定义绘制圆环与实心圆(带文字)

    自定义绘制圆环 package com.cn.myvdun; import android.content.Context; import android.graphics.Canvas; impor ...

  3. 自定义Android带图片和文字的ImageButton

    自定义Android带图片的按钮 前言 现在移动设备的按钮设计讲究大图标小文字,希望用户只要一看到图标便能知道这个按钮是干嘛的,但又要有必要的文字提示,最常见的就数搜索按钮了,上面一个大大的放大镜图标 ...

  4. 【Android】Android实现自定义带文字和图片的Button

    在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最 ...

  5. Android自定义SeekBar,带开始值结束值和Thumb上方滑动的Text

    之前根据网友的博文写了一个Demo(点击打开链接)但是这个Demo用到attr,layout color,还有其他的类,给使用者造成很多麻烦,我想,这样的自定义控件为啥不用一个类来完成呢,这样直接复制 ...

  6. 自定义Android带图片的按钮

    自定义Android带图片的按钮 前言 现在移动设备的按钮设计讲究大图标小文字,希望用户只要一看到图标便能知道这个按钮是干嘛的,但又要有必要的文字提示,最常见的就数搜索按钮了,上面一个大大的放大镜图标 ...

  7. 微信分享网页链接自定义图片和文字描述

    今天开发需要微信分享网页链接自定义图片和文字描述,于是网上各种查找资料和各种看手册,遇到了好多坑,不过啃了半天以后终于把问题解决了,以防以后忘记,今天记录一下; 首先,由于微信已经发布了想要分享链接必 ...

  8. Android 自定义seekbar【仿微信联系人】

    /** *  * 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50452578 *   @author:[JunTao_sun]   ...

  9. Android按钮滚动条,Android自定义Seekbar滑动条,Pop提示跟随滑动按钮一起滑动

    由于项目需要做出此效果,自定义写了一个. 效果图 思路: 原始的seekbar只有滑动条并没有下方的提示文字,所以我们必须要继承Seekbar重写这个控件. 代码: 在values文件夹下新建attr ...

  10. 分享一套响应式自适应公司网站官网源码,带文字搭建教程

    分享一套响应式自适应公司网站官网源码,带文字搭建教程.需要源码学习可私信我. 技术架构 PHP7.2 + nginx + mysql5.7 + JS + CSS + HTML cnetos7以上 + ...

最新文章

  1. 表观调控高通量测序分析培训开课啦
  2. 小程序 - 效果处理之技巧合集(更新中...)
  3. VMM虚拟机启动失败故障处理
  4. kafka消费者如何读同一生产者消息_Kafka消费者生产者实例
  5. SpringBootAdmin监控信息讲解
  6. Vue路由开启keep-alive缓存页面
  7. ERROR 1044 (42000): Access denied for user ''@'localhost' to database
  8. Vim-latex 插件 的安装
  9. docker强制删除none的image镜像
  10. c语言创建一个文本文件datadat,c语言文件选择题.docx
  11. 西门子FB284伺服v90profinet程序西门子触摸屏程序
  12. 如何快速调整图片亮度和对比度?
  13. Secure CRT 最大显示行数的设置
  14. CSS基础(emmet 语法,CSS 复合选择器, 布局认知,背景样式)
  15. Java爬虫 --- 爬取王者荣耀英雄图片
  16. 12uec++多人游戏【自定义碰撞通道+头部暴击+连续开火】
  17. 基于linux的qos编程接口研究与分析,基于Linux的QoS编程接口研究与分析(2)
  18. NOI2020 瞎逛游记
  19. 11月面完美团+网易+腾讯+百度+滴滴熬夜5天整理面经攒人品
  20. KISSY基础篇乄KISSY之DOM(2)

热门文章

  1. mysql连接失败问题
  2. 电器上的这些符号有什么特别含义?
  3. 2021年京东/淘宝/天猫/双十一红包最新优惠攻略,1111超级红包如何抢?
  4. iOS问题记录 - Xcode 14安装低版本iOS模拟器
  5. 【信息系统项目管理师】信息系统项目管理师计算题汇总
  6. grep、cut、sed、awk
  7. 卡方检验的统计量推导_卡方检验如何计算?
  8. 【计算机网络】网络层(六)—— IP组播与移动IP
  9. Guava学习笔记-Joiner
  10. 小程序使用wxs处理手机号