標籤:lin tac 不能 action nts 滑動 初始化 text tar
原來朋友給過的一個 顯示時間的 範例,還能夠改動時間,可是要機子有root許可權才幹改動。
在這個時間錶盤的範例基礎上 改動改動 圖片。背景圖什麼的 就能夠達到自己想要的效果了。。
: http://download.csdn.net/detail/kongbaidepao/8090083
1個風車效果的範例
是依據手滑動的速度 轉動快慢的
代碼不多,直接粘過來
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RotatView rotatView=(RotatView)findViewById(R.id.myRotatView); rotatView.setRotatDrawableResource(R.drawable.cycle); }}
public class RotatView extends View { //原心座標x float o_x; float o_y; /** * 處理慣性的handler */ Handler handler; //handler處理訊息的間隔 int delayedTime = 20; /** * 訊息訊號,滾動的標識 */ static final int play = 0; /** * 訊息訊號,停止滾動的標識 */ static final int stop = 1; /** * 上次記錄的時間,計算一定時間所走過的弧度、計算速度. */ double currentTime = 0; /** * 圖片的寬度 */ int width; /** * 圖片的高度 */ int height; /** * view的真實寬度與高度:由於是旋轉。所以這個view是正方形,它的值是圖片的對角線長度 */ double maxwidth; /** * 旋轉的圖片 */ Bitmap rotatBitmap; public RotatView(Context context, AttributeSet attrs) { super(context, attrs); init(); } /** * 初始化handler與速度計算機 */ private void init() { vRecord = new VRecord(); handler = new Handler() { @Override public void handleMessage(Message msg) { double detaTime = System.currentTimeMillis() - currentTime; switch (msg.what) { case play: { if (isClockWise) { speed = speed - a * detaTime; if (speed <= 0) { return; } else { handler.sendEmptyMessageDelayed(play, delayedTime); } } else { speed = speed + a * detaTime; if (speed >= 0) { return; } else { handler.sendEmptyMessageDelayed(play, delayedTime); } } addDegree((float)(speed * detaTime + (a * detaTime * detaTime) / 2)); // if (a < a_max) { // a = (float)(a + a_add*detaTime); // System.out.println("a:"+a); // } currentTime = System.currentTimeMillis(); invalidate(); break; } case stop: { speed = 0; handler.removeMessages(play); } } super.handleMessage(msg); } }; // 預設是有一張圖片的 initSize(); } public void setRotatBitmap(Bitmap bitmap) { rotatBitmap = bitmap; initSize(); postInvalidate(); } public void setRotatDrawableResource(int id) { BitmapDrawable drawable = (BitmapDrawable)getContext().getResources().getDrawable(id); setRotatDrawable(drawable); } public void setRotatDrawable(BitmapDrawable drawable) { rotatBitmap = drawable.getBitmap(); initSize(); postInvalidate(); } private void initSize() { if (rotatBitmap == null) { // throw new NoBitMapError("Error,No bitmap in RotatView!"); return; } width = rotatBitmap.getWidth(); height = rotatBitmap.getHeight(); maxwidth = Math.sqrt(width * width + height * height); o_x = o_y = (float)(maxwidth / 2);//確定圓心座標 } /** * 通過此方法來控制旋轉度數,假設超過360,讓它求餘,防止,該值過大造成越界 * * @param added */ private void addDegree(float added) { deta_degree += added; if (deta_degree > 360 || deta_degree < -360) { deta_degree = deta_degree % 360; } } @Override protected void onDraw(Canvas canvas) { Matrix matrix = new Matrix(); // 設定轉軸位置 matrix.setTranslate((float)width / 2, (float)height / 2); // 開始轉 matrix.preRotate(deta_degree); // 轉軸還原 matrix.preTranslate(-(float)width / 2, -(float)height / 2); // 將位置送到view的中心 matrix.postTranslate((float)(maxwidth - width) / 2, (float)(maxwidth - height) / 2); canvas.drawBitmap(rotatBitmap, matrix,paint); super.onDraw(canvas); } Paint paint=new Paint(); @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 它的寬高不是圖片的寬高,而是以寬高為直角的矩形的對角線的長度 setMeasuredDimension((int)maxwidth, (int)maxwidth); } /** * 手指觸屏的初始x的座標 */ float down_x; /** * 手指觸屏的初始y的座標 */ float down_y; /** * 移動時的x的座標 */ float target_x; /** * 移動時的y的座標 */ float target_y; /** * 放手時的x的座標 */ float up_x; /** * 放手時的y的座標 */ float up_y; /** * 當前的弧度(以該 view 的中心為圓點) */ float current_degree; /** * 放手時的弧度(以該 view 的中心為圓點) */ float up_degree; /** * 當前圓盤所轉的弧度(以該 view 的中心為圓點) */ float deta_degree; /** * 最後一次手勢滑過的時間 */ double lastMoveTime = 0; /** * 最小加速度(當手指放手是) */ public static final float a_min = 0.001f; /** * 加速度增量 */ public static final float a_add = 0.001f; /** * 加速度 */ float a = a_min; /** * 最大加速度(當手指按住時) */ public static final float a_max = a_min * 5; /** * 旋轉速度(度/毫秒) */ double speed = 0; /** * 速度計算機 */ VRecord vRecord; /** * 是否為順時針旋轉 */ boolean isClockWise; @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (rotatBitmap == null) { throw new NoBitMapError("Error,No bitmap in RotatView!"); } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { down_x = event.getX(); down_y = event.getY(); current_degree = detaDegree(o_x, o_y, down_x, down_y); vRecord.reset(); // handler.sendEmptyMessage(stop); a = a_max; break; } case MotionEvent.ACTION_MOVE: { down_x = target_x = event.getX(); down_y = target_y = event.getY(); float degree = detaDegree(o_x, o_y, target_x, target_y); // 滑過的弧度增量 float dete = degree - current_degree; // 假設小於-90度說明 它跨周了,須要特殊處理350->17, if (dete < -270) { dete = dete + 360; // 假設大於90度說明 它跨周了,須要特殊處理-350->-17, } else if (dete > 270) { dete = dete - 360; } lastMoveTime = System.currentTimeMillis(); vRecord.add(dete, lastMoveTime); addDegree(dete); current_degree = degree; postInvalidate(); break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: { a = a_min; double lastupTime = System.currentTimeMillis(); double detaTime = lastupTime - lastMoveTime; up_x = event.getX(); up_y = event.getY(); up_degree = detaDegree(o_x, o_y, up_x, up_y); // 放手時的速度 speed = speed + vRecord.getSpeed(); if (speed > 0) { speed = Math.min(VRecord.max_speed, speed); } else { speed = Math.max(-VRecord.max_speed, speed); }// System.out.println("speed:" + speed); if (speed > 0) { isClockWise = true; // v = 1; } else { isClockWise = false; // v = -1; } currentTime = System.currentTimeMillis(); handler.sendEmptyMessage(0); break; } } return true; } /** * 計算以(src_x,src_y)為座標圓點,建立直角體系,求出(target_x,target_y)座標與x軸的夾角 * 主要是利用反正切函數的知識求出夾角 * * @param src_x * @param src_y * @param target_x * @param target_y * @return */ float detaDegree(float src_x, float src_y, float target_x, float target_y) { float detaX = target_x - src_x; float detaY = target_y - src_y; double d; if (detaX != 0) { float tan = Math.abs(detaY / detaX); if (detaX > 0) { if (detaY >= 0) { d = Math.atan(tan); } else { d = 2 * Math.PI - Math.atan(tan); } } else { if (detaY >= 0) { d = Math.PI - Math.atan(tan); } else { d = Math.PI + Math.atan(tan); } } } else { if (detaY > 0) { d = Math.PI / 2; } else { d = -Math.PI / 2; } } return (float)((d * 180) / Math.PI); } /** * 一個異常。用來推斷是否有rotatbitmap * * @author sun.shine */ static class NoBitMapError extends RuntimeException { /** * */ private static final long serialVersionUID = 1L; public NoBitMapError(String detailMessage) { super(detailMessage); } } /** * 速度計算機 原來是將近期的 弧度增量和時間點記錄下來,然後<br> * 通過增量除以總時間求出平均值做為它的即時手勢滑過的速度 * * @author sun.shine */ static class VRecord { /** * 數組中的有效數字 */ int addCount; /** * 最大能裝的資料空間 */ public static final int length = 15; /** * 二維數組,1.儲存弧度增量.2.儲存產生這個增量的時間點 */ double[][] record = new double[length][2]; /** * 為二維數組裝載資料<br> * 註:通過此方法,有個特點,能把最後的length組資料記錄下來,length以外的會丟失 * * @param detadegree * @param time */ public void add(double detadegree, double time) { for (int i = length - 1; i > 0; i--) { record[i][0] = record[i - 1][0]; record[i][1] = record[i - 1][1]; } record[0][0] = detadegree; record[0][1] = time; addCount++; } /** * 最大速度 */ public static final double max_speed = 8; /** * 通過數組裡所裝載的資料分析出即時速度<br> * 原理是:計算數組裡的時間長度和增量的總數。然後求出每毫秒所走過的弧度<br> * 當然不能超過{@link VRecord#max_speed} * * @return */ public double getSpeed() { if (addCount == 0) { return 0; } int maxIndex = Math.min(addCount, length) - 1; if ((record[0][1] - record[maxIndex][1]) == 0) { return 0; } double detaTime = record[0][1] - record[maxIndex][1]; double sumdegree = 0; for (int i = 0; i < length - 1; i++) { sumdegree += record[i][0]; // System.out.println(record[i][0]); } // System.out.println("----------"); // System.out.println(sumdegree); // System.out.println(detaTime); double result = sumdegree / detaTime; if (result > 0) { return Math.min(result, max_speed); } else { return Math.max(result, -max_speed); } // System.out.println("v=" + result); } /** * 重設 */ public void reset() { addCount = 0; for (int i = length - 1; i > 0; i--) { record[i][0] = 0; record[i][1] = 0; } } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if(rotatBitmap!=null){ rotatBitmap.recycle(); rotatBitmap=null; } }}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffffff" > <com.sun.shine.myrotation.view.RotatView android:id="@+id/myRotatView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dip" > </com.sun.shine.myrotation.view.RotatView></RelativeLayout>
android的一些控制項