带数字显示的自定义SeekBar

由于项目需要做个单向滑动SeekBar,而系统自带的SeekBar并没能提供滑块上面的数字,所以只能自定义了。

效果图如下:

MSeekBar

使用方法如下:

<com.whoisaa.mseekbar.MSeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="0"
    android:progressDrawable="@drawable/bg_seekbar_progress_drawable"
    android:thumb="@mipmap/icon_seekbar_thumb"
    app:textBackground="@mipmap/bg_seekbar_display2"
    app:textColor="@color/white"
    app:textOrientation="top"
    app:textSize="14sp"/>
  • SeekBar底部背景和进度背景
android:progressDrawable="@drawable/bg_seekbar_progress_drawable"
  • bg_seekbar_progress_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 底部背景 -->
    <item android:id="@android:id/background" android:height="15dp">
        <shape>
            <corners android:radius="10dp"/>
            <size android:height="15dp" />
            <solid android:color="#CBCBCB"/>
        </shape>
    </item>

    <!-- 进度背景 -->
    <item android:id="@android:id/progress" android:height="15dp">
        <clip>
            <shape>
                <corners android:radius="10dp"/>
                <size android:height="15dp" />
                <solid android:color="#0069B6"/>
            </shape>
        </clip>
    </item>

</layer-list>
  • 滑块图片
android:thumb="@mipmap/icon_seekbar_thumb"
  • 文字在滑块的顶部(top)或底部(bottom)
app:textOrientation="top"
  • 滑块顶部(底部)文字背景图片
app:textBackground="@mipmap/bg_seekbar_display2"
  • attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MSeekBar">
        <attr name="textSize" format="dimension" />
        <attr name="textColor" format="color" />
        <attr name="textBackground" format="reference" />
        <attr name="textOrientation" format="enum">
            <enum name="top" value="1" />
            <enum name="bottom" value="2" />
        </attr>
    </declare-styleable>
</resources>

MSeekBar源码

package com.whoisaa.mseekbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;


public class MSeekBar extends SeekBar {

    /**
     * SeekBar数值文字颜色
     */
    private int mTextColor;

    /**
     * SeekBar数值文字大小
     */
    private float mTextSize;

    /**
     * SeekBar数值文字内容
     */
    private String mText;

    /**
     * SeekBar数值文字背景
     */
    private Bitmap mBackgroundBitmap;

    /**
     * SeekBar数值文字背景宽高
     */
    private float mBgWidth, mBgHeight;

    /**
     * 画笔
     */
    private Paint mPaint;

    /**
     * SeekBar数值文字方向
     */
    private int mTextOrientation;

    /**
     * SeekBar数值文字宽度
     */
    private float mTextWidth;

    /**
     * SeekBar数值文字基线Y坐标
     */
    private float mTextBaseLineY;

    //文字方向
    private static final int ORIENTATION_TOP = 1;
    private static final int ORIENTATION_BOTTOM = 2;


    public MSeekBar(Context context) {
        this(context, null);
    }

    public MSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MSeekBar, defStyleAttr, 0);
        int count = ta.getIndexCount();
        for(int i = 0; i < count; i++) {
            int index = ta.getIndex(i);
            switch (index) {
                case R.styleable.MSeekBar_textColor:
                    mTextColor = ta.getColor(index, Color.WHITE);
                    break;

                case R.styleable.MSeekBar_textSize:
                    mTextSize = ta.getDimension(index, 15f);
                    break;

                case R.styleable.MSeekBar_textBackground:
                    //获取文字背景图片的宽高
                    int bgResId = ta.getResourceId(index, R.mipmap.bg_seekbar_display1);
                    mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), bgResId);
                    mBgWidth = mBackgroundBitmap.getWidth();
                    mBgHeight = mBackgroundBitmap.getHeight();
                    break;

                case R.styleable.MSeekBar_textOrientation:
                    mTextOrientation = ta.getInt(index, ORIENTATION_TOP);
                    break;
            }
        }
        ta.recycle();

        //设置画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);

        //设置文字显示方向
        if(mTextOrientation == ORIENTATION_TOP) {
            //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,顶部为数值背景图片高度加五的间隔
            setPadding((int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5, (int) Math.ceil(mBgWidth) / 2, 0);
        } else {
            //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,底部为数值背景图片高度加五的间隔
            setPadding((int) Math.ceil(mBgWidth) / 2, 0, (int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5);
        }
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        getTextLocation();
        Rect bgRect = getProgressDrawable().getBounds();
        //计算数值背景X坐标
        float bgX = bgRect.width() * getProgress() / getMax();
        //计算数值背景Y坐标
        float bgY = 0;
        if(mTextOrientation == ORIENTATION_BOTTOM) {
            bgY = mBgHeight + 10;
        }

        //计算数值文字X坐标
        float textX = bgX + (mBgWidth - mTextWidth) / 2;
        float textY = (float) (mTextBaseLineY + bgY + (0.16 * mBgHeight / 2) - 10);

        //绘制文字和背景
        canvas.drawBitmap(mBackgroundBitmap, bgX, bgY, mPaint);
        canvas.drawText(mText, textX, textY, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        invalidate();
        return super.onTouchEvent(event);
    }

    /**
     * 计算SeekBar数值文字的显示位置
     */
    private void getTextLocation() {
        Paint.FontMetrics fm = mPaint.getFontMetrics();
        mText = "¥" + getProgress();
        //测量文字宽度
        mTextWidth = mPaint.measureText(mText);
        //计算文字基线Y坐标
        mTextBaseLineY = mBgHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;
    }
}

在MainActivity中调用和普通SeekBar一样

package com.whoisaa.mseekbar;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.SeekBar;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {

    private TextView mTextView1, mTextView2;
    private MSeekBar mSeekBar1, mSeekBar2;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView1 = (TextView) findViewById(R.id.tv_main1);
        mTextView2 = (TextView) findViewById(R.id.tv_main2);
        mSeekBar1 = (MSeekBar) findViewById(R.id.sb_main1);
        mSeekBar2 = (MSeekBar) findViewById(R.id.sb_main2);
        mSeekBar1.setOnSeekBarChangeListener(this);
        mSeekBar2.setOnSeekBarChangeListener(this);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if(seekBar.equals(mSeekBar1)) {
            mTextView1.setText("滑块一当前值为" + progress);
        } else if(seekBar.equals(mSeekBar2)) {
            mTextView2.setText("滑块二当前值为" + progress);
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

去Github查看源码

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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实现数字滑动的简单方法。可以根据自己的需求进行进一步的定制和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值