<Android>自定义竖向seekbar
2015-07-31 21:37
141 查看
自定义竖向的seekbar(顶部在上),开始以为只要将画布翻转就可以,后来发现动作的操作也需要重新定义,移动由X轴转到Y轴,需要进行的操作有两步:
1.翻转画布,先顺时针转动90度。再右移动width宽度。
2.将X轴进行的动作搬到Y轴上。
此外用到的一种较好的设计模式是:
留接口处理seekListener,在内部预留接口使得外部调用的方法,是一种比较常见的封装方式。
代码如下,参考网络
1.翻转画布,先顺时针转动90度。再右移动width宽度。
2.将X轴进行的动作搬到Y轴上。
此外用到的一种较好的设计模式是:
留接口处理seekListener,在内部预留接口使得外部调用的方法,是一种比较常见的封装方式。
代码如下,参考网络
public class VerticalSeekBar extends SeekBar { private boolean mIsDragging; private float mTouchDownY; private int mScaledTouchSlop; private boolean isInScrollingContainer = false; public interface OnSeekBarChangeListener { void onProgressChanged(VerticalSeekBar VerticalBar, int progress, boolean fromUser); void onStartTrackingTouch(VerticalSeekBar VerticalBar); void onStopTrackingTouch(VerticalSeekBar VerticalBar); } private OnSeekBarChangeListener mOnSeekBarChangeListener; public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) { mOnSeekBarChangeListener = l; } public boolean isInScrollingContainer() { return isInScrollingContainer; } public void setInScrollingContainer(boolean isInScrollingContainer) { this.isInScrollingContainer = isInScrollingContainer; } /** * On touch, this offset plus the scaled value from the position of the * touch will form the progress value. Usually 0. */ float mTouchProgressOffset; public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalSeekBar(Context context) { super(context); } @Override 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()); } @Override protected synchronized void onDraw(Canvas canvas) { canvas.rotate(90); canvas.translate(0, -getWidth()); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (isInScrollingContainer()) { mTouchDownY = event.getY(); } else { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); onSizeChanged(getWidth(), getHeight(), 0, 0); } break; case MotionEvent.ACTION_MOVE: if (mIsDragging) { trackTouchEvent(event); } else { final float y = event.getY(); if (Math.abs(y - mTouchDownY) > mScaledTouchSlop) { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); } } onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_UP: if (mIsDragging) { trackTouchEvent(event); onStopTrackingTouch(); setPressed(false); } else { // Touch up when we never crossed the touch slop threshold // should // be interpreted as a tap-seek to that location. onStartTrackingTouch(); trackTouchEvent(event); onStopTrackingTouch(); } onSizeChanged(getWidth(), getHeight(), 0, 0); invalidate(); break; } return true; } private void trackTouchEvent(MotionEvent event) { final int height = getHeight(); final int top = getPaddingTop(); final int bottom = getPaddingBottom(); final int available = height - top - bottom; int y = (int) event.getY(); float scale; float progress = 0; if (y > height - bottom) { scale = 0.0f; } else if (y < top) { scale = 1.0f; } else { scale = (float) (y) / (float) available; progress = mTouchProgressOffset; } final int max = getMax(); progress += scale * max; setProgress((int) progress); } /** * This is called when the user has started touching this widget. */ public void onStartTrackingTouch() { mIsDragging = true; if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStartTrackingTouch(this); } } /** * This is called when the user either releases his touch or the touch is * canceled. */ public void onStopTrackingTouch() { mIsDragging = false; if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStopTrackingTouch(this); } } private void attemptClaimDrag() { ViewParent p = getParent(); if (p != null) { p.requestDisallowInterceptTouchEvent(true); } } @Override public synchronized void setProgress(int progress) { super.setProgress(progress); onSizeChanged(getWidth(), getHeight(), 0, 0); if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), isPressed()); } } }
相关文章推荐
- Android -- 绑定服务
- android developers training 文档学习笔记(目录)
- 使用O-LLVM和NDK对Android应用进行混淆
- Android的四种监听事件处理方式
- Android开发——下载功能的逻辑和实现
- Android之——原生分享功能
- Android学习笔记-Activity
- android系统服务
- android debug
- android之Broadcast
- Android子线程更新主界面
- android 开发 drawerlayout出现退不回去的情况
- Android之——判断当前应用程序是否是用户程序
- Android之——实现应用卸载功能
- 谈谈Android(Activity)的理解
- Android学习笔记之事件分发机制(二)
- android broadcast基础学习
- Android第四十五期 - QQ空间发说说功能
- Android第四十五期 - QQ空间发说说功能
- Android侧滑抽屉效果实现