中山网站的建设,广州注册公司多少钱,交通运输网站建设的方案,出口外贸网站实现原理#xff1a;1、自定义View#xff0c;在onDraw(Canvas canvas)中#xff0c;画出2个Drawable滑动块#xff0c;2个Drawable滑动条#xff0c;2个Paint#xff08;text#xff09;2、监听onTouchEvent()事件#xff0c;修改滑块和滑动条的坐标#xff0c;调用i… 实现原理 1、自定义View在onDraw(Canvas canvas)中画出2个Drawable滑动块2个Drawable滑动条2个Painttext 2、监听onTouchEvent()事件修改滑块和滑动条的坐标调用invalidate()来更新界面 使用方法 1、自定义View SeekBarPressure.class package xxxxxxxxximport 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;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.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()之前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 mThumbMarginTop2);}private int measureWidth(int measureSpec) {int specMode MeasureSpec.getMode(measureSpec);int specSize MeasureSpec.getSize(measureSpec);//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;}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(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);}}}Overridepublic 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() 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} 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 mDistancemThumbWidth/2) ? (mOffsetLow) : (mDistancemThumbWidth/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 money.length; i) {
// if(Math.abs(mOffsetLow-i* ((mScollBarWidth-mThumbWidth)/ (money.length-1)))(mScollBarWidth-mThumbWidth)/(money.length-1)/2){
// mprogressLowi;
// 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){
// mprogressHighi;
// mOffsetHigh i* ((mScollBarWidth-mThumbWidth)/(money.length-1));
// invalidate();
// break;
// }
// }}return true;}public int 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;} 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、布局调用 xxx.xml com.xxx.SeekBarPressureandroid:idid/seekBar_tg2android:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_alignParentToptrueandroid:layout_marginBottom10dpandroid:layout_marginLeft10dpandroid:layout_marginRight10dp / 3、在Activity中实现XxxActivity.class seekBarPressures (SeekBarPressure) findViewById(R.id.seekBar_tg2);seekBarPressures.setOnSeekBarChangeListener(new SeekBarPressure.OnSeekBarChangeListener() {Overridepublic void onProgressBefore() {isScreen true;}Overridepublic void onProgressChanged(SeekBarPressure seekBar, double progressLow, double progressHigh) {editTexts_min.setText((int) progressLow );editTexts_max.setText((int) progressHigh );}Overridepublic void onProgressAfter() {isScreen false;}}); 注意seekBar的父容器必须LinearLayout别问我为什么我也不知道。反正如果是Rinearlayout的话滑动会不正常我曹了为这问题搞了整整3个小时