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();
    }

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

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在 Android SeekBar 中实时更新视频进度,你需要在代码中实现以下步骤: 1. 初始化 SeekBar 和 MediaPlayer。 2. 在 SeekBar 上设置 OnSeekBarChangeListener,以监听拖动事件。 3. 在拖动事件中,更新 MediaPlayer 的当前位置。 4. 在 MediaPlayer 中设置 OnPreparedListener,以获取视频的总长度。 5. 使用 Handler 定期更新 SeekBar进度,以反映当前视频的进度。 下面是一些示例代码,用于演示如何在 Android SeekBar 中实时更新视频进度: ``` // 初始化 SeekBar 和 MediaPlayer SeekBar seekBar = findViewById(R.id.seek_bar); MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.video); // 监听 SeekBar 的拖动事件 seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { // 如果是用户拖动 SeekBar,更新 MediaPlayer 的当前位置 mediaPlayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); // 获取视频的总长度 mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { int duration = mediaPlayer.getDuration(); seekBar.setMax(duration); } }); // 定期更新 SeekBar进度 final Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { int currentPosition = mediaPlayer.getCurrentPosition(); seekBar.setProgress(currentPosition); handler.postDelayed(this, 1000); } }; handler.postDelayed(runnable, 1000); ``` 上面的代码中,我们使用了 Handler 定期更新 SeekBar进度,间隔为 1 秒钟。在实际应用中,你可以根据需要调整更新的频率。另外,由于视频播放需要消耗大量的资源,建议在退出页面时及时释放 MediaPlayer。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linconi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值