主要實現垂直的ProgressBar以及反向增減progress value。
垂直的話,很多代碼都有,但是反向貌似沒有做過。
通過VerticalProgressBar.setCurrMode(int)即可設置方向。
原理很簡單,配合canvas的rotate和translate即可實現。
以下代碼僅供參考。
/** * Created by culm on 13-12-11. */ public class VerticalProgressBar extends ProgressBar { public static final int MODE_TOP=0x001; public static final int MODE_BOTTOM=0x002; private int curr_mode=MODE_BOTTOM; public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VerticalProgressBar(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalProgressBar(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(widthMeasureSpec, heightMeasureSpec); } @Override protected synchronized void onDraw(Canvas canvas) { switch (curr_mode) { case MODE_BOTTOM: canvas.rotate(-90); canvas.translate(-canvas.getHeight(), 0); super.onDraw(canvas); break; case MODE_TOP: canvas.rotate(90,canvas.getWidth(),0); canvas.translate(10,0); super.onDraw(canvas); break; } } public void setCurrMode(int mode) { curr_mode=mode; invalidate(); } }
還有一個是長按按鈕監聽連續事件的控件代碼。一並附上。這兩個主要用於實現以下圖片所需的效果
分成兩個progressbar。一個是正向增減,一個是反向增減。
長按升調降調響應增減。
通過設定setRepeatListener(RepeatListener listener,int mInterval)去監聽事件。第二個參數是用於監聽事件間隔。
由於extends Button,所以也可以監聽View.OnClickListener
代碼如下,同樣,僅供參考。
/** * Created by culm on 13-12-16. */ public class RepeatingButton extends Button { private long mStartTime; private int mRepeatCount; private RepeatListener mListener; private long mInterval = 500; public RepeatingButton(Context context) { this(context, null); } public RepeatingButton(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.imageButtonStyle); } public RepeatingButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setFocusable(true); setLongClickable(true); } public void setRepeatListener(RepeatListener l, long interval) { mListener = l; mInterval = interval; } @Override public boolean performLongClick() { mStartTime = SystemClock.elapsedRealtime(); mRepeatCount = 0; post(mRepeater); return true; } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { removeCallbacks(mRepeater); if (mStartTime != 0) { doRepeat(true); mStartTime = 0; } } return super.onTouchEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: super.onKeyDown(keyCode, event); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: removeCallbacks(mRepeater); if (mStartTime != 0) { doRepeat(true); mStartTime = 0; } } return super.onKeyUp(keyCode, event); } private Runnable mRepeater = new Runnable() { public void run() { doRepeat(false); if (isPressed()) { postDelayed(this, mInterval); } } }; private void doRepeat(boolean last) { long now = SystemClock.elapsedRealtime(); if (mListener != null) { mListener.onRepeat(this, now - mStartTime, last ? -1 : mRepeatCount++); } } public interface RepeatListener { void onRepeat(View v, long duration, int repeatcount); } }

