Android怎么自定义双向滑动控件
发表于:2024-11-20 作者:千家信息网编辑
千家信息网最后更新 2024年11月20日,这篇文章主要介绍"Android怎么自定义双向滑动控件"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Android怎么自定义双向滑动控件"文章能帮助大家解决问
千家信息网最后更新 2024年11月20日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() < 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 <= 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 < 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;// }// } } 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.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); } }}
关于"Android怎么自定义双向滑动控件"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。
控件
宽度
双向
位置
坐标
知识
输入
精确
刻度
对象
百分
百分比
背景
行业
进度
顶部
高度
更新
不同
实用
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
聂辉华 工业企业数据库
学软件开发挺好就是头有点凉
查询人类遗传力的数据库
plsql怎么装服务器上
思科服务器网卡管理
腾讯云服务器升级
用什么软件开发一款app
数据库资源池
浪潮服务器主机故障
依人网络安全绘画
软件开发必备工具箱
glean数据库
什么情况下不要服务器
faceit怎么连接到服务器
SQL数据库技术技巧
软件开发报价每日费用
创享物联网络技术服务部
网络安全基本属性是
软件开发的xml书籍
dns服务器会被攻击吗
读数据库的sh脚本
软件开发去哪家翰诺科技好
数据库建模开源工具
网络安全信息简称
网络安全应该学会什么
华硕服务器2008系统安装步骤
高中选修网络技术哪个学校好
网络技术维护难学吗
师生学习网络安全知识
广州荔枝网络技术上市了吗