android Seekbar双滑块滑动
来源:互联网 发布:mac系统怎么重装win10 编辑:程序博客网 时间:2024/06/06 00:07
虽然是转载,但我也做了一些修改
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.math.BigDecimal;
import com.zjcpo.mobileapp.R;
publicclassSeekBarPressureextendsView{
privatestaticfinalString TAG="SeekBarPressure";
privatestaticfinalint CLICK_ON_LOW=1;//点击在前滑块上
privatestaticfinalint CLICK_ON_HIGH=2;//点击在后滑块上
privatestaticfinalint CLICK_IN_LOW_AREA=3;
privatestaticfinalint CLICK_IN_HIGH_AREA=4;
privatestaticfinalint CLICK_OUT_AREA=5;
privatestaticfinalint CLICK_INVAILD=0;
privatestaticfinalint[] STATE_NORMAL ={};
privatestaticfinalint[] STATE_PRESSED ={
android.R.attr.state_pressed, android.R.attr.state_window_focused,
};
privateDrawable hasScrollBarBg;//滑动条滑动后背景图
privateDrawable notScrollBarBg;//滑动条未滑动背景图
privateDrawable mThumbLow;//前滑块
privateDrawable mThumbHigh;//后滑块
privateint mScollBarWidth;//控件宽度=滑动条宽度+滑动块宽度
privateint mScollBarHeight;//滑动条高度
privateint mThumbWidth;//滑动块宽度
privateint mThumbHeight;//滑动块高度
privatedouble mOffsetLow=0;//前滑块中心坐标
privatedouble mOffsetHigh=0;//后滑块中心坐标
privateint mDistance=0;//总刻度是固定距离 两边各去掉半个滑块距离
privateint mThumbMarginTop=30;//滑动块顶部距离上边框距离,也就是距离字体顶部的距离
privateint mFlag= CLICK_INVAILD;
privateOnSeekBarChangeListener mBarChangeListener;
privatedouble defaultScreenLow=0;//默认前滑块位置百分比
privatedouble defaultScreenHigh=100;//默认后滑块位置百分比
privateboolean isEdit=false;//输入框是否正在输入
publicSeekBarPressure(Context context){
this(context,null);
}
publicSeekBarPressure(Context context,AttributeSet attrs){
this(context, attrs,0);
}
publicSeekBarPressure(Context context,AttributeSet attrs,int defStyle){
super(context, attrs, defStyle);
// this.setBackgroundColor(Color.BLACK);
Resources resources = getResources();
notScrollBarBg= resources.getDrawable(R.drawable.seekbarpressure_bg_progress);
hasScrollBarBg= resources.getDrawable(R.drawable.seekbarpressure_bg_normal);
mThumbLow= resources.getDrawable(R.drawable.seekbarpressure_thumb);
mThumbHigh= resources.getDrawable(R.drawable.seekbarpressure_thumb);
mThumbLow.setState(STATE_NORMAL);
mThumbHigh.setState(STATE_NORMAL);
mScollBarWidth= notScrollBarBg.getIntrinsicWidth();
mScollBarHeight= notScrollBarBg.getIntrinsicHeight();
mThumbWidth= mThumbLow.getIntrinsicWidth();
mThumbHeight= mThumbLow.getIntrinsicHeight();
}
//默认执行,计算view的宽高,在onDraw()之前
protectedvoid onMeasure(int widthMeasureSpec,int heightMeasureSpec){
int width = measureWidth(widthMeasureSpec);
// int height = measureHeight(heightMeasureSpec);
mScollBarWidth= width;
mOffsetHigh= width- mThumbWidth/2;
mOffsetLow= mThumbWidth/2;
mDistance= width- mThumbWidth;
mOffsetLow= formatDouble(defaultScreenLow/100*(mDistance))+ mThumbWidth/2;
mOffsetHigh= formatDouble(defaultScreenHigh/100*(mDistance))+ mThumbWidth/2;
setMeasuredDimension(width, mThumbHeight + mThumbMarginTop+2);
}
privateint measureWidth(int measureSpec){
int specMode =MeasureSpec.getMode(measureSpec);
int specSize =MeasureSpec.getSize(measureSpec);
//wrap_content
if(specMode==MeasureSpec.AT_MOST){
}
//fill_parent或者精确值
elseif(specMode==MeasureSpec.EXACTLY){
}
return specSize;
}
privateint measureHeight(int measureSpec){
int specMode =MeasureSpec.getMode(measureSpec);
int specSize =MeasureSpec.getSize(measureSpec);
int defaultHeight =100;
//wrap_content
if(specMode==MeasureSpec.AT_MOST){
}
//fill_parent或者精确值
elseif(specMode==MeasureSpec.EXACTLY){
defaultHeight= specSize;
}
return defaultHeight;
}
protectedvoid onLayout(boolean changed,int l,int t,int r,int b){
super.onLayout(changed, l, t, r, b);
}
protectedvoid onDraw(Canvas canvas){
super.onDraw(canvas);
Paint text_Paint =newPaint();
text_Paint.setTextAlign(Paint.Align.CENTER);
text_Paint.setColor(Color.RED);
text_Paint.setTextSize(20);
int aaa = mThumbMarginTop+ mThumbHeight/2- mScollBarHeight/2;
int bbb = aaa+ mScollBarHeight;
//白色,不会动
notScrollBarBg.setBounds(mThumbWidth/2, aaa, mScollBarWidth- mThumbWidth/2, bbb);
notScrollBarBg.draw(canvas);
//蓝色,中间部分会动
hasScrollBarBg.setBounds((int)mOffsetLow, aaa,(int)mOffsetHigh, bbb);
hasScrollBarBg.draw(canvas);
//前滑块
mThumbLow.setBounds((int)(mOffsetLow- mThumbWidth/2), mThumbMarginTop,(int)(mOffsetLow+ mThumbWidth/2), mThumbHeight + mThumbMarginTop);
mThumbLow.draw(canvas);
//后滑块
mThumbHigh.setBounds((int)(mOffsetHigh- mThumbWidth/2), mThumbMarginTop,(int)(mOffsetHigh+ mThumbWidth/2), mThumbHeight + mThumbMarginTop);
mThumbHigh.draw(canvas);
double progressLow = formatDouble((mOffsetLow- mThumbWidth/2)*100/ mDistance);
double progressHigh = formatDouble((mOffsetHigh- mThumbWidth/2)*100/ mDistance);
// Log.d(TAG, "onDraw-->mOffsetLow: " + mOffsetLow + " mOffsetHigh: " + mOffsetHigh + " progressLow: " + progressLow + " progressHigh: " + progressHigh);
canvas.drawText((int) progressLow +"",(int)mOffsetLow-2-2,15, text_Paint);
canvas.drawText((int) progressHigh +"",(int)mOffsetHigh-2,15, text_Paint);
if(mBarChangeListener!=null){
if(!isEdit){
mBarChangeListener.onProgressChanged(this, progressLow, progressHigh);
}
}
}
@Override
publicboolean onTouchEvent(MotionEvent e){
//按下
if(e.getAction()==MotionEvent.ACTION_DOWN){
if(mBarChangeListener!=null){
mBarChangeListener.onProgressBefore();
isEdit=false;
}
mFlag= getAreaFlag(e);
// Log.d(TAG, "e.getX: " + e.getX() + "mFlag: " + mFlag);
// Log.d("ACTION_DOWN", "------------------");
if(mFlag== CLICK_ON_LOW){
mThumbLow.setState(STATE_PRESSED);
}elseif(mFlag== CLICK_ON_HIGH){
mThumbHigh.setState(STATE_PRESSED);
}elseif(mFlag== CLICK_IN_LOW_AREA){
mThumbLow.setState(STATE_PRESSED);
//如果点击0-mThumbWidth/2坐标
if(e.getX()<0|| e.getX()<= mThumbWidth/2){
mOffsetLow= mThumbWidth/2;
}elseif(e.getX()> mScollBarWidth- mThumbWidth/2){
// mOffsetLow = mDistance - mDuration;
mOffsetLow= mThumbWidth/2+ mDistance;
}else{
mOffsetLow= formatDouble(e.getX());
// if (mOffsetHigh<= mOffsetLow) {
// mOffsetHigh = (mOffsetLow + mDuration <= mDistance) ? (mOffsetLow + mDuration)
// : mDistance;
// mOffsetLow = mOffsetHigh - mDuration;
// }
}
}elseif(mFlag== CLICK_IN_HIGH_AREA){
mThumbHigh.setState(STATE_PRESSED);
// if (e.getX() < mDuration) {
// mOffsetHigh = mDuration;
// mOffsetLow = mOffsetHigh - mDuration;
// } else if (e.getX() >= mScollBarWidth - mThumbWidth/2) {
// mOffsetHigh = mDistance + mThumbWidth/2;
if(e.getX()>= mScollBarWidth- mThumbWidth/2){
mOffsetHigh= mDistance+ mThumbWidth/2;
}else{
mOffsetHigh= formatDouble(e.getX());
// if (mOffsetHigh <= mOffsetLow) {
// mOffsetLow = (mOffsetHigh - mDuration >= 0) ? (mOffsetHigh - mDuration) : 0;
// mOffsetHigh = mOffsetLow + mDuration;
// }
}
}
//设置进度条
refresh();
//移动move
}elseif(e.getAction()==MotionEvent.ACTION_MOVE){
// Log.d("ACTION_MOVE", "------------------");
if(mFlag== CLICK_ON_LOW){
if(e.getX()<0|| e.getX()<= mThumbWidth/2){
mOffsetLow= mThumbWidth/2;
}elseif(e.getX()>= mScollBarWidth- mThumbWidth/2){
mOffsetLow= mThumbWidth/2+ mDistance;
mOffsetHigh= mOffsetLow;
}else{
mOffsetLow= formatDouble(e.getX());
if(mOffsetHigh- mOffsetLow<=0){
mOffsetHigh=(mOffsetLow<= mDistance+mThumbWidth/2)?(mOffsetLow):(mDistance+mThumbWidth/2);
}
}
}elseif(mFlag== CLICK_ON_HIGH){
if(e.getX()< mThumbWidth/2){
mOffsetHigh= mThumbWidth/2;
mOffsetLow= mThumbWidth/2;
}elseif(e.getX()> mScollBarWidth- mThumbWidth/2){
mOffsetHigh= mThumbWidth/2+ mDistance;
}else{
mOffsetHigh= formatDouble(e.getX());
if(mOffsetHigh- mOffsetLow<=0){
mOffsetLow=(mOffsetHigh>= mThumbWidth/2)?(mOffsetHigh): mThumbWidth/2;
}
}
}
//设置进度条
refresh();
//抬起
}elseif(e.getAction()==MotionEvent.ACTION_UP){
// Log.d("ACTION_UP", "------------------");
mThumbLow.setState(STATE_NORMAL);
mThumbHigh.setState(STATE_NORMAL);
if(mBarChangeListener!=null){
mBarChangeListener.onProgressAfter();
}
//这两个for循环 是用来自动对齐刻度的,注释后,就可以自由滑动到任意位置
// for (int i = 0; i < money.length; i++) {
// if(Math.abs(mOffsetLow-i* ((mScollBarWidth-mThumbWidth)/ (money.length-1)))<=(mScollBarWidth-mThumbWidth)/(money.length-1)/2){
// mprogressLow=i;
// mOffsetLow =i* ((mScollBarWidth-mThumbWidth)/(money.length-1));
// invalidate();
// break;
// }
// }
//
// for (int i = 0; i < money.length; i++) {
// if(Math.abs(mOffsetHigh-i* ((mScollBarWidth-mThumbWidth)/(money.length-1) ))<(mScollBarWidth-mThumbWidth)/(money.length-1)/2){
// mprogressHigh=i;
// mOffsetHigh =i* ((mScollBarWidth-mThumbWidth)/(money.length-1));
// invalidate();
// break;
// }
// }
}
returntrue;
}
publicint getAreaFlag(MotionEvent e){
int top = mThumbMarginTop;
int bottom = mThumbHeight+ mThumbMarginTop;
if(e.getY()>= top&& e.getY()<= bottom&& e.getX()>=(mOffsetLow- mThumbWidth/2)&& e.getX()<= mOffsetLow+ mThumbWidth/2){
return CLICK_ON_LOW;
}elseif(e.getY()>= top&& e.getY()<= bottom&& e.getX()>=(mOffsetHigh- mThumbWidth/2)&& e.getX()<=(mOffsetHigh+ mThumbWidth/2)){
return CLICK_ON_HIGH;
}elseif(e.getY()>= top
&& e.getY()<= bottom
&&((e.getX()>=0&& e.getX()<(mOffsetLow- mThumbWidth/2))||((e.getX()>(mOffsetLow+ mThumbWidth/2))
&& e.getX()<=((double) mOffsetHigh + mOffsetLow)/2))){
return CLICK_IN_LOW_AREA;
}elseif(e.getY()>= top
&& e.getY()<= bottom
&&(((e.getX()>((double) mOffsetHigh + mOffsetLow)/2)&& e.getX()<(mOffsetHigh- mThumbWidth/2))||(e
.getX()>(mOffsetHigh+ mThumbWidth/2)&& e.getX()<= mScollBarWidth))){
return CLICK_IN_HIGH_AREA;
}elseif(!(e.getX()>=0&& e.getX()<= mScollBarWidth&& e.getY()>= top&& e.getY()<= bottom)){
return CLICK_OUT_AREA;
}else{
return CLICK_INVAILD;
}
}
//更新滑块
privatevoid refresh(){
invalidate();
}
//设置前滑块的值
publicvoid setProgressLow(double progressLow){
this.defaultScreenLow= progressLow;
mOffsetLow= formatDouble(progressLow/100*(mDistance))+ mThumbWidth/2;
isEdit=true;
refresh();
}
//设置后滑块的值
publicvoid setProgressHigh(double progressHigh){
this.defaultScreenHigh= progressHigh;
mOffsetHigh= formatDouble(progressHigh/100*(mDistance))+ mThumbWidth/2;
isEdit=true;
refresh();
}
publicvoid setOnSeekBarChangeListener(OnSeekBarChangeListener mListener){
this.mBarChangeListener= mListener;
}
//回调函数,在滑动时实时调用,改变输入框的值
publicinterfaceOnSeekBarChangeListener{
//滑动前
publicvoid onProgressBefore();
//滑动时
publicvoid onProgressChanged(SeekBarPressure seekBar,double progressLow,
double progressHigh);
//滑动后
publicvoid onProgressAfter();
}
/* private int formatInt(double value) {
BigDecimal bd = new BigDecimal(value);
BigDecimal bd1 = bd.setScale(0, BigDecimal.ROUND_HALF_UP);
return bd1.intValue();
}*/
publicstaticdouble formatDouble(double pDouble){
BigDecimal bd =newBigDecimal(pDouble);
BigDecimal bd1 = bd.setScale(2,BigDecimal.ROUND_HALF_UP);
pDouble= bd1.doubleValue();
return pDouble;
}
}
2、布局调用 xxx.xml
<com.example.shuangseekbardemo.SeekBarPressure
android:id="@+id/seekBar_tg2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_toRightOf="@id/ni"/>
3、在Activity中实现XxxActivity.class
seekBarPressures = (SeekBarPressure) findViewById(R.id.seekBar_tg2); seekBarPressures.setOnSeekBarChangeListener(new SeekBarPressure.OnSeekBarChangeListener() { @Override public void onProgressBefore() { isScreen = true; } @Override public void onProgressChanged(SeekBarPressure seekBar, double progressLow, double progressHigh) { editTexts_min.setText((int) progressLow + ""); editTexts_max.setText((int) progressHigh + ""); } @Override public void onProgressAfter() { isScreen = false; } });
原文:http://lanaiver6291.blog.163.com/blog/static/177798310201531314
下载地址:http://download.csdn.net/detail/zhanghuaiwang/9912331
- android Seekbar双滑块滑动
- 【Android】SeekBar禁止滑动
- Android自定义SeekBar滑动条
- Android-SeekBar可滑动进度条
- Android 自定义双向滑动SeekBar
- Android SeekBar 拖动条 滑动条
- Android百度音乐滑动进度条SeekBar
- android 音乐播放器,带seekBar滑动
- Android—SeekBar(滑动条)
- Android seekbar 滑动时上方显示进度
- android SeekBar双滑块
- android SeekBar(带滑动块的进度条)的应用举例
- 从零开始学android<SeekBar滑动组件.二十二.>
- Android程序:使用SeekBar实现滑动进度条功能
- android TextView文字跟随seekBar滑动条滑块的位置移动
- android SeekBar自定义样式滑动条的使用
- Android Seekbar透明滑动球thumb 不透明的解决办法
- Android自定义SeekBar,滑动时弹出气泡指示器显示进度
- Eclipse 安装 SVN 插件的两种方法
- java中静态成员与非静态成员
- Android kotlin 详解(3)
- mysql保存数据提示:Out of range value for column错误
- 代码里不能写 ...... IN ()这种条件,如果参数>1000服务器就会报错,CPU占用会达到100%
- android Seekbar双滑块滑动
- 常见的加密算法
- JS 控制图片在浏览器上幻灯片式自动播放
- 浅谈分布式消息技术 Kafka
- Linux 下cut用法总结
- POJ
- 并发Queue一
- hibernate学习笔记(一)
- 多线程总结