Android自定义SeekBar,带开始值结束值和Thumb上方滑动的Text

之前根据网友的博文写了一个Demo(点击打开链接)但是这个Demo用到attr,layout color,还有其他的类,给使用者造成很多麻烦,我想,这样的自定义控件为啥不用一个类来完成呢,这样直接复制过来就能用,于是我彻底的封装了这个自定义的SeekBar,做到了一个类完成所有功能,而且代码量也不多。效果图:


    原理,其实我不是自定义SeekBar,我是自定义了一个RelativeLayout,里面放了三个TextView和一个SeekBar,用代码控制他们的位置,实现动态显示值。

    首先,向自定义的RelativeLayout用代码添加子控件,这样就不用XML来布局了

private void addChildens() {
        textView = new ProgressTextView(mContext);
        textView.setId(View.generateViewId());
        LayoutParams lpTextView = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);
        textView.setLayoutParams(lpTextView);
        addView(textView);

        mSeekBar = new SeekBar(mContext);
        mSeekBar.setId(View.generateViewId());
        mSeekBar.setMax(seekBarMax);
        mSeekBar.setMinimumHeight(12);
        if (thumDrawable > 0) {
            mSeekBar.setThumb(ContextCompat.getDrawable(mContext, thumDrawable));
        }
        if (seekBarDrawable > 0) {
            mSeekBar.setBackgroundResource(seekBarDrawable);
        }
        mSeekBar.setPadding(0, 0, 0, 0);
        mSeekBar.setThumbOffset(0);
        LayoutParams lpSeekBar = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lpSeekBar.addRule(RelativeLayout.BELOW, textView.getId());
        mSeekBar.setLayoutParams(lpSeekBar);
        addView(mSeekBar);

        mTvStart = new TextView(mContext);
        LayoutParams lpStart = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lpStart.addRule(ALIGN_PARENT_LEFT);
        lpStart.addRule(RelativeLayout.BELOW, mSeekBar.getId());
        mTvStart.setLayoutParams(lpStart);
        addView(mTvStart);

        mTvEnd = new TextView(mContext);
        LayoutParams lpEnd = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lpEnd.addRule(ALIGN_PARENT_RIGHT);
        lpEnd.addRule(RelativeLayout.BELOW, mSeekBar.getId());
        mTvEnd.setLayoutParams(lpEnd);
        addView(mTvEnd);
    }
    然后就是自定义的一个浮标并显示SeekBar的值:

class ProgressTextView extends View {
        private int mHeight;
        private int mWidth;
        private double mOneProgressWidth;
        private int mCurProgress = 0;
        private String mProgressText = "";
        private Paint mPaint;
        private float mThumbOffset;
        private int mTextSize = 12;
        private float thumWidth;

        private String mTextColor = "#303F9F";//default color of column

        public ProgressTextView(Context context) {
            super(context);
            initObserver();
        }

        @RequiresApi(api = Build.VERSION_CODES.M)
        public ProgressTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            if (null != context && attrs != null) {
                mThumbOffset = thumWidth / 2;
            }
            initObserver();
        }

        private void initObserver() {
            ViewTreeObserver vto = getViewTreeObserver();
            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

                @Override
                public boolean onPreDraw() {
                    mHeight = getMeasuredHeight();
                    mWidth = getMeasuredWidth();
                    initPaint();
                    initData();
                    return true;
                }
            });
        }

        private void initPaint() {
            mPaint = new Paint();
            mPaint.setTextSize(mTextSize);
            mPaint.setTextAlign(Paint.Align.CENTER);
            mPaint.setColor(Color.parseColor(mTextColor));
        }

        private void initData() {
            mOneProgressWidth = (double) (mWidth - 2 * mThumbOffset) / (seekBarMax);
        }

        public void setTextSize(int mTextSize) {
            this.mTextSize = mTextSize;
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            initPaint();
            drawText(canvas);
            super.onDraw(canvas);
        }

        //设置字体居中显示
        private void drawText(Canvas canvas) {
            float x = (float) (mCurProgress * mOneProgressWidth);
            float textWidth = mPaint.measureText(mProgressText);
            float textOffset = textWidth / 2;
            if (x + textOffset > mWidth - mThumbOffset) {//超过view的右边
                float exWidth = x + textOffset - (mWidth - mThumbOffset);
                x -= exWidth;//避免超过右边
            }
            if (x + mThumbOffset < textOffset) {//超过左边
                float exWidth = textOffset - (x + mThumbOffset);
                x += exWidth;//避免超过左边
            }
            canvas.translate(mThumbOffset, 0);
            canvas.drawText(mProgressText, x, mHeight, mPaint);
        }

        //设置显示的进度位置和字符串
        public void setProgress(int progress, String showText) {
            mCurProgress = progress;
            mProgressText = showText;
            invalidate();
        }
    }
我还写了监听器和各种setter,保证这个自定义View的可操作性

Demo源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,可以通过自定义SeekBar实现数字滑动功能。首先,在布局文件中定义自定义SeekBar的样式,可以使用ProgressBar来实现。如下所示: ``` <ProgressBar android:id="@+id/customSeekBar" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:progressDrawable="@drawable/custom_seekbar_progress" android:thumb="@drawable/custom_seekbar_thumb" /> ``` 在drawable文件夹下创建custom_seekbar_progress.xml和custom_seekbar_thumb.xml来定义SeekBar的背景和滑样式。在custom_seekbar_progress.xml中,可以使用shape和gradient标签来定义进度条的背景样式。在custom_seekbar_thumb.xml中,可以使用shape标签来定义滑的样式。 接下来,在Activity或Fragment中找到SeekBar的实例,并设置OnSeekBarChangeListener监听器。在监听器中,通过getProgress方法获取SeekBar的进度,并根据需要进行相应的处理。例如,可以在TextView中显示SeekBar的进度,如下所示: ``` SeekBar customSeekBar = findViewById(R.id.customSeekBar); final TextView progressTextView = findViewById(R.id.progressTextView); customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { progressTextView.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // 当开始滑动SeekBar时执行的操作 } @Override public void onStopTrackingTouch(SeekBar seekBar) { // 当结束滑动SeekBar时执行的操作 } }); ``` 通过设置OnSeekBarChangeListener监听器,可以在SeekBar滑动时实时更新进度,并进行相应的处理操作。根据自己的需求,可以在onProgressChanged、onStartTrackingTouch和onStopTrackingTouch方法中添加自定义的逻辑。 以上就是使用自定义SeekBar实现数字滑动的简单方法。可以根据自己的需求进行进一步的定制和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值