当前位置: 移动技术网 > 移动技术>移动开发>Android > Android双向选择控件DoubleSeekBar使用详解

Android双向选择控件DoubleSeekBar使用详解

2020年08月27日  | 移动技术网移动技术  | 我要评论
本文实例为大家分享了android双向选择控件doubleseekbar的使用方法,供大家参考,具体内容如下先看效果图1.doubleslideseekbarpublic class doublesl

本文实例为大家分享了android双向选择控件doubleseekbar的使用方法,供大家参考,具体内容如下

先看效果图

1.doubleslideseekbar

public class doubleslideseekbar extends view {
 /**
 * 线条(进度条)的宽度
 */
 private int linewidth;
 /**
 * 线条(进度条)的长度
 */
 private int linelength = 400;
 /**
 * 字所在的高度 100$
 */
 private int textheight;
 /**
 * 游标 图片宽度
 */
 private int imagewidth;
 /**
 * 游标 图片高度
 */
 private int imageheight;
 /**
 * 是否有刻度线
 */
 private boolean hasrule;
 /**
 * 左边的游标是否在动
 */
 private boolean islowermoving;
 /**
 * 右边的游标是否在动
 */
 private boolean isuppermoving;
 /**
 * 字的大小 100$
 */
 private int textsize;
 /**
 * 字的颜色 100$
 */
 private int textcolor;
 /**
 * 两个游标内部 线(进度条)的颜色
 */
 private int incolor = color.blue;
 /**
 * 两个游标外部 线(进度条)的颜色
 */
 private int outcolor = color.blue;
 /**
 * 刻度的颜色
 */
 private int rulecolor = color.blue;
 /**
 * 刻度上边的字 的颜色
 */
 private int ruletextcolor = color.blue;
 /**
 * 左边图标的图片
 */
 private bitmap bitmaplow;
 /**
 * 右边图标 的图片
 */
 private bitmap bitmapbig;
 /**
 * 左边图标所在x轴的位置
 */
 private int slidelowx;
 /**
 * 右边图标所在x轴的位置
 */
 private int slidebigx;
 /**
 * 图标(游标) 高度
 */
 private int bitmapheight;
 /**
 * 图标(游标) 宽度
 */
 private int bitmapwidth;
 /**
 * 加一些padding 大小酌情考虑 为了我们的自定义view可以显示完整
 */
 private int paddingleft = 100;
 private int paddingright = 100;
 private int paddingtop = 50;
 private int paddingbottom = 10;
 /**
 * 线(进度条) 开始的位置
 */
 private int linestart = paddingleft;
 /**
 * 线的y轴位置
 */
 private int liney;
 /**
 * 线(进度条)的结束位置
 */
 private int lineend = linelength + paddingleft;
 /**
 * 选择器的最大值
 */
 private int bigvalue = 100;
 /**
 * 选择器的最小值
 */
 private int smallvalue = 0;
 /**
 * 选择器的当前最小值
 */
 private float smallrange;
 /**
 * 选择器的当前最大值
 */
 private float bigrange;
 /**
 * 单位 元
 */
 private string unit = " ";
 /**
 * 单位份数
 */
 private int equal = 20;
 /**
 * 刻度单位 $
 */
 private string ruleunit = " ";
 /**
 * 刻度上边文字的size
 */
 private int ruletextsize = 20;
 /**
 * 刻度线的高度
 */
 private int rulelineheight = 20;
 private paint linepaint;
 private paint bitmappaint;
 private paint textpaint;
 private paint paintrule;
 
 public doubleslideseekbar(context context) {
 this(context, null);
 }
 
 public doubleslideseekbar(context context, @nullable attributeset attrs) {
 this(context, attrs, 0);
 }
 
 public doubleslideseekbar(context context, @nullable attributeset attrs, int defstyleattr) {
 super(context, attrs, defstyleattr);
 typedarray typedarray = context.gettheme().obtainstyledattributes(attrs, r.styleable.doubleslideseekbar, defstyleattr, 0);
 int size = typedarray.getindexcount();
 for (int i = 0; i < size; i++) {
  int type = typedarray.getindex(i);
  switch (type) {
  case r.styleable.doubleslideseekbar_incolor:
   incolor = typedarray.getcolor(type, color.black);
   break;
  case r.styleable.doubleslideseekbar_lineheight:
   linewidth = (int) typedarray.getdimension(type, dip2px(getcontext(), 10));
   break;
  case r.styleable.doubleslideseekbar_outcolor:
   outcolor = typedarray.getcolor(type, color.yellow);
   break;
  case r.styleable.doubleslideseekbar_textcolor:
   textcolor = typedarray.getcolor(type, color.blue);
   break;
  case r.styleable.doubleslideseekbar_textsize:
   textsize = typedarray.getdimensionpixelsize(type, (int) typedvalue.applydimension(
    typedvalue.complex_unit_sp, 16, getresources().getdisplaymetrics()));
   break;
  case r.styleable.doubleslideseekbar_imagelow:
   bitmaplow = bitmapfactory.decoderesource(getresources(), typedarray.getresourceid(type, 0));
   break;
  case r.styleable.doubleslideseekbar_imagebig:
   bitmapbig = bitmapfactory.decoderesource(getresources(), typedarray.getresourceid(type, 0));
   break;
  case r.styleable.doubleslideseekbar_imageheight:
   imageheight = (int) typedarray.getdimension(type, dip2px(getcontext(), 20));
   break;
  case r.styleable.doubleslideseekbar_imagewidth:
   imagewidth = (int) typedarray.getdimension(type, dip2px(getcontext(), 20));
   break;
  case r.styleable.doubleslideseekbar_hasrule:
   hasrule = typedarray.getboolean(type, false);
   break;
  case r.styleable.doubleslideseekbar_rulecolor:
   rulecolor = typedarray.getcolor(type, color.blue);
   break;
  case r.styleable.doubleslideseekbar_ruletextcolor:
   ruletextcolor = typedarray.getcolor(type, color.blue);
   break;
  case r.styleable.doubleslideseekbar_unit:
   unit = typedarray.getstring(type);
   break;
  case r.styleable.doubleslideseekbar_equal:
   equal = typedarray.getint(type, 10);
   break;
  case r.styleable.doubleslideseekbar_ruleunit:
   ruleunit = typedarray.getstring(type);
   break;
  case r.styleable.doubleslideseekbar_ruletextsize:
   ruletextsize = typedarray.getdimensionpixelsize(type, (int) typedvalue.applydimension(
    typedvalue.complex_unit_sp, 16, getresources().getdisplaymetrics()));
   break;
  case r.styleable.doubleslideseekbar_rulelineheight:
   rulelineheight = (int) typedarray.getdimension(type, dip2px(getcontext(), 10));
   break;
  case r.styleable.doubleslideseekbar_bigvalue:
   bigvalue = typedarray.getinteger(type, 100);
   break;
  case r.styleable.doubleslideseekbar_smallvalue:
   smallvalue = typedarray.getinteger(type, 100);
   break;
 
 
  default:
   break;
  }
 }
 typedarray.recycle();
 init();
 }
 
 private void init() {
 /**游标的默认图*/
 if (bitmaplow == null) {
  bitmaplow = bitmapfactory.decoderesource(getresources(), r.mipmap.ic_launcher);
 }
 if (bitmapbig == null) {
  bitmapbig = bitmapfactory.decoderesource(getresources(), r.mipmap.ic_launcher);
 }
 /**游标图片的真实高度 之后通过缩放比例可以把图片设置成想要的大小*/
 bitmapheight = bitmaplow.getheight();
 bitmapwidth = bitmaplow.getwidth();
 // 设置想要的大小
 int newwidth = imagewidth;
 int newheight = imageheight;
 // 计算缩放比例
 float scalewidth = ((float) newwidth) / bitmapwidth;
 float scaleheight = ((float) newheight) / bitmapheight;
 matrix matrix = new matrix();
 matrix.postscale(scalewidth, scaleheight);
 /**缩放图片*/
 bitmaplow = bitmap.createbitmap(bitmaplow, 0, 0, bitmapwidth, bitmapheight, matrix, true);
 bitmapbig = bitmap.createbitmap(bitmapbig, 0, 0, bitmapwidth, bitmapheight, matrix, true);
 /**重新获取游标图片的宽高*/
 bitmapheight = bitmaplow.getheight();
 bitmapwidth = bitmaplow.getwidth();
 /**初始化两个游标的位置*/
 slidelowx = linestart;
 slidebigx = lineend;
 smallrange = smallvalue;
 bigrange = bigvalue;
 if (hasrule) {
  //有刻度时 paddingtop 要加上(text高度)和(刻度线高度加刻度线上边文字的高度和) 之间的最大值
  paddingtop = paddingtop + math.max(textsize, rulelineheight + ruletextsize);
 } else {
  //没有刻度时 paddingtop 加上 text的高度
  paddingtop = paddingtop + textsize;
 }
 }
 
 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
 int width = getmymeasurewidth(widthmeasurespec);
 int height = getmymeasureheight(heightmeasurespec);
 setmeasureddimension(width, height);
 }
 
 private int getmymeasureheight(int heightmeasurespec) {
 int mode = measurespec.getmode(heightmeasurespec);
 int size = measurespec.getsize(heightmeasurespec);
 if (mode == measurespec.exactly) {
  // matchparent 或者 固定大小 view最小应为 paddingbottom + paddingtop + bitmapheight + 10 否则显示不全
  size = math.max(size, paddingbottom + paddingtop + bitmapheight + 10);
 } else {
  //wrap content
  int height = paddingbottom + paddingtop + bitmapheight + 10;
  size = math.min(size, height);
 }
 return size;
 }
 
 private int getmymeasurewidth(int widthmeasurespec) {
 int mode = measurespec.getmode(widthmeasurespec);
 int size = measurespec.getsize(widthmeasurespec);
 if (mode == measurespec.exactly) {
 
  size = math.max(size, paddingleft + paddingright + bitmapwidth * 2);
 
 } else {
  //wrap content
  int width = paddingleft + paddingright + bitmapwidth * 2;
  size = math.min(size, width);
 }
 // match parent 或者 固定大小 此时可以获取线(进度条)的长度
 linelength = size - paddingleft - paddingright - bitmapwidth;
 //线(进度条)的结束位置
 lineend = linelength + paddingleft + bitmapwidth / 2;
 //线(进度条)的开始位置
 linestart = paddingleft + bitmapwidth / 2;
 //初始化 游标位置
 slidebigx = lineend;
 slidelowx = linestart;
 return size;
 }
 
 @override
 protected void ondraw(canvas canvas) {
 super.ondraw(canvas);
 // y轴 坐标
 liney = getheight() - paddingbottom - bitmapheight / 2;
 // 字所在高度 100$
 textheight = liney - bitmapheight / 2 - 10;
// //是否画刻度
// if (hasrule) {
//  drawrule(canvas);
// }
// if (linepaint == null) {
//  linepaint = new paint();
// }
 linepaint = new paint();
 //画内部线
 linepaint.setantialias(true);
 linepaint.setstrokewidth(linewidth);
 linepaint.setcolor(incolor);
 linepaint.setstrokecap(paint.cap.round);
 canvas.drawline(slidelowx, liney, slidebigx, liney, linepaint);
 linepaint.setcolor(outcolor);
 linepaint.setstrokecap(paint.cap.round);
 //画 外部线
 canvas.drawline(linestart, liney, slidelowx, liney, linepaint);
 canvas.drawline(slidebigx, liney, lineend, liney, linepaint);
 //画游标
 if (bitmappaint == null) {
  bitmappaint = new paint();
 }
 canvas.drawbitmap(bitmaplow, slidelowx - bitmapwidth / 2, liney - bitmapheight / 2, bitmappaint);
 canvas.drawbitmap(bitmapbig, slidebigx - bitmapwidth / 2, liney - bitmapheight / 2, bitmappaint);
 //画 游标上边的字
 if (textpaint == null) {
  textpaint = new paint();
 }
 textpaint.setcolor(textcolor);
 textpaint.settextsize(textsize);
 textpaint.setantialias(true);
 canvas.drawtext(string.format("%.0f" + unit, smallrange), slidelowx - bitmapwidth / 2, textheight, textpaint);
 canvas.drawtext(string.format("%.0f" + unit, bigrange), slidebigx - bitmapwidth / 2, textheight, textpaint);
 }
 
 @override
 public boolean ontouchevent(motionevent event) {
 //事件机制
 super.ontouchevent(event);
 float nowx = event.getx();
 float nowy = event.gety();
 switch (event.getaction()) {
  case motionevent.action_down:
  //按下 在线(进度条)范围上
  boolean righty = math.abs(nowy - liney) < bitmapheight / 2;
  //按下 在左边游标上
  boolean lowslide = math.abs(nowx - slidelowx) < bitmapwidth / 2;
  //按下 在右边游标上
  boolean bigslide = math.abs(nowx - slidebigx) < bitmapwidth / 2;
  if (righty && lowslide) {
   islowermoving = true;
  } else if (righty && bigslide) {
   isuppermoving = true;
   //点击了游标外部 的线上
  } else if (nowx >= linestart && nowx <= slidelowx - bitmapwidth / 2 && righty) {
   slidelowx = (int) nowx;
   updaterange();
   postinvalidate();
  } else if (nowx <= lineend && nowx >= slidebigx + bitmapwidth / 2 && righty) {
   slidebigx = (int) nowx;
   updaterange();
   postinvalidate();
  }
  break;
  case motionevent.action_move:
  //左边游标是运动状态
  if (islowermoving) {
   //当前 x坐标在线上 且在右边游标的左边
   if (nowx <= slidebigx - bitmapwidth && nowx >= linestart - bitmapwidth / 2) {
   slidelowx = (int) nowx;
   if (slidelowx < linestart) {
    slidelowx = linestart;
   }
   //更新进度
   updaterange();
   postinvalidate();
   }
 
  } else if (isuppermoving) {
   //当前 x坐标在线上 且在左边游标的右边
   if (nowx >= slidelowx + bitmapwidth && nowx <= lineend + bitmapwidth / 2) {
   slidebigx = (int) nowx;
   if (slidebigx > lineend) {
    slidebigx = lineend;
   }
   //更新进度
   updaterange();
   postinvalidate();
 
   }
  }
  break;
  //手指抬起
  case motionevent.action_up:
  isuppermoving = false;
  islowermoving = false;
  break;
  default:
  break;
 }
 
 return true;
 }
 
 private void updaterange() {
 //当前 左边游标数值
 smallrange = computrange(slidelowx);
 //当前 右边游标数值
 bigrange = computrange(slidebigx);
 //接口 实现值的传递
 if (onrangelistener != null) {
  onrangelistener.onrange(smallrange, bigrange);
 }
 }
 
 /**
 * 获取当前值
 */
 private float computrange(float range) {
 return (range - linestart) * (bigvalue - smallvalue) / linelength + smallvalue;
 }
 
 public int dip2px(context context, float dpvalue) {
 final float scale = context.getresources().getdisplaymetrics().density;
 return (int) (dpvalue * scale + 0.5f);
 }
 
// /**
// * 画刻度
// */
// protected void drawrule(canvas canvas) {
// if (paintrule == null) {
//  paintrule = new paint();
// }
// paintrule.setstrokewidth(1);
// paintrule.settextsize(ruletextsize);
// paintrule.settextalign(paint.align.center);
// paintrule.setantialias(true);
// //遍历 equal份,画刻度
// for (int i = smallvalue; i <= bigvalue; i += (bigvalue - smallvalue) / equal) {
//  float degx = linestart + i * linelength / (bigvalue - smallvalue);
//  int degy = liney - rulelineheight;
//  paintrule.setcolor(rulecolor);
//  canvas.drawline(degx, liney, degx, degy, paintrule);
//  paintrule.setcolor(ruletextcolor);
//  canvas.drawtext(string.valueof(i) + ruleunit, degx, degy, paintrule);
// }
// }
 
 /**
 * 写个接口 用来传递最大最小值
 */
 public interface onrangelistener {
 void onrange(float low, float big);
 }
 
 private onrangelistener onrangelistener;
 
 public void setonrangelistener(doubleslideseekbar.onrangelistener onrangelistener) {
 this.onrangelistener = onrangelistener;
 }
}

2.在values文件夹中创建attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <!--线(进度条)宽度-->
 <attr name="lineheight" format="dimension" />
 <!--字的大小 100元-->
 <attr name="textsize" format="dimension" />
 <!--字的颜色 100元-->
 <attr name="textcolor" format="color" />
 <!--两个游标内部 线(进度条)的颜色-->
 <attr name="incolor" format="color" />
 <!--两个游标外部 线(进度条)的颜色-->
 <attr name="outcolor" format="color" />
 <!--左边图标的图片-->
 <attr name="imagelow" format="reference"/>
 <!--右边图标 的图片-->
 <attr name="imagebig" format="reference"/>
 <!--游标 图片宽度-->
 <attr name="imagewidth" format="dimension" />
 <!--游标 图片高度-->
 <attr name="imageheight" format="dimension" />
 <!--是否有刻度线-->
 <attr name="hasrule" format="boolean" />
 <!--刻度的颜色-->
 <attr name="rulecolor" format="color" />
 <!--刻度上边的字 的颜色-->
 <attr name="ruletextcolor" format="color" />
 <!--单位 元-->
 <attr name="unit" format="string"/>
 <!--单位份数-->
 <attr name="equal" format="integer"/>
 <!--刻度单位 $-->
 <attr name="ruleunit" format="string"/>
 <!--刻度上边文字的size-->
 <attr name="ruletextsize" format="dimension" />
 <!--刻度线的高度-->
 <attr name="rulelineheight" format="dimension" />
 <!--选择器的最大值-->
 <attr name="bigvalue" format="integer"/>
 <!--选择器的最小值-->
 <attr name="smallvalue" format="integer"/>
 <declare-styleable name="doubleslideseekbar">
  <attr name="lineheight" />
  <attr name="textsize" />
  <attr name="textcolor" />
  <attr name="incolor" />
  <attr name="outcolor" />
  <attr name="imagelow"/>
  <attr name="imagebig"/>
  <attr name="imagewidth" />
  <attr name="imageheight" />
  <attr name="hasrule" />
  <attr name="rulecolor" />
  <attr name="ruletextcolor" />
  <attr name="unit" />
  <attr name="equal" />
  <attr name="ruleunit" />
  <attr name="ruletextsize" />
  <attr name="rulelineheight" />
  <attr name="bigvalue" />
  <attr name="smallvalue" />
 </declare-styleable>
</resources> 

3.activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 xmlns:custom="http://schemas.android.com/apk/res-auto"
 tools:context=".mainactivity"
 android:orientation="vertical">
 
 <com.xxx.xxx.doubleslideseekbar
  android:id="@+id/doubleslide_withrule"
  android:layout_margintop="20dp"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  custom:lineheight="6dp"
  custom:textsize="12sp"
  custom:textcolor="#0628e4"
  custom:incolor="#f10a0a"
  custom:outcolor="#af08e2"
  custom:imagewidth="20dp"
  custom:imageheight="20dp"
  custom:hasrule="true"
  custom:rulecolor="#0e0e0e"
  custom:ruletextcolor="#f74104"
  custom:equal="10"
  custom:ruletextsize="8sp"
  custom:rulelineheight="10dp"
  />
 <textview
  android:id="@+id/tv_min_rule"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="0"
  android:layout_margintop="10dp"></textview>
 <textview
  android:id="@+id/tv_max_rule"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="0"
  android:layout_margintop="10dp"></textview>
 
 
</linearlayout>

4.mainactivity

public class mainactivity extends appcompatactivity {
 
 private doubleslideseekbar mdoubleslidewithrule;
 private textview mtvminrule;
 private textview mtvmaxrule;
 
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  mdoubleslidewithrule = (doubleslideseekbar) findviewbyid(r.id.doubleslide_withrule);
  mtvminrule = (textview) findviewbyid(r.id.tv_min_rule);
  mtvmaxrule = (textview) findviewbyid(r.id.tv_max_rule);
  setlistener();
 }
 private void setlistener() {
 
  mdoubleslidewithrule.setonrangelistener(new doubleslideseekbar.onrangelistener() {
   @override
   public void onrange(float low, float big) {
    mtvminrule.settext("最小值" + string.format("%.0f" , low));
    mtvmaxrule.settext("最大值" + string.format("%.0f" , big));
   }
  });
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网