主要实现垂直的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); } }