为了账号安全,请及时绑定邮箱和手机立即绑定

自定义双向滑动SeekBar

标签:
Android

自定义控件是进阶高级必须掌握的知识点。自定义控件可以做到系统自带的控件做不到的效果。学习自定义控件也可以加深对View的理解。之后会写一系列博客,从图形绘制到控件的交互一步步分析如何做出自定义控件。这里先放一个例子,

源码在我的github:https://github.com/SingleShadowBlade/MySeekBar
欢迎star
这个是自定义控件,有详细注释
public class DoubleSeekBar extends View {

private int preX,preY;private int currentX,currentX2,currentY;//进度条左右位置private Bitmap bitmap1,bitmap2,bitmap3;private Canvas canvas;private Paint paint;private int mScollBarWidth,mScollBarHeight;  //控件宽度=滑动条宽度+滑动块宽度private int thumbTop,thunbBootom;//滑块顶部与底部高private int offset;//控件的偏移量private int progressLow,progressHigh;private OnSeekBarChangeListener mBarChangeListener;public DoubleSeekBar(Context context, AttributeSet attrs) {    super(context, attrs);
    paint=new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(Color.RED);
    paint.setStrokeWidth(20);
    bitmap1= BitmapFactory.decodeResource(getResources(),R.mipmap.back);
    bitmap2= BitmapFactory.decodeResource(getResources(),R.mipmap.red);
    bitmap3= BitmapFactory.decodeResource(getResources(),R.mipmap.thumb);
}//默认执行,计算view的宽高,在onDraw()之前protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = measureWidth(widthMeasureSpec);    int height = measureHeight(heightMeasureSpec);
    mScollBarWidth = width-offset;
    mScollBarHeight=20;
    currentX=offset;
    currentX2=width-offset;
    offset=20;
    thumbTop=40;
    thunbBootom=100;
    progressLow =0;
    progressHigh=100;
    setMeasuredDimension(width, height);
}private int measureWidth(int measureSpec) {    int specMode = MeasureSpec.getMode(measureSpec);    int specSize = MeasureSpec.getSize(measureSpec);    // 声明一个临时变量来存储计算出的测量值int resultWidth = 0;
    //wrap_contentif (specMode == MeasureSpec.AT_MOST) {
    }    //fill_parent或者精确值else if (specMode == MeasureSpec.EXACTLY) {
    }    return specSize;
}private int measureHeight(int measureSpec) {    int specMode = MeasureSpec.getMode(measureSpec);    int specSize = MeasureSpec.getSize(measureSpec);    int defaultHeight = 100;    //wrap_contentif (specMode == MeasureSpec.AT_MOST) {
    }    //fill_parent或者精确值else if (specMode == MeasureSpec.EXACTLY) {
       // defaultHeight = specSize-getPaddingLeft()-getPaddingRight();defaultHeight = specSize;
    }    return defaultHeight;
}//处理控件位置//    @Override//    public void layout(int l, int t, int r, int b) {//        super.layout(l, t, r, b);//    }    //处理手势@Overridepublic boolean onTouchEvent(MotionEvent event) {    int x= (int) event.getX();    switch (event.getAction()){        case MotionEvent.ACTION_DOWN:
            preX=x;            break;        case MotionEvent.ACTION_MOVE:           if(preX>mScollBarWidth/2){               if(x>mScollBarWidth){
                   currentX2=mScollBarWidth;
               }else{
                   currentX2=x;
               }               //右滑块进度progressHigh=(currentX2)*100/mScollBarWidth;

//// Log.e("tag","currentX2"+currentX2);// Log.e("tag","mScollBarWidth"+mScollBarWidth);// Log.e("tag","progressHigh"+progressHigh);}else {

               if(x<offset){
                   currentX=offset;
               }else{
                   currentX=x;
               }               //左滑块进度progressLow = (currentX-offset)*100/mScollBarWidth;

// Log.e("tag","currentX"+currentX);// Log.e("tag","mScollBarWidth"+mScollBarWidth);// Log.e("tag","progressLow"+progressLow);}

            if(mBarChangeListener!=null){
                mBarChangeListener.onProgressChanged(this,progressLow,progressHigh);
            }            break;        case MotionEvent.ACTION_UP:
            invalidate();            break;
    }    return true;
}@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //绘制背景Rect rectBack=new Rect(offset+getPaddingLeft(),0,mScollBarWidth-getPaddingRight(),mScollBarHeight);
    canvas.drawBitmap(bitmap1,null,rectBack,paint);    //绘制前景Rect rectRed=new Rect(currentX+getPaddingLeft(),0,currentX2-getPaddingRight(),mScollBarHeight);
    canvas.drawBitmap(bitmap2,null,rectRed,paint);    //绘制左滑块Rect rect1=new Rect(currentX-offset+getPaddingLeft(),thumbTop,currentX+offset+getPaddingLeft(),thunbBootom);
    canvas.drawBitmap(bitmap3,null,rect1,paint);    //绘制右滑块、getPaddingRight()设置paddingRight,其他同理Rect rect2=new Rect(currentX2-offset-getPaddingRight(),thumbTop,currentX2+offset-getPaddingRight(),thunbBootom);
    canvas.drawBitmap(bitmap3,null,rect2,paint);

    invalidate();
}public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener) {    this.mBarChangeListener = mListener;
}//回调函数,在滑动时实时调用,改变输入框的值public interface OnSeekBarChangeListener {
    //滑动前public void onProgressBefore();
    //滑动时public void onProgressChanged(DoubleSeekBar seekBar, int progressLow,
                                  int progressHigh);    //滑动后public void onProgressAfter();}

}
使用方法:
<com.gjl.myseekbar.DoubleSeekBarandroid:id="@+id/dsb"android:layout_width="300dp"android:layout_height="50dp"/>
MainActivity
public class MainActivity extends AppCompatActivity implements DoubleSeekBar.OnSeekBarChangeListener {

private DoubleSeekBar dsb;private TextView tv_low,tv_high;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    dsb = (DoubleSeekBar) findViewById(R.id.dsb);
    dsb.setOnSeekBarChangeListener(this);
    tv_low= (TextView) findViewById(R.id.tv_low);
    tv_high= (TextView) findViewById(R.id.tv_high);
}@Overridepublic void onProgressBefore() {

}@Overridepublic void onProgressChanged(DoubleSeekBar seekBar, int progressLow, int progressHigh) {
    Log.e("tag","progressLow"+progressLow);
    Log.e("tag","progressHigh"+progressHigh);
    tv_low.setText(""+progressLow);
    tv_high.setText(""+progressHigh);
}@Overridepublic void onProgressAfter() {

}

}

原文链接:http://www.apkbus.com/blog-820900-61769.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消