由于项目需要做出此效果,自定义写了一个。

效果图

思路:

原始的seekbar只有滑动条并没有下方的提示文字,所以我们必须要继承Seekbar重写这个控件。

代码:

在values文件夹下新建attrs.xml,用于设置跟随滑动按钮的文字大小,颜色,背景。

<declare-styleable name="MySeekBar">
        <attr name="textsize" format="dimension" />
        <attr name="textcolor" format="color" />
        <attr name="img" format="reference" />
</declare-styleable>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在布局里引用此控件

 <com.jzh.myseekbar.MySeekBar
            android:id="@+id/seekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="80"
            android:maxHeight="10dp"
            android:progress="0"
            android:progressDrawable="@drawable/seekbar_style"
            android:splitTrack="false"
            android:thumb="@mipmap/niu"
            app:img="@mipmap/ann"
            app:textcolor="#fff"
            app:textsize="14dp" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

自定义控件样式

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/background">

        <shape>
            <corners android:radius="5dp" />
            <gradient
                android:angle="0"
                android:centerColor="@android:color/holo_orange_dark"
                android:endColor="@android:color/holo_red_dark"
                android:startColor="#2aade3" />
        </shape>
    </item>

</layer-list>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

主要核心代码

/**
     * 文本的颜色
     */
    private int mTitleTextColor;
    /**
     * 文本的大小
     */
    private float mTitleTextSize;
    private String mTitleText;//文字的内容

    /**
     * 背景图片
     */
    private int img;
    private Bitmap map;
    //bitmap对应的宽高
    private float img_width, img_height;
    Paint paint;

    private float numTextWidth;
    //测量seekbar的规格
    private Rect rect_seek;
    private Paint.FontMetrics fm;

    public static final int TEXT_ALIGN_LEFT = 0x00000001;
    public static final int TEXT_ALIGN_RIGHT = 0x00000010;
    public static final int TEXT_ALIGN_CENTER_VERTICAL = 0x00000100;
    public static final int TEXT_ALIGN_CENTER_HORIZONTAL = 0x00001000;
    public static final int TEXT_ALIGN_TOP = 0x00010000;
    public static final int TEXT_ALIGN_BOTTOM = 0x00100000;
    /**
     * 文本中轴线X坐标
     */
    private float textCenterX;
    /**
     * 文本baseline线Y坐标
     */
    private float textBaselineY;
    /**
     * 文字的方位
     */
    private int textAlign;

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

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

    public MySeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MySeekBar, defStyleAttr, 0);
        int n = array.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = array.getIndex(i);
            switch (attr) {
                case R.styleable.MySeekBar_textsize:
                    mTitleTextSize = array.getDimension(attr, 15f);
                    break;
                case R.styleable.MySeekBar_textcolor:
                    mTitleTextColor = array.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.MySeekBar_img:
                    img = array.getResourceId(attr, R.mipmap.ic_launcher);
                    break;
            }
        }
        array.recycle();
        getImgWH();
        paint = new Paint();
        paint.setAntiAlias(true);//设置抗锯齿
        paint.setTextSize(mTitleTextSize);//设置文字大小
        paint.setColor(mTitleTextColor);//设置文字颜色
        //设置控件的padding 给提示文字留出位置
        setPadding((int) Math.ceil(img_width) / 2, 0, (int) Math.ceil(img_height) / 2, (int) Math.ceil(img_height) + 10);
        textAlign = TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL;
    }

    /**
     * 获取图片的宽高
     */
    private void getImgWH() {
        map = BitmapFactory.decodeResource(getResources(), img);
        img_width = map.getWidth();
        img_height = map.getHeight();

    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        setTextLocation();//定位文本绘制的位置
        rect_seek = this.getProgressDrawable().getBounds();
        //定位文字背景图片的位置
        float bm_x = rect_seek.width() * getProgress() / getMax();
        float bm_y = rect_seek.height() + 20;
//        //计算文字的中心位置在bitmap
        float text_x = rect_seek.width() * getProgress() / getMax() + (img_width - numTextWidth) / 2;
        canvas.drawBitmap(map, bm_x, bm_y, paint);//画背景图
        // canvas.drawRoundRect();
        canvas.drawText(mTitleText, text_x, (float) (textBaselineY + bm_y + (0.16 * img_height / 2)), paint);//画文字

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        invalidate();//监听手势滑动,不断重绘文字和背景图的显示位置
        return super.onTouchEvent(event);
    }

    /**
     * 定位文本绘制的位置
     */
    private void setTextLocation() {

        fm = paint.getFontMetrics();
        //文本的宽度
        mTitleText = getProgress() + 10 + "℃";

        numTextWidth = paint.measureText(mTitleText);

        float textCenterVerticalBaselineY = img_height / 2 - fm.descent + (fm.descent - fm.ascent) / 2;
        switch (textAlign) {
            case TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL:
                textCenterX = img_width / 2;
                textBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_LEFT | TEXT_ALIGN_CENTER_VERTICAL:
                textCenterX = numTextWidth / 2;
                textBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_RIGHT | TEXT_ALIGN_CENTER_VERTICAL:
                textCenterX = img_width - numTextWidth / 2;
                textBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_CENTER_HORIZONTAL:
                textCenterX = img_width / 2;
                textBaselineY = img_height - fm.bottom;
                break;
            case TEXT_ALIGN_TOP | TEXT_ALIGN_CENTER_HORIZONTAL:
                textCenterX = img_width / 2;
                textBaselineY = -fm.ascent;
                break;
            case TEXT_ALIGN_TOP | TEXT_ALIGN_LEFT:
                textCenterX = numTextWidth / 2;
                textBaselineY = -fm.ascent;
                break;
            case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_LEFT:
                textCenterX = numTextWidth / 2;
                textBaselineY = img_height - fm.bottom;
                break;
            case TEXT_ALIGN_TOP | TEXT_ALIGN_RIGHT:
                textCenterX = img_width - numTextWidth / 2;
                textBaselineY = -fm.ascent;
                break;
            case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_RIGHT:
                textCenterX = img_width - numTextWidth / 2;
                textBaselineY = img_height - fm.bottom;
                break;
        }
    }

Android自定义Seekbar滑动条,Pop提示跟随滑动按钮一起滑动的更多相关文章

  1. Android自定义Seekbar拖动条式样

    SeekBar拖动条可以由用户控制,进行拖动操作.比如,应用程序中用户需要对音量进行控制,就可以使用拖动条来实现. 1.SeekBar控件的使用 1.1SeekBar常用属性 SeekBar的常用属性 ...

  2. android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

    示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...

  3. Android 自定义seekbar中,thumb被覆盖掉一部分问题

    (图一)  (图二)    (图三) 做一个自定义的seekbar,更改其背景图片: <com.android.Progress android:id="@+id/focus_seek ...

  4. android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]

    http://blog.csdn.net/jj120522/article/details/8095852 示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这 ...

  5. Android 自定义水平进度条的圆角进度

    有时项目中需要实现水平圆角进度,如下两种,其实很简单     下面开始看代码,先从主界面布局开始看起: <?xml version="1.0" encoding=" ...

  6. Android -- 自定义带进度条的按钮

    1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击

  7. android自定义seekBar

    Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子 很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧状的,咋办,比如 ok,我们开始吧: 一)变换前背景 先来 ...

  8. android 自定义圆形进度条

    一.通过动画实现 定义res/anim/loading.xml如下: [html]  view plain copy print ?   <?xml version="1.0" ...

  9. 推荐几个Android自定义的进度条(转载)

    CustomLoading ElasticDownload Circle-Progress-View lzyzsdCircleProgress SquareProgressBar materialis ...

随机推荐

  1. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  2. math对象与数组对象

    1.math对象 属性 //PI    圆周率 方法 //random    随机数 var num= Math.random();    生成0到1的随机数//round 四舍五入var num2 ...

  3. 知识点干货—多线程同步【6】之synchronized

    "明日复明日,明日何其多. 我生待明日,万事成蹉跎. 世人若被明日累,春去秋来老将至. 朝看水东流,暮看日西坠. 百年明日能几何?请君听我明日歌. 明日复明日,明日何其多! 日日待明日,万世 ...

  4. [UWP]实现Picker控件

    1. 前言 在WPF中,很多打开下拉框(Popup或Flyout)选择一个结果值的控件,除了ComboBox等少数例外,这种控件都以-Picker做名称后缀.因为要打开关闭下拉框和计算下拉框的弹出位置 ...

  5. 使用localhost可以访问,但使用本地ip+端口号无法访问

    今天想使用ip访问本机的iview-admin项目,结果怎么配置都无法访问,根据iview工程执行的命令npm run dev了解到是webpack配置的问题,打开工程里的node_modules文件 ...

  6. Sonar 数据库表关系整理一(续)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 简介:Sonar平台是目前较为流行的静态代码扫描平台,为了便于使用以及自己二次开发,有必要对它的数据库结构进行学习 ...

  7. netstream播放rtmp直播流卡顿

    标准的flash播放器ActionScript3语句,播放flash publish的rtmp流,NetConnection--->NetStream--->play--->atta ...

  8. Spring-shiro源码陶冶-AuthorizingRealm用户认证以及授权

    阅读源码有助于陶冶情操,本文旨在简单的分析shiro在Spring中的使用 简单介绍 Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能 AuthorizingReal ...

  9. BZOJ 2986: Non-Squarefree Numbers [容斥原理 二分]

    题意:求第$n \le 10^{10}$个不是无平方因子数 二分答案, 容斥一下,0个质数的平方因子-1个..... 枚举$\sqrt$的平方因子乘上莫比乌斯函数,最后求出无平方因子数的个数取补集 # ...

  10. BZOJ 4031: [HEOI2015]小Z的房间 [矩阵树定理 行列式取模]

    http://www.lydsy.com/JudgeOnline/problem.php?id=4031 裸题........ 问题在于模数是$10^9$ 我们发现消元的目的是让一个地方为0 辗转相除 ...