自定义垂直拖动的seekbar进度条
系统自定义的seekbar为横向拖动的样式,需要纵向的时则需要自己定义,网上很多说了重写系统SeekBar中onDraw()的方法,但是我使用的时候不知道为什么拖动条和点偏离了,不在一条直线上,好气。。。
然后用了另一篇中改进之后的自定义bar,效果才正常,下面贴出代码
1 import android.content.Context; 2 import android.graphics.Canvas; 3 import android.util.AttributeSet; 4 import android.view.MotionEvent; 5 import android.view.ViewConfiguration; 6 import android.view.ViewParent; 7 import android.widget.SeekBar; 8 9 10 11 public class VerticalSeekBar extends SeekBar { 12 private boolean mIsDragging; 13 private float mTouchDownY; 14 private int mScaledTouchSlop; 15 private boolean isInScrollingContainer = false; 16 17 public boolean isInScrollingContainer() { 18 return isInScrollingContainer; 19 } 20 21 public void setInScrollingContainer(boolean isInScrollingContainer) { 22 this.isInScrollingContainer = isInScrollingContainer; 23 } 24 25 /** 26 * On touch, this offset plus the scaled value from the position of the 27 * touch will form the progress value. Usually 0. 28 */ 29 float mTouchProgressOffset; 30 31 public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { 32 super(context, attrs, defStyle); 33 mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 34 35 } 36 37 public VerticalSeekBar(Context context, AttributeSet attrs) { 38 super(context, attrs); 39 } 40 41 public VerticalSeekBar(Context context) { 42 super(context); 43 } 44 45 @Override 46 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 47 super.onSizeChanged(h, w, oldh, oldw); 48 } 49 50 @Override 51 protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 52 super.onMeasure(heightMeasureSpec, widthMeasureSpec); 53 setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); 54 } 55 56 @Override 57 protected synchronized void onDraw(Canvas canvas) { 58 canvas.rotate(-90); 59 canvas.translate(-getHeight(), 0); 60 super.onDraw(canvas); 61 } 62 63 @Override 64 public boolean onTouchEvent(MotionEvent event) { 65 if (!isEnabled()) { 66 return false; 67 } 68 69 switch (event.getAction()) { 70 case MotionEvent.ACTION_DOWN: 71 if (isInScrollingContainer()) { 72 mTouchDownY = event.getY(); 73 } 74 else { 75 setPressed(true); 76 77 invalidate(); 78 onStartTrackingTouch(); 79 trackTouchEvent(event); 80 attemptClaimDrag(); 81 82 onSizeChanged(getWidth(), getHeight(), 0, 0); 83 } 84 break; 85 86 case MotionEvent.ACTION_MOVE: 87 if (mIsDragging) 88 { 89 trackTouchEvent(event); 90 91 } 92 else 93 { 94 final float y = event.getY(); 95 if (Math.abs(y - mTouchDownY) > mScaledTouchSlop) 96 { 97 setPressed(true); 98 99 invalidate(); 100 onStartTrackingTouch(); 101 trackTouchEvent(event); 102 attemptClaimDrag(); 103 104 } 105 } 106 onSizeChanged(getWidth(), getHeight(), 0, 0); 107 break; 108 109 case MotionEvent.ACTION_UP: 110 if (mIsDragging) 111 { 112 trackTouchEvent(event); 113 onStopTrackingTouch(); 114 setPressed(false); 115 116 } 117 else 118 { 119 // Touch up when we never crossed the touch slop threshold 120 // should 121 // be interpreted as a tap-seek to that location. 122 onStartTrackingTouch(); 123 trackTouchEvent(event); 124 onStopTrackingTouch(); 125 126 } 127 onSizeChanged(getWidth(), getHeight(), 0, 0); 128 // ProgressBar doesn't know to repaint the thumb drawable 129 // in its inactive state when the touch stops (because the 130 // value has not apparently changed) 131 invalidate(); 132 break; 133 } 134 return true; 135 136 } 137 138 private void trackTouchEvent(MotionEvent event) 139 { 140 final int height = getHeight(); 141 final int top = getPaddingTop(); 142 final int bottom = getPaddingBottom(); 143 final int available = height - top - bottom; 144 145 int y = (int) event.getY(); 146 147 float scale; 148 float progress = 0; 149 150 // 下面是最小值 151 if (y > height - bottom) 152 { 153 scale = 0.0f; 154 } 155 else if (y < top) 156 { 157 scale = 1.0f; 158 } 159 else 160 { 161 scale = (float) (available - y + top) / (float) available; 162 progress = mTouchProgressOffset; 163 } 164 165 final int max = getMax(); 166 progress += scale * max; 167 168 setProgress((int) progress); 169 170 } 171 172 /** 173 * This is called when the user has started touching this widget. 174 */ 175 void onStartTrackingTouch() 176 { 177 mIsDragging = true; 178 } 179 180 /** 181 * This is called when the user either releases his touch or the touch is 182 * canceled. 183 */ 184 void onStopTrackingTouch() 185 { 186 mIsDragging = false; 187 } 188 189 private void attemptClaimDrag() 190 { 191 ViewParent p = getParent(); 192 if (p != null) 193 { 194 p.requestDisallowInterceptTouchEvent(true); 195 } 196 } 197 198 @Override 199 public synchronized void setProgress(int progress) 200 { 201 202 super.setProgress(progress); 203 onSizeChanged(getWidth(), getHeight(), 0, 0); 204 205 } 206 }
代码取自:http://www.cnblogs.com/mengdd/archive/2013/04/08/3008482.html