android seekbar thumb 上添加进度值并居中

环境:android studio 、java

项目需要在进度条的滑块上显示进度值并居中, UI设计图

代码实现效果图

浅色模式:

深色模式:

由于一开始没有自定义seekbar, 使用源码Seekar, 滑块要求时带圆角,所以需要设置thumbOffset 使滑条和滑块衔接顺畅。想实现UI效果,需要对文字与滑条的左边距,进行计算处理。

布局:

    <RelativeLayout
        android:layout_width="1335dp"
        android:layout_height="46dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        app:layout_constraintStart_toEndOf="@+id/dark"
        app:layout_constraintEnd_toStartOf="@+id/light"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:orientation="vertical">
        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:thumbOffset="5dp"
            android:splitTrack="false"
            android:thumb="@drawable/brightness_adjustment_slider"
            android:progressDrawable="@drawable/brightness_adjustment_bg"/>
        <TextView
            android:id="@+id/seekbar_value"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/harmonyos_sans_sc_regular"
            android:textColor="@color/font_color"
            android:singleLine="true"
            android:textSize="24sp"/>
    </RelativeLayout>

实现文字居中的java代码:

                int textViewWidth = mSeekBarValueTextView.getWidth();
                int textViewHeight = mSeekBarValueTextView.getHeight();
                int thumbWidth = mSeekBar.getThumb().getIntrinsicWidth();
                int thumbHeight = mSeekBar.getThumb().getIntrinsicHeight();
                int thumbOff = mSeekBar.getThumbOffset(); // 滑块偏移距离
                int available = mSeekBar.getWidth() - mSeekBar.getPaddingLeft() - mSeekBar.getPaddingRight(); // seekbar 有效宽
                int tempValue = value - mMin;
                // 进度百分比
                float progressRatio = (float) tempValue / (mSeekBar.getMax() - mSeekBar.getMin());
                // 文字相对滑块左边的距离
                int textInThumbOff = (thumbWidth-textViewWidth)/2;
                available = available - thumbWidth;
                available += thumbOff*2;
                final int thumbPos = (int) (progressRatio * available + 0.5f); // 滑块的左起始位置
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mSeekBarValueTextView.getLayoutParams();
                int textTopPos = (thumbHeight- textViewHeight)/2; // 文字上方的位置
                int textLeftPos = thumbPos+ textInThumbOff + mSeekBar.getPaddingLeft() - thumbOff; // 文字左边的位置,mSeekBar.getPaddingLeft() - thumbOff 为X轴上的偏移量
                params.setMargins(textLeftPos, textTopPos,0, 0);
                mSeekBarValueTextView.setLayoutParams(params);

java 中文字左边位置计算参考seekbar原生代码滑块位置实现:

frameworks/base/core/java/android/widget/AbsSeekBar.java:


    /**
     * Updates the thumb drawable bounds.
     *
     * @param w Width of the view, including padding
     * @param thumb Drawable used for the thumb
     * @param scale Current progress between 0 and 1
     * @param offset Vertical offset for centering. If set to
     *            {@link Integer#MIN_VALUE}, the current offset will be used.
     */
    private void setThumbPos(int w, Drawable thumb, float scale, int offset) {
        int available = w - mPaddingLeft - mPaddingRight;
        final int thumbWidth = thumb.getIntrinsicWidth();
        final int thumbHeight = thumb.getIntrinsicHeight();
        available -= thumbWidth;

        // The extra space for the thumb to move on the track
        available += mThumbOffset * 2;

        final int thumbPos = (int) (scale * available + 0.5f);

        final int top, bottom;
        if (offset == Integer.MIN_VALUE) {
            final Rect oldBounds = thumb.getBounds();
            top = oldBounds.top;
            bottom = oldBounds.bottom;
        } else {
            top = offset;
            bottom = offset + thumbHeight;
        }

        final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
        final int right = left + thumbWidth;

        final Drawable background = getBackground();
        if (background != null) {
            final int offsetX = mPaddingLeft - mThumbOffset;
            final int offsetY = mPaddingTop;
            background.setHotspotBounds(left + offsetX, top + offsetY,
                    right + offsetX, bottom + offsetY);
        }

        // Canvas will be translated, so 0,0 is where we start drawing
        thumb.setBounds(left, top, right, bottom);
        updateGestureExclusionRects();
    }

本文为项目效果实现思路记录所用

相关推荐

  1. uniapp传文件获取进度

    2024-03-19 21:42:06       26 阅读
  2. android 水平居中对齐举例

    2024-03-19 21:42:06       36 阅读
  3. css中让div下位置居中

    2024-03-19 21:42:06       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-19 21:42:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-19 21:42:06       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-19 21:42:06       82 阅读
  4. Python语言-面向对象

    2024-03-19 21:42:06       91 阅读

热门阅读

  1. 安卓UI面试题 36-40

    2024-03-19 21:42:06       35 阅读
  2. 网络编程day4

    2024-03-19 21:42:06       45 阅读
  3. 关于前端的学习2

    2024-03-19 21:42:06       38 阅读
  4. 人生视角的双重镜像:喜剧与悲剧的辩证统一

    2024-03-19 21:42:06       41 阅读
  5. pytorch升级打怪(七)

    2024-03-19 21:42:06       40 阅读
  6. C语言 函数

    2024-03-19 21:42:06       45 阅读
  7. 用python实现球球大作战

    2024-03-19 21:42:06       41 阅读
  8. python怎样使用excel

    2024-03-19 21:42:06       39 阅读
  9. 程序员如何选择职业赛道?

    2024-03-19 21:42:06       38 阅读
  10. QT 多线程使用以及注意事项

    2024-03-19 21:42:06       43 阅读