1. 程式人生 > >Android仿Win8界面的button點擊

Android仿Win8界面的button點擊

鋸齒 camera param 例如 sqrt urn oat data 寬度

今天沒事的時候,感覺Win8的扁平化的button還是挺好看的,就研究了下怎樣在安卓界面實現Win8的扁平化button點擊效果。

發現了一個自己定義的View能夠實現扁平化button效果,話不多說,我們直接上代碼。

1、首先要自己定義自己的View。創建一個自己定義的MyImageView類繼承ImageView,並實現點擊效果的設定。

public class MyImageView extends ImageView {

   private boolean onAnimation = true;// 是否處於動畫狀態
   private int rotateDegree 
= 10;// 運行動畫的時間 private boolean isFirst = true;// 標識是否為第一次繪制視圖 private float minScale = 0.95f;// 最小縮放限度 private int vWidth;// 視圖寬度 private int vHeight;// 視圖高度 private boolean isFinish = true;// 標識是否為結束 private boolean isActionMove = false;// 標識是否在移動狀態 private boolean isScale = false;// 標識是否為縮放狀態
private Camera camera; boolean XbigY = false;// 是否放大 float RolateX = 0;// 旋轉的X軸點 float RolateY = 0;// 旋轉的Y軸點 OnViewClick onclick = null; public MyImageView(Context context) { super(context); // TODO Auto-generated constructor stub camera = new Camera(); } public MyImageView(Context context, AttributeSet attrs) { super
(context, attrs); // TODO Auto-generated constructor stub camera = new Camera(); } public void SetAnimationOnOff(boolean oo) { onAnimation = oo; } /** * 設置點擊事件 * * @param onclick */ public void setOnClickIntent(OnViewClick onclick) { this.onclick = onclick; } /** * 繪制View */ @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isFirst) {// 推斷是否為第一次進入 isFirst = false; init(); } canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));// 抗鋸齒 } /** * 初始化視圖---初始化配置 */ public void init() { vWidth = getWidth() - getPaddingLeft() - getPaddingRight(); vHeight = getHeight() - getPaddingTop() - getPaddingBottom(); Drawable drawable = getDrawable(); BitmapDrawable bd = (BitmapDrawable) drawable; bd.setAntiAlias(true); } /** * 觸摸監聽 */ @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); if (!onAnimation)// 推斷是否為動畫狀態 return true; switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN:// 按下 float X = event.getX(); float Y = event.getY(); RolateX = vWidth / 2 - X; RolateY = vHeight / 2 - Y; XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false; isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3 && Y < vHeight * 2 / 3; isActionMove = false; if (isScale) {// 推斷是否同意縮放 scaleHandler.sendEmptyMessage(1); } else { rolateHandler.sendEmptyMessage(1); } break; case MotionEvent.ACTION_MOVE:// 移動 float x = event.getX(); float y = event.getY(); if (x > vWidth || y > vHeight || x < 0 || y < 0) { isActionMove = true; } else { isActionMove = false; } break; case MotionEvent.ACTION_UP:// 松開 if (isScale) {// 推斷是否同意縮放 scaleHandler.sendEmptyMessage(6); } else { rolateHandler.sendEmptyMessage(6); } break; } return true; } /** * 自己定義View點擊事件接口 */ public interface OnViewClick { public void onClick(); } /** * 旋轉動畫的Handler,依據狀態運行動畫 */ @SuppressLint("HandlerLeak") private Handler rolateHandler = new Handler() { private Matrix matrix = new Matrix(); private float count = 0; @Override public void handleMessage(Message msg) { super.handleMessage(msg); matrix.set(getImageMatrix()); switch (msg.what) { case 1: count = 0; BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count)); rolateHandler.sendEmptyMessage(2); break; case 2: BeginRolate(matrix, (XbigY ?

count : 0), (XbigY ? 0 : count)); if (count < getDegree()) { rolateHandler.sendEmptyMessage(2); } else { isFinish = true; } count++; count++; break; case 3: BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count)); if (count > 0) { rolateHandler.sendEmptyMessage(3); } else { isFinish = true; if (!isActionMove && onclick != null) { onclick.onClick(); } } count--; count--; break; case 6: count = getDegree(); BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count)); rolateHandler.sendEmptyMessage(3); break; } } }; /** * 開始旋轉--使用線程鎖控制,確保每次僅僅運行一個動作 * * @param matrix * @param rolateX * @param rolateY */ private synchronized void BeginRolate(Matrix matrix, float rolateX, float rolateY) { int scaleX = (int) (vWidth * 0.5f); int scaleY = (int) (vHeight * 0.5f); camera.save(); camera.rotateX(RolateY > 0 ? rolateY : -rolateY); camera.rotateY(RolateX < 0 ?

rolateX : -rolateX); camera.getMatrix(matrix); camera.restore(); // 控制中心點 if (RolateX > 0 && rolateX != 0) { matrix.preTranslate(-vWidth, -scaleY); matrix.postTranslate(vWidth, scaleY); } else if (RolateY > 0 && rolateY != 0) { matrix.preTranslate(-scaleX, -vHeight); matrix.postTranslate(scaleX, vHeight); } else if (RolateX < 0 && rolateX != 0) { matrix.preTranslate(-0, -scaleY); matrix.postTranslate(0, scaleY); } else if (RolateY < 0 && rolateY != 0) { matrix.preTranslate(-scaleX, -0); matrix.postTranslate(scaleX, 0); } setImageMatrix(matrix); } /** * 縮放動畫Handler */ @SuppressLint("HandlerLeak") private Handler scaleHandler = new Handler() { private Matrix matrix = new Matrix(); private float s; int count = 0; @Override public void handleMessage(Message msg) { super.handleMessage(msg); matrix.set(getImageMatrix()); switch (msg.what) { case 1: if (!isFinish) { return; } else { isFinish = false; count = 0; s = (float) Math.sqrt(Math.sqrt(minScale)); BeginScale(matrix, s); scaleHandler.sendEmptyMessage(2); } break; case 2: BeginScale(matrix, s); if (count < 4) { scaleHandler.sendEmptyMessage(2); } else { isFinish = true; if (!isActionMove && onclick != null) { onclick.onClick(); } } count++; break; case 6: if (!isFinish) { scaleHandler.sendEmptyMessage(6); } else { isFinish = false; count = 0; s = (float) Math.sqrt(Math.sqrt(1.0f / minScale)); BeginScale(matrix, s); scaleHandler.sendEmptyMessage(2); } break; } } }; /** * 開始縮放動畫 * * @param matrix * @param scale */ private synchronized void BeginScale(Matrix matrix, float scale) { int scaleX = (int) (vWidth * 0.5f); int scaleY = (int) (vHeight * 0.5f); matrix.postScale(scale, scale, scaleX, scaleY); setImageMatrix(matrix); } /** * 獲取運行的時間--旋轉 * * @return */ public int getDegree() { return rotateDegree; } /** * 設置動畫時間--旋轉 * * @param degree */ public void setDegree(int degree) { rotateDegree = degree; } /** * 獲取縮放程度 * * @return */ public float getScale() { return minScale; } /** * 設置視圖縮放度 * * @param scale */ public void setScale(float scale) { minScale = scale; } }


當中Record類的主要內容例如以下:
public class Record{
   

   public int getDegrees(float a, float b) {
      float dx = a;
      float x = b / 4;
      float x2 = 3 * b / 4;
      if (dx < x / 10)
         return 10;
      else if (dx < x / 5)
         return 9;
      else if (dx < x * 3 / 10)
         return 8;
      else if (dx < x * 2 / 5)
         return 7;
      else if (dx < x * 5 / 10)
         return 6;
      else if (dx < x * 3 / 5)
         return 5;
      else if (dx < x * 7 / 10)
         return 4;
      else if (dx < x * 4 / 5)
         return 3;
      else if (dx < x * 9 / 10)
         return 2;
      else if (dx < x)
         return 2;
      else if (dx - x2 > x * 9 / 10)
         return 10;
      else if (dx - x2 > x * 4 / 5)
         return 9;
      else if (dx - x2 > x * 7 / 10)
         return 8;
      else if (dx - x2 > x * 3 / 5)
         return 7;
      else if (dx - x2 > x * 5 / 10)
         return 6;
      else if (dx - x2 > x * 2 / 5)
         return 5;
      else if (dx - x2 > x * 3 / 10)
         return 4;
      else if (dx - x2 > x / 5)
         return 3;
      else if (dx - x2 > x / 10)
         return 2;
      return 10;
   }
}
2、定義好了自己的ImageView後,在給界面加入button的時候,引用自己定義的ImageView就可以。




Android仿Win8界面的button點擊