Android自定义双向滑动控件

这篇文章主要为大家详细介绍了Android自定义双向滑动控件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义双向滑动控件的具体代码,供大家参考,具体内容如下

先看一下效果图

1.SeekBarPressure工具类

public class SeekBarPressure extends View {     private static final String TAG = "SeekBarPressure";     private static final int CLICK_ON_LOW = 1;      //点击在前滑块上     private static final int CLICK_ON_HIGH = 2;     //点击在后滑块上     private static final int CLICK_IN_LOW_AREA = 3;     private static final int CLICK_IN_HIGH_AREA = 4;     private static final int CLICK_OUT_AREA = 5;     private static final int CLICK_INVAILD = 0;     /*      * private static final int[] PRESSED_STATE_SET = {      * android.R.attr.state_focused, android.R.attr.state_pressed,      * android.R.attr.state_selected, android.R.attr.state_window_focused, };      */     private static final int[] STATE_NORMAL = {};     private static final int[] STATE_PRESSED = {             android.R.attr.state_pressed, android.R.attr.state_window_focused,     };     private Drawable hasScrollBarBg;        //滑动条滑动后背景图     private Drawable notScrollBarBg;        //滑动条未滑动背景图     private Drawable mThumbLow;         //前滑块     private Drawable mThumbHigh;        //后滑块       private int mScollBarWidth;     //控件宽度=滑动条宽度+滑动块宽度     private int mScollBarHeight;    //滑动条高度       private int mThumbWidth;        //滑动块宽度     private int mThumbHeight;       //滑动块高度       private double mOffsetLow = 0;     //前滑块中心坐标     private double mOffsetHigh = 0;    //后滑块中心坐标     private int mDistance = 0;      //总刻度是固定距离 两边各去掉半个滑块距离       private int mThumbMarginTop = 30;   //滑动块顶部距离上边框距离,也就是距离字体顶部的距离       private int mFlag = CLICK_INVAILD;     private OnSeekBarChangeListener mBarChangeListener;         private double defaultScreenLow = 0;    //默认前滑块位置百分比     private double defaultScreenHigh = 100;  //默认后滑块位置百分比       private boolean isEdit = false;     //输入框是否正在输入       public SeekBarPressure(Context context) {         this(context, null);     }       public SeekBarPressure(Context context, AttributeSet attrs) {         this(context, attrs, 0);     }       public SeekBarPressure(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle); //        this.setBackgroundColor(Color.BLACK);           Resources resources = getResources();         notScrollBarBg = resources.getDrawable(R.color.red);         hasScrollBarBg = resources.getDrawable(R.color.blue);         mThumbLow = resources.getDrawable(R.drawable.blue);         mThumbHigh = resources.getDrawable(R.drawable.red);           mThumbLow.setState(STATE_NORMAL);         mThumbHigh.setState(STATE_NORMAL);           mScollBarWidth = notScrollBarBg.getIntrinsicWidth();         mScollBarHeight = notScrollBarBg.getIntrinsicHeight();           mThumbWidth = mThumbLow.getIntrinsicWidth();         mThumbHeight = mThumbLow.getIntrinsicHeight();       }       //默认执行,计算view的宽高,在onDraw()之前     protected void 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);     }         private int measureWidth(int measureSpec) {         int specMode = MeasureSpec.getMode(measureSpec);         int specSize = MeasureSpec.getSize(measureSpec);         //wrap_content         if (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_content         if (specMode == MeasureSpec.AT_MOST) {         }         //fill_parent或者精确值         else if (specMode == MeasureSpec.EXACTLY) {             defaultHeight = specSize;         }           return defaultHeight;     }       protected void onLayout(boolean changed, int l, int t, int r, int b) {         super.onLayout(changed, l, t, r, b);     }       protected void onDraw(Canvas canvas) {         super.onDraw(canvas);   //        Paint text_Paint = new Paint(); //        text_Paint.setTextAlign(Paint.Align.CENTER); //        text_Paint.setColor(Color.RED); //        text_Paint.setTextSize(50);           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     public boolean 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);             } else if (mFlag == CLICK_ON_HIGH) {                 mThumbHigh.setState(STATE_PRESSED);             } else if (mFlag == CLICK_IN_LOW_AREA) {                 mThumbLow.setState(STATE_PRESSED);                 //如果点击0-mThumbWidth/2坐标                 if (e.getX() <0 || e.getx() <=mThumbWidth/2) {   moffsetlow=mThumbWidth/2; } else if (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; //                    }                 }             } else if (mFlag == CLICK_IN_HIGH_AREA) {                 mThumbHigh.setState(STATE_PRESSED); //                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         } else if (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; } else if (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);                     }                 }             } else if (mFlag == CLICK_ON_HIGH) {                 if (e.getX() < mThumbWidth/2) {                     mOffsetHigh = mThumbWidth/2;                     mOffsetLow = mThumbWidth/2;                 } else if (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();             //抬起         } else if (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 = top && e.getY() <= bottom && e.getX() >= (mOffsetLow - mThumbWidth / 2) && e.getX() <= mOffsetLow + mThumbWidth / 2) {             return CLICK_ON_LOW;         } else if (e.getY() >= top && e.getY() <= bottom && e.getX() >= (mOffsetHigh - mThumbWidth / 2) && e.getX() <= (mOffsetHigh + mThumbWidth / 2)) {             return CLICK_ON_HIGH;         } else if (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;         } else if (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;         } else if (!(e.getX() >= 0 && e.getX() <= mScollBarWidth && e.getY() >= top && e.getY() <= bottom)) {             return CLICK_OUT_AREA;         } else {             return CLICK_INVAILD;         }     }       //更新滑块     private void refresh() {         invalidate();     }       //设置前滑块的值     public void setProgressLow(double  progressLow) {         this.defaultScreenLow = progressLow;         mOffsetLow = formatDouble(progressLow / 100 * (mDistance ))+ mThumbWidth / 2;         isEdit = true;         refresh();     }       //设置后滑块的值     public void setProgressHigh(double  progressHigh) {         this.defaultScreenHigh = progressHigh;         mOffsetHigh = formatDouble(progressHigh / 100 * (mDistance)) + mThumbWidth / 2;         isEdit = true;         refresh();     }       public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener) {         this.mBarChangeListener = mListener;     }       //回调函数,在滑动时实时调用,改变输入框的值     public interface OnSeekBarChangeListener {         //滑动前         public void onProgressBefore();           //滑动时         public void onProgressChanged(SeekBarPressure seekBar, double progressLow,                                       double progressHigh);           //滑动后         public void onProgressAfter();     }   /*    private int formatInt(double value) {         BigDecimal bd = new BigDecimal(value);         BigDecimal bd1 = bd.setScale(0, BigDecimal.ROUND_HALF_UP);         return bd1.intValue();     }*/       public static double formatDouble(double pDouble) {         BigDecimal bd = new BigDecimal(pDouble);         BigDecimal bd1 = bd.setScale(2, BigDecimal.ROUND_HALF_UP);         pDouble = bd1.doubleValue();         return pDouble;     }   }

2.activity_main.xml 布局

                       

3.MainActivity

public class MainActivity extends AppCompatActivity {       private boolean isScreen;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);           //id         final SeekBarPressure seekBarPressures = findViewById(R.id.seekBar_tg2);         final TextView editTexts_min = findViewById(R.id.editTexts_min);         final TextView editTexts_max = findViewById(R.id.editTexts_max);           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 + "");                   //获取SharedPreferences对象                 SharedPreferences sharedPre=getSharedPreferences("config", MODE_PRIVATE);                   //获取Editor对象                 SharedPreferences.Editor edit = sharedPre.edit();                 edit.clear();                   //设置参数                 edit.putString("progressHigh", String.valueOf(progressHigh));                 edit.putString("progressLow", String.valueOf(progressLow));                   //提交                 edit.commit();               }               @Override             public void onProgressAfter() {                 isScreen = false;             }         });             //取值         SharedPreferences sharedPre=getSharedPreferences("config",MODE_PRIVATE);           String progressHighs = sharedPre.getString("progressHigh", "");         String progressLows = sharedPre.getString("progressLow", "");           if (progressHighs.length()!=0){             seekBarPressures.setProgressHigh(Double.parseDouble(progressHighs));             seekBarPressures.setProgressLow(Double.parseDouble(progressLows));               editTexts_max.setText(progressHighs);             editTexts_min.setText(progressLows);         }else {             seekBarPressures.setProgressLow(30);             seekBarPressures.setProgressHigh(70);               editTexts_min.setText("最小值:"+30);             editTexts_max.setText("最大值:"+70);         }     } }

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

以上就是Android自定义双向滑动控件的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动