編輯:Android開發教程
android系統自帶的拖動條(seekbar)只有橫向,這裡分享一個垂直的seekbar。
原理很簡單:
(1)在測量控件大小(包括發現控件大小改變時)時,把寬度和高度互換
(2)在繪制時將畫布順時針旋轉90度,即將拖動條逆時針旋轉90度,為了保證從畫布的原點開始繪制需要將畫布上移視圖高度
(3)自定義觸摸事件,根據觸摸的相對位置來修改progress變量的值。
代碼分享如下(這個代碼是很久以前網上找的,老外寫的):
import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.view.ViewParent; import android.widget.SeekBar; /** * 豎向拖動條 */ public class VerticalSeekBar extends SeekBar { private boolean mIsDragging; private float mTouchDownY; private int mScaledTouchSlop; private boolean isInScrollingContainer = false; public boolean isInScrollingContainer() { return isInScrollingContainer; } public void setInScrollingContainer(boolean isInScrollingContainer) { this.isInScrollingContainer = isInScrollingContainer; } /** * On touch, this offset plus the scaled value from the position of the *URL:http://www.bianceng.cn/OS/extra/201609/50429.htm * touch will form the progress value. Usually 0. */ float mTouchProgressOffset; public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalSeekBar(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(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } @Override protected synchronized void onDraw(Canvas canvas) { canvas.rotate(90); canvas.translate(0, -getWidth()); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (isInScrollingContainer()) { mTouchDownY = event.getY(); } else { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); onSizeChanged(getWidth(), getHeight(), 0, 0); } break; case MotionEvent.ACTION_MOVE: if (mIsDragging) { trackTouchEvent(event); } else { final float y = event.getY(); if (Math.abs(y - mTouchDownY) > mScaledTouchSlop) { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); } } onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_UP: if (mIsDragging) { trackTouchEvent(event); onStopTrackingTouch(); setPressed(false); } else { // Touch up when we never crossed the touch slop threshold // should // be interpreted as a tap-seek to that location. onStartTrackingTouch(); trackTouchEvent(event); onStopTrackingTouch(); } onSizeChanged(getWidth(), getHeight(), 0, 0); // 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; } return true; } private void trackTouchEvent(MotionEvent event) { final int height = getHeight(); final int top = getPaddingTop(); final int bottom = getPaddingBottom(); final int available = height - top - bottom; int y = (int) event.getY(); float scale; float progress = 0; if (y > height - bottom) { scale = 0.0f; } else if (y < top) { scale = 1.0f; } else { scale = (float) (available - y + top) / (float) available; progress = mTouchProgressOffset; } final int max = getMax(); // progress += scale * max; progress = Math.round(max * (1 - scale) - progress); setProgress((int) progress); } /** * This is called when the user has started touching this widget. */ void onStartTrackingTouch() { mIsDragging = true; } /** * This is called when the user either releases his touch or the touch is * canceled. */ void onStopTrackingTouch() { mIsDragging = false; } private void attemptClaimDrag() { ViewParent p = getParent(); if (p != null) { p.requestDisallowInterceptTouchEvent(true); } } @Override public synchronized void setProgress(int progress) { super.setProgress(progress); onSizeChanged(getWidth(), getHeight(), 0, 0); } }
1、在Android4.0環境下編譯的actionbarsherlock、slidingmenu類庫,能不能在4.0以下的版本中使用相信很多人跟我一樣,都以為在低版本(如
bundle.putParcelable可以實現傳遞對象,但是這個對象的類必須實現Parcelable接口才能夠使用。下面是一個簡單的在Activity之間傳遞對象的例子
ionic第二坑——ionic 上拉菜單(ActionSheet)安卓樣式坑閒話不說,先上圖: 這是IOS上的顯示效果,代碼如下: HTML部分: 1 <bod
這個話題是繼續android安全問題(二) 程序鎖延伸的之前我已經展示了如何制作程序鎖。當打 開指定應用的時候,彈出一個密碼頁面。程序鎖的話題雖然是和安全相關,但是這應該