android 垂直 SeekBar 源代码(VerticalSeekBar)
搬家后的博客链接: IT客栈 www.itkezhan.org
这几天需要用到垂直的 seekbar 但是android 包下翻了一下。发现没有,只能自己修改源码。
主要是继承 AbsSeekBar 然后修改下面这些方法
onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用
setThumbPos() //这个方法是设置Thumb的位置
onDraw() //这个是负责画界面
onSizeChanged() //更新画布尺寸
onTouchEvent() //当触摸屏幕的时候被调用
trackTouchEvent() //当拖动滑动条的时候,这个被调用
还有就是添加一个接口这个接口是SeekBar 的一个内部接口 public interface OnSeekBarChangeListener
里面有三个方法:
public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);
public void onStartTrackingTouch(VerticalSeekBar vBar);
public void onStopTrackingTouch(VerticalSeekBar vBar);
这个接口主要是为外部提供监听。多说无益,大家看源代码明白一点。
import java.lang.reflect.Field;import java.lang.reflect.Method;import android.content.Context;import android.graphics.Canvas;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.AbsSeekBar;import android.widget.SeekBar;public class VerticalSeekBar extends AbsSeekBar { private int height = -1;private int width = -1;public interface OnSeekBarChangeListener{public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);public void onStartTrackingTouch(VerticalSeekBar vBar);public void onStopTrackingTouch(VerticalSeekBar vBar);}private OnSeekBarChangeListener mOnSeekBarChangeListener;public VerticalSeekBar(Context context){this(context, null);}public VerticalSeekBar(Context context, AttributeSet attrs){this(context, attrs, android.R.attr.seekBarStyle);}public VerticalSeekBar(Context context, AttributeSet attrs, int defstyle){super(context, attrs, defstyle);}public void setOnSeekBarChangeListener(OnSeekBarChangeListener l){mOnSeekBarChangeListener = l;}void onStartTrackingTouch(){if (mOnSeekBarChangeListener != null){mOnSeekBarChangeListener.onStartTrackingTouch(this);}}void onStopTrackingTouch(){if (mOnSeekBarChangeListener != null){mOnSeekBarChangeListener.onStopTrackingTouch(this);}}void onProgressRefresh(float scale, boolean fromUser){Drawable thumb = null;try{Field mThumb_f = this.getClass().getSuperclass().getDeclaredField("mThumb");mThumb_f.setAccessible(true);thumb = (Drawable)mThumb_f.get(this);}catch (Exception e){e.printStackTrace();}setThumbPos(getWidth(), 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 = 0;try{int up = getPaddingTop();int bottom = getPaddingBottom();available = getHeight() - up - bottom; int thumbWidth = thumb.getIntrinsicWidth(); int thumbHeight = thumb.getIntrinsicHeight(); available -= thumbWidth; //The extra space for the thumb to move on the track available += getThumbOffset() * 2; int thumbPos = (int) (scale * available); int topBound, bottomBound; if (gap == Integer.MIN_VALUE) { Rect oldBounds = thumb.getBounds(); topBound = oldBounds.top; bottomBound = oldBounds.bottom; } else { topBound = gap; bottomBound = gap + thumbHeight; } // Canvas will be translated, so 0,0 is where we start drawing thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);}catch (Exception e){e.printStackTrace();}} protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { width = 30; height = View.MeasureSpec.getSize(heightMeasureSpec); this.setMeasuredDimension(width, height); } protected void onDraw(Canvas c){c.rotate(-90);c.translate(-height,0); super.onDraw(c);}protected void onSizeChanged(int w, int h, int oldw, int oldh){ super.onSizeChanged(h, w, oldw, oldh); } @Override public boolean onTouchEvent(MotionEvent event) { boolean mIsUserSeekable=true;try{ Field mIsUserSeekable_f = this.getClass().getSuperclass().getDeclaredField("mIsUserSeekable"); mIsUserSeekable_f.setAccessible(true);mIsUserSeekable = mIsUserSeekable_f.getBoolean(this);}catch (Exception e1){e1.printStackTrace();} if (!mIsUserSeekable || !isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setPressed(true); onStartTrackingTouch(); trackTouchEvent(event); break; case MotionEvent.ACTION_MOVE: trackTouchEvent(event); Method attemptClaimDrag;try{attemptClaimDrag = this.getClass().getSuperclass().getDeclaredMethod("attemptClaimDrag");attemptClaimDrag.setAccessible(true); attemptClaimDrag.invoke(this);}catch (Exception e){e.printStackTrace();} break; case MotionEvent.ACTION_UP: trackTouchEvent(event); onStopTrackingTouch(); setPressed(false); // ProgressBar doesn't know to repaint the thumb drawable // in its inactive state when the touch stops (because the // value has not apparently changed) invalidate(); break; case MotionEvent.ACTION_CANCEL: onStopTrackingTouch(); setPressed(false); invalidate(); // see above explanation break; } return true; } protected void trackTouchEvent(MotionEvent event) { final int height = getHeight(); final int available = height - getPaddingLeft() - getPaddingRight(); int y = (int)(height - event.getY()); float scale; float progress = 0; if (y < getPaddingLeft()) { scale = 0.0f; } else if (y > height - getPaddingRight()) { scale = 1.0f; } else { scale = (float)(y - getPaddingLeft()) / (float)available; float mTouchProgressOffset = 0.0f; try { Field mTouchProgressOffset_f = this.getClass().getSuperclass().getDeclaredField("mTouchProgressOffset"); mTouchProgressOffset_f.setAccessible(true); mTouchProgressOffset = mTouchProgressOffset_f.getFloat(this); } catch(Exception e) { e.printStackTrace(); } progress = mTouchProgressOffset; } final int max = getMax(); progress += scale * max; try { Method setProgress = this.getClass().getSuperclass().getSuperclass().getDeclaredMethod("setProgress", int.class,boolean.class); setProgress.setAccessible(true); setProgress.invoke(this, (int)progress, true); } catch(Exception e) {e.printStackTrace(); } }}
一个运行的截图
转载请注明出处,祝新年快乐。
本文链接:
http://blog.csdn.net/failure01/article/details/8577675
参考文档链接:
http://www.eoeandroid.com/thread-430-1-1.html
http://blog.csdn.net/saintswordsman/article/details/5248233
更多相关文章
- Android(安卓)不得不知Tag的妙用
- Android中捕捉menu按键点击事件的方法
- 多个Activity跳转的小结
- Android绘制流程窗口启动流程分析(上)
- Android实现在列表List中显示半透明小窗体效果的控件用法详解
- Android(安卓)DownloadManager 的使用
- Android使用文件进行数据存储的方法
- Android包管理机制(三)PMS处理APK的安装
- android的手机任务管理器,关键功能实现方法总结