1:根據startAngle來擺放子view(特別注意坐標的問題)
@Override PRotected void onLayout(boolean changed, int l, int t, int r, int b) { for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); //獲取孩子視圖的測量寬度 int childWidth = child.getMeasuredWidth(); //temp:相當于自定義控件所在圓的圓心到子視圖所在矩形的幾何中心的距離 float temp = d / 3.0f; int left = (int) (d / 2 + Math.round(temp * Math.cos(Math.toRadians(startAngle))) - childWidth / 2); int right = left + childWidth; int top = (int) (d / 2 + Math.round(temp * Math.sin(Math.toRadians(startAngle))) - childWidth / 2); int bottom = top + childWidth; child.layout(left, top, right, bottom); startAngle += 360 / getChildCount(); } }2:實現旋轉的思路是計算出down到move之間的角度(注意坐標和角度的象限問題),在累加給startAngle,重新布局requestLayout();
private float lastX; private float lastY; @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.i("test", "ACTION_DOWN"); lastX = x; lastY = y; break; case MotionEvent.ACTION_MOVE: Log.i("test", "ACTION_MOVE"); float start = CircleUtil.getAngle(lastX, lastY, d); float end = CircleUtil.getAngle(x, y, d); float angle; //判斷點擊的點所處的象限,如果是1,4象限,角度值是正數,否則是負數 if (CircleUtil.getQuadrant(x, y, d) == 1 || CircleUtil.getQuadrant(x, y, d) == 4) { angle = end - start; } else { angle = start - end; } startAngle += angle; //讓界面重新布局和繪制 requestLayout(); lastX = x; lastY = y; break; case MotionEvent.ACTION_UP: Log.i("test", "ACTION_UP"); break; } //return true 表示當前控件想要處理事件,如果沒有其他控件想要處理,則所有的MotionEvent事件都會交給自己處理 return true; }3:兩個工具類
public class CircleUtil { /** * 根據觸摸的位置,計算角度 * * @param xTouch * @param yTouch * @param d 直徑 * @return */ public static float getAngle(float xTouch, float yTouch,int d) { double x = xTouch - (d / 2f); double y = yTouch - (d / 2f); //hypot:通過兩條直角邊,求斜邊 return (float) (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI); } /** * 根據當前位置計算象限 * * @param x * @param y * @param d 直徑 * @return */ public static int getQuadrant(float x, float y,int d) { int tmpX = (int) (x - d / 2); int tmpY = (int) (y - d / 2); if (tmpX >= 0) { return tmpY >= 0 ? 4 : 1; } else { return tmpY >= 0 ? 3 : 2; } }}新聞熱點
疑難解答