Seekbar thumb center

最近项目中用到了一个可拖动的进度条,并且在当前进度的末端的icon上,添加当前进度。毫无疑问,当前进度只有在icon的中心才好看。左搜右搜,怎么都没有找到。后来,我就很生气,你都不会自己写一个吗?硬着头皮,想了想原理。发现是so easy!
先贴几张图片,让大家清楚我在啰嗦什么
开始位置
中间任意位置
结束位置
简单叙述一下原理:既然文字要位于icon的中心,则首先要定位到Icon的位置。
在水平方向上:icon走的路程=进度条长度-icon的长度;然后计算出每一个进度icon需要移动的位置:((mScreenWidth - mDrawableWidth) / (double) mTotalSeconds); 由于文字是从左侧进行定位的,计算出文字块占用的空间,以便定位到文字在icon上的左侧位置:相关代码如下:

/**
         * 获取显示字样占用的空间
         */
        TextPaint paint = new TextPaint();
        paint.setTextSize(mProgressView.getTextSize());
        Rect rect = new Rect();
        String tt = "00:00";
        paint.getTextBounds(mStartTimeStr, 0, tt.length(), rect);
        mTextWidth = rect.width();
        mTextHeight = rect.height();
/**定位文字在icon左侧的相对坐标
*/
(mDrawableWidth - mTextWidth) / 2

在垂直方向上:icon没有移动,只需要在起始位置定位到icon中心即可;为了可以使用layout方法,在这里给代表当前进度的TextView添加了一个ViewGroup:

    <gu.chuan.hang.PlaySeekbarGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="-3dp" >
            <TextView
                android:id="@+id/text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:includeFontPadding="false"
                android:singleLine="true"
                android:text="00:00"
                android:textColor="#f00"
                android:textSize="12sp" />
        </gu.chuan.hang.PlaySeekbarGroup>
package gu.chuan.hang;

import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;

public class PlaySeekbarGroup extends ViewGroup {

    public PlaySeekbarGroup(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public PlaySeekbarGroup(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public PlaySeekbarGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // TODO Auto-generated method stub

    }

}

PS:1.可以看到这个自定义ViewGroup什么都没有做。onLayout()方法是ViewGroup才会有的,在布局的时候,调用完TextView的layout(),还需要调用parent组件的onLayout(),最终才能确定,TextView的位置。在这里我大胆猜测是,代表当前进度的TextView不想让parent组件“管闲事”(影响自己的位置)。所以在外层包裹了一个空的ViewGroup;
2.android:layout_marginTop=”-3dp”这种用法很少见,但有的时候不得不用啊,TextView中文本与TextView顶端并不是对齐的,何况又加上一层包裹(ViewGroup),为了与seekbar实现垂直对齐,就向上偏移吧。
讲解了折磨多,看一下OnSeekChangeListener吧:

private class OnSeekBarChangeListenerImp implements
            SeekBar.OnSeekBarChangeListener {
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int layoutLeft = (int) (progress * mMoveStep)
                    + (mDrawableWidth - mTextWidth) / 2;

            System.err.println("layoutLeft" + layoutLeft);
            mProgressView.layout(layoutLeft, mTextlayoutTop, mScreenWidth, 80);
            String showText = getTimeBySeconds(progress, mStartTimeStr);
            mProgressView.setText(showText.substring(3));
        }

        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub
        }
    }

本人菜鸟一枚,讲解的不怎么清楚。为了大家能更好的体会,现附上Demo:
http://download.csdn.net/detail/guchuanhang/9145923

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要自定义seekBar的样式,可以通过以下步骤来进行操作: 1. 在布局文件中添加seekBar控件,并设置相应的属性,如id、宽度、高度和最大值等。可以使用wrap_content属性来自动适应seekBar的高度。 2. 使用style属性来设置seekBar的风格。可以创建自定义的style,并在seekBar的style属性中引用。 3. 可以使用minHeight属性来设置seekBar的最小高度,用paddingTop和paddingBottom属性来拓宽seekBar的触摸区域。如果要让thumb在中间显示,需要将seekBar的layout_height属性设置为wrap_content。 4. 使用scaleType属性来设置seekBar的缩放类型,可以选择center等选项。 下面是一个示例代码: ```xml <SeekBar android:id="@id/seekBar" style="@style/Widget.AppCompat.SeekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxHeight="32dp" android:minHeight="32dp" android:paddingTop="16dp" android:paddingBottom="16dp" android:max="100" android:progress="80" android:scaleType="center" /> ``` 通过以上步骤,你可以自定义seekBar的样式,包括设置风格、高度、触摸区域和缩放类型等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [自定义SeekBar样式](https://download.csdn.net/download/tfs080640234/7947933)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Seekbar自定义样式及使用](https://blog.csdn.net/u013082948/article/details/55217680)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值