android 垂直 SeekBar 源代码(VerticalSeekBar)

这几天需要用到垂直的 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);

这个接口主要是为外部提供监听。多说无益,大家看源代码明白一点。


  1. import java.lang.reflect.Field;  
  2. import java.lang.reflect.Method;  
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Rect;  
  6. import android.graphics.drawable.Drawable;  
  7. import android.util.AttributeSet;  
  8. import android.util.Log;  
  9. import android.view.MotionEvent;  
  10. import android.view.View;  
  11. import android.widget.AbsSeekBar;  
  12. import android.widget.SeekBar;  
  13.   
  14.   
  15. public class VerticalSeekBar extends AbsSeekBar {   
  16.   
  17.     private int height = -1;  
  18.     private int width = -1;  
  19.     public interface OnSeekBarChangeListener  
  20.     {  
  21.         public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);  
  22.         public void onStartTrackingTouch(VerticalSeekBar vBar);  
  23.         public void onStopTrackingTouch(VerticalSeekBar vBar);  
  24.     }  
  25.       
  26.     private OnSeekBarChangeListener mOnSeekBarChangeListener;  
  27.     public VerticalSeekBar(Context context)  
  28.     {  
  29.         this(context, null);  
  30.     }  
  31.       
  32.     public VerticalSeekBar(Context context, AttributeSet attrs)  
  33.     {  
  34.         this(context, attrs, android.R.attr.seekBarStyle);  
  35.     }  
  36.       
  37.     public VerticalSeekBar(Context context, AttributeSet attrs, int defstyle)  
  38.     {  
  39.         super(context, attrs, defstyle);  
  40.     }  
  41.       
  42.     public void setOnSeekBarChangeListener(OnSeekBarChangeListener l)  
  43.     {  
  44.         mOnSeekBarChangeListener = l;  
  45.     }  
  46.       
  47.     void onStartTrackingTouch()  
  48.     {  
  49.         if (mOnSeekBarChangeListener != null)  
  50.         {  
  51.             mOnSeekBarChangeListener.onStartTrackingTouch(this);  
  52.         }  
  53.     }  
  54.       
  55.     void onStopTrackingTouch()  
  56.     {  
  57.         if (mOnSeekBarChangeListener != null)  
  58.         {  
  59.             mOnSeekBarChangeListener.onStopTrackingTouch(this);  
  60.         }  
  61.     }  
  62.       
  63.     void onProgressRefresh(float scale, boolean fromUser)  
  64.     {  
  65.         Drawable thumb = null;  
  66.         try  
  67.         {  
  68.             Field mThumb_f = this.getClass().getSuperclass().getDeclaredField("mThumb");  
  69.             mThumb_f.setAccessible(true);  
  70.             thumb = (Drawable)mThumb_f.get(this);  
  71.         }  
  72.         catch (Exception e)  
  73.         {  
  74.             e.printStackTrace();  
  75.         }  
  76.   
  77.         setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);  
  78.           
  79.         invalidate();  
  80.           
  81.         if (mOnSeekBarChangeListener != null) {  
  82.             mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);  
  83.         }  
  84.     }  
  85.       
  86.     private void setThumbPos(int w, Drawable thumb, float scale, int gap)  
  87.     {  
  88.         int available = 0;  
  89.         try  
  90.         {  
  91.   
  92.             int up = getPaddingTop();  
  93.             int bottom = getPaddingBottom();  
  94.               
  95.             available = getHeight() - up - bottom;  
  96.             int thumbWidth = thumb.getIntrinsicWidth();  
  97.             int thumbHeight = thumb.getIntrinsicHeight();  
  98.             available -= thumbWidth;  
  99.               
  100.             //The extra space for the thumb to move on the track   
  101.             available += getThumbOffset() * 2;  
  102.               
  103.             int thumbPos = (int) (scale * available);  
  104.   
  105.             int topBound, bottomBound;  
  106.             if (gap == Integer.MIN_VALUE) {  
  107.                 Rect oldBounds = thumb.getBounds();  
  108.                 topBound = oldBounds.top;  
  109.                 bottomBound = oldBounds.bottom;  
  110.             } else {  
  111.                 topBound = gap;  
  112.                 bottomBound = gap + thumbHeight;  
  113.             }  
  114.             // Canvas will be translated, so 0,0 is where we start drawing   
  115.             thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);      
  116.         }  
  117.         catch (Exception e)  
  118.         {  
  119.             e.printStackTrace();  
  120.         }  
  121.   
  122.     }  
  123.       
  124.      protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
  125.      {       
  126.          width = 30;  
  127.          height = View.MeasureSpec.getSize(heightMeasureSpec);  
  128.    
  129.          this.setMeasuredDimension(width, height);   
  130.      }   
  131.       
  132.     protected void onDraw(Canvas c)  
  133.     {  
  134.         c.rotate(-90);  
  135.         c.translate(-height,0);   
  136.         super.onDraw(c);  
  137.     }  
  138.       
  139.     protected void onSizeChanged(int w, int h, int oldw, int oldh)  
  140.     {       
  141.         super.onSizeChanged(h, w, oldw, oldh);   
  142.     }   
  143.       
  144.     @Override  
  145.     public boolean onTouchEvent(MotionEvent event)  
  146.     {  
  147.           
  148.         boolean mIsUserSeekable=true;  
  149.         try  
  150.         {  
  151.             Field mIsUserSeekable_f = this.getClass().getSuperclass().getDeclaredField("mIsUserSeekable");  
  152.             mIsUserSeekable_f.setAccessible(true);  
  153.   
  154.             mIsUserSeekable = mIsUserSeekable_f.getBoolean(this);  
  155.         }  
  156.         catch (Exception e1)  
  157.         {  
  158.             e1.printStackTrace();  
  159.         }  
  160.           
  161.         if (!mIsUserSeekable || !isEnabled()) {  
  162.             return false;  
  163.         }  
  164.           
  165.         switch (event.getAction()) {  
  166.             case MotionEvent.ACTION_DOWN:  
  167.                 setPressed(true);  
  168.                 onStartTrackingTouch();  
  169.                 trackTouchEvent(event);  
  170.                 break;  
  171.                   
  172.             case MotionEvent.ACTION_MOVE:  
  173.                 trackTouchEvent(event);  
  174.                 Method attemptClaimDrag;  
  175.                 try  
  176.                 {  
  177.                     attemptClaimDrag = this.getClass().getSuperclass().getDeclaredMethod("attemptClaimDrag");  
  178.                     attemptClaimDrag.setAccessible(true);  
  179.                     attemptClaimDrag.invoke(this);  
  180.                 }  
  181.                 catch (Exception e)  
  182.                 {  
  183.                     e.printStackTrace();  
  184.                 }  
  185.                 break;  
  186.                   
  187.             case MotionEvent.ACTION_UP:  
  188.                 trackTouchEvent(event);  
  189.                 onStopTrackingTouch();  
  190.                 setPressed(false);  
  191.                 // ProgressBar doesn't know to repaint the thumb drawable   
  192.                 // in its inactive state when the touch stops (because the   
  193.                 // value has not apparently changed)   
  194.                 invalidate();  
  195.                 break;  
  196.                   
  197.             case MotionEvent.ACTION_CANCEL:  
  198.                 onStopTrackingTouch();  
  199.                 setPressed(false);  
  200.                 invalidate(); // see above explanation   
  201.                 break;  
  202.         }  
  203.         return true;  
  204.     }  
  205.       
  206.     protected void trackTouchEvent(MotionEvent event)  
  207.     {  
  208.           
  209.         final int height = getHeight();  
  210.         final int available = height - getPaddingLeft() - getPaddingRight();  
  211.         int y = (int)(height - event.getY());  
  212.         float scale;  
  213.         float progress = 0;  
  214.         if (y < getPaddingLeft()) {  
  215.             scale = 0.0f;  
  216.         } else if (y > height - getPaddingRight()) {  
  217.             scale = 1.0f;  
  218.         } else {  
  219.             scale = (float)(y - getPaddingLeft()) / (float)available;  
  220.             float mTouchProgressOffset = 0.0f;  
  221.             try  
  222.             {  
  223.                 Field mTouchProgressOffset_f = this.getClass().getSuperclass().getDeclaredField("mTouchProgressOffset");  
  224.                 mTouchProgressOffset_f.setAccessible(true);  
  225.                 mTouchProgressOffset = mTouchProgressOffset_f.getFloat(this);  
  226.             }  
  227.             catch(Exception e)  
  228.             {  
  229.                 e.printStackTrace();  
  230.             }  
  231.             progress = mTouchProgressOffset;  
  232.         }  
  233.           
  234.         final int max = getMax();  
  235.         progress += scale * max;  
  236.           
  237.         try  
  238.         {  
  239.             Method setProgress = this.getClass().getSuperclass().getSuperclass().getDeclaredMethod("setProgress"int.class,boolean.class);  
  240.             setProgress.setAccessible(true);  
  241.             setProgress.invoke(this, (int)progress, true);  
  242.         }  
  243.         catch(Exception e)  
  244.         {  
  245.             e.printStackTrace();  
  246.         }  
  247.     }  
  248. }  
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值