垂直进度条VerticalSeekBar
来源:互联网 发布:seo百分百秒收录 编辑:程序博客网 时间:2024/04/29 11:55
水平的进度条见多了,总会想见个垂直的进度条开开眼。今天咱就试试。
要说原理也简单,就是把宽高倒置,其他的理论上都不需要动,发现问题再补补也就行了。
官方提供
官方是提供了垂直进度条的例子源码的,位置在android-sdk-windows\sources\android-23\com\android\example\rscamera\VerticalSeekBar.java,当然首先你SDK中要有Android 6.0。
VerticalSeekBar.java
/** * Class to create a vertical slider */public class VerticalSeekBar extends SeekBar { public VerticalSeekBar(Context context) { super(context); } public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } protected void onDraw(Canvas c) { c.rotate(-90); c.translate(-getHeight(), 0); super.onDraw(c); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: setProgress(getMax() - (int) (getMax() * event.getY() / getHeight())); onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_CANCEL: break; } return true; }}
继承SeekBar是最简单快捷的,不用重写太多方法,只需要把
onMeasure
onSizeChanged
onDraw
三个方法作一些改动;但也有一些问题,比如只能响应onPregress方法,为了让他能响应onStartTrackingTouch和onStopTrackingTouch方法,只好再加一些代码,于是有了改进版。
稍作改进
VerticalSeekBar2.java
public class VerticalSeekBar2 extends SeekBar { private Drawable mThumb; private OnSeekBarChangeListener mOnSeekBarChangeListener; public VerticalSeekBar2(Context context) { super(context); } public VerticalSeekBar2(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalSeekBar2(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) { mOnSeekBarChangeListener = l; } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } protected void onDraw(Canvas c) { c.rotate(-90); c.translate(-getHeight(), 0); super.onDraw(c); } void onProgressRefresh(float scale, boolean fromUser) { Drawable thumb = mThumb; if (thumb != null) { setThumbPos(getHeight(), thumb, scale, Integer.MIN_VALUE); invalidate(); } if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser); } } private void setThumbPos(int w, Drawable thumb, float scale, int gap) { int available = w - getPaddingLeft() - getPaddingRight(); int thumbWidth = thumb.getIntrinsicWidth(); int thumbHeight = thumb.getIntrinsicHeight(); int thumbPos = (int) (scale * available + 0.5f); // int topBound = getWidth() / 2 - thumbHeight / 2 - getPaddingTop(); // int bottomBound = getWidth() / 2 + thumbHeight / 2 - getPaddingTop(); int topBound, bottomBound; if (gap == Integer.MIN_VALUE) { Rect oldBounds = thumb.getBounds(); topBound = oldBounds.top; bottomBound = oldBounds.bottom; } else { topBound = gap; bottomBound = gap + thumbHeight; } thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound); } public void setThumb(Drawable thumb) { mThumb = thumb; super.setThumb(thumb); } void onStartTrackingTouch() { if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStartTrackingTouch(this); } } void onStopTrackingTouch() { if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStopTrackingTouch(this); } } private void attemptClaimDrag() { if (getParent() != null) { getParent().requestDisallowInterceptTouchEvent(true); } } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setPressed(true); onStartTrackingTouch(); break; case MotionEvent.ACTION_MOVE: attemptClaimDrag(); setProgress(getMax() - (int) (getMax() * event.getY() / getHeight())); break; case MotionEvent.ACTION_UP: onStopTrackingTouch(); setPressed(false); break; case MotionEvent.ACTION_CANCEL: onStopTrackingTouch(); setPressed(false); break; } return true; }
为了响应另外两个不知道怎么就被onPregress抛弃的方法,添了这么多代码真是罪过,不过都是从SeekBar的父类AbsSeekBar中仿写过来的,逻辑稍作改动就能用。
对比测试
上图。
左边是官方例子中的,右边是改进过的。
请自行测试~~
测试源码
0 0
- 垂直进度条VerticalSeekBar
- Android---垂直的进度条(VerticalSeekBar、VerticalProgressBar)
- 安卓原生垂直进度条剥离打包(VerticalSeekBar)
- 垂直的SeekBar:VerticalSeekBar
- 垂直的VerticalSeekBar
- android 垂直 SeekBar 源代码(VerticalSeekBar)
- android 垂直 SeekBar 源代码(VerticalSeekBar)
- VerticalSeekBar 垂直拖动条的实现
- 竖直(垂直)VerticalSeekBar和VerticalProgressBar
- 自定义垂直进度条
- 垂直进度条的实现
- 实现垂直进度条
- 如何实现垂直进度条
- 设置垂直进度条
- Android:VerticalSeekBar
- VerticalProgressBar 垂直进度条的实现
- android 垂直的进度条实现
- android 垂直方向进度条progressbar
- SpringSecurity从数据库中获取url资源地址和对应的权限信息
- CodeForces 589F 究竟能吃多久?
- Avro:RPC例子
- unsigned和signed的转换
- 编码规范(华为)
- 垂直进度条VerticalSeekBar
- shell开发入门,第一个shell
- FragmentPagerAdapter刷新数据原理分析与解决
- CSU-ACM2016暑假集训训练1-二分搜索-C
- 《代码大全》读书笔记及随想(day03)
- Socket —— 通过多线程简单模拟了聊天室
- JQuery Ajax提交form工具类
- ---简单的mvc模式理解案例
- 配置手工高级TFS2015特性