Seekbar thumb center

来源:互联网 发布:暂无数据提示图 编辑:程序博客网 时间:2024/04/29 18:08

最近项目中用到了一个可拖动的进度条,并且在当前进度的末端的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
原创粉丝点击