自定义垂直拖动的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

时间: 2024-10-11 21:02:56

自定义垂直拖动的seekbar进度条的相关文章

控制SeekBar进度条来同时触发ProgressBar

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent

自定义View实现钟摆效果进度条PendulumView

在网上看到了一个IOS组件PendulumView,实现了钟摆的动画效果.由于原生的进度条确实是不好看,所以想可以自定义View实现这样的效果,以后也可以用于加载页面的进度条. 废话不多说,先上效果图 底部黑边是录制时不小心录上的,可以忽略. 既然是自定义View我们就按标准的流程来,第一步,自定义属性自定义属性 建立属性文件 在Android项目的res->values目录下新建一个attrs.xml文件,文件内容如下: [html] view plain copy <?xml versio

自定义View之绘制交替进度条

一.attrs.xml 这进度条交替,涉及到一些属性,例如:进度条的颜色和速度等,这些属性是View里面没有的,所以需要自定义. <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="firstColor" format="color" /> <attr name="secondColor" f

自定义VIew——漂亮的圆形进度条

package com.example.firstapp; import java.text.DecimalFormat; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphic

自定义带有渐变颜色的进度条

在项目中用到了渐变颜色的进度条 样式如下: 1.设置背景色颜色 2.设置边框圆角大小 3.设置渐变的颜色个数 4.设置渐变颜色 5.设置显示,隐藏进度条动画条纹 Demo地址:https://github.com/xqG/gradual-ProgressBar

TangIDE开发技巧之自定义资源加载窗口进度条

用TangIDE开发游戏的朋友都知道,你可以像编辑普通的窗口一样编辑资源加载窗口,加入各种丰富的控件和动画效果,但是进度条相对比较单调,现在进度条默认是两张小图,加载时按九宫格来绘制,如果你不想用九宫格,想用两张水平长图替代它们,那么你可以在资源加载窗口的onSystemInit事件下,重写进度条控件(UIProgressBar)的drawBgImageH方法(这里的H表示水平形状的进度条),改变图片的绘制方式. var me = this; var win = this.getWindow()

(三)自定义不断转圈的圆形进度条的实现(主要在网络访问时候,提示用户在获取数据)

1.要实现的转圈进度条的效果图如下所示: 2.view_loading.xml中代码如下所示: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/loading_view_layout" androi

Android自定义可长按 可点击不可拖动的SeekBar

项目中遇见一个奇怪的需求 就是SeekBar不可点击 ,可长按 和拉着拖拽点拖动.一开始想着很简单嘛.屏蔽吊点击事件,SeekBar自带长按事件,差不多就搞定了,然而是我太天真啊,SeekBar自带的长按监听是无效的.我通过网上查寻资料 有一些简单的方法实现不可单击的 有实现长按的,然后我根据这些方式自己写了一个 满足需求的自定义控件.现在依次说下吧. 1. 不可点击的SeekBar 这个可以直接通过seekBar的监听 修改SeekBar的进度 让其达到显示的效果. 可以重写SeekBar 设

Android自定义圆角矩形进度条2

效果图: 或 方法讲解: (1)invalidate()方法 invalidate()是用来刷新View的,必须是在UI线程中进行工作.比如在修改某个view的显示时, 调用invalidate()才能看到重新绘制的界面.invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉.一般在自定义控件中会用到这个方法. (2)RectF方法的应用 RectF是用来绘画矩形的方法. RectF(left,top,right,bottom),四个参数的含义分别是父控件距离矩形左上右下