android Seekbar双滑块滑动

来源:互联网 发布:mac系统怎么重装win10 编辑:程序博客网 时间:2024/06/06 00:07

虽然是转载,但我也做了一些修改


使用方法
1、自定义View   SeekBarPressure.class
import android.content.Context;
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

原创粉丝点击