Refactor the code of menu position counting

This commit is contained in:
Dacer
2016-11-18 21:54:26 +08:00
parent c53fe07266
commit 0c59e91c3e
3 changed files with 59 additions and 79 deletions

View File

@@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
@@ -18,6 +19,9 @@ import android.view.WindowManager;
import com.hackplan.androidarcmenu.ArcMenu.OnClickMenuListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Dacer on 12/11/2016.
*/
@@ -47,33 +51,38 @@ public class ArcMenuLayout extends ViewGroup {
return show;
}
private float xFirst, yFirst, xEnd, yEnd;
private int radius = (int)dpToPx(80f);
private double radAlpha = Math.toRadians(90d);
private ArrayList<PointF> menuPoints = new ArrayList<>();
private int radius = (int) dpToPx(80f);
private double arcRadians = Math.toRadians(90d);
public void show(ArcMenu arcMenu, int x, int y, boolean hideOnTouchUp) {
if (getChildCount() <= 0) return;
this.hideOnTouchUp = hideOnTouchUp;
this.arcMenu = arcMenu;
show = true;
if (x == mScreenRect.centerX() && y == mScreenRect.centerY()) y += 1;
touchPoint.set(x, y);
double radO = Math.PI - radAlpha/2 -
Math.atan((touchPoint.x - mScreenRect.centerX()) / (touchPoint.y - mScreenRect.centerY()));
double rad2 = Math.atan((touchPoint.x - mScreenRect.centerX()) / (touchPoint.y - mScreenRect.centerY())) - radAlpha/2;
xFirst = touchPoint.x - ((float) (radius * Math.sin(radO)));
yFirst = touchPoint.y + ((float) (Math.cos(radO) * radius));
xEnd = touchPoint.x - ((float) (radius * Math.sin(rad2)));
yEnd = touchPoint.y - ((float) (Math.cos(rad2) * radius));
menuPoints.clear();
double alpha = Math.atan((double) (y - mScreenRect.centerY()) / (x - mScreenRect.centerX()));
if (x < mScreenRect.centerX()) alpha += Math.PI;
for (int i=0; i<getChildCount(); i++) {
double b;
if (getChildCount() == 1) {
b = arcRadians / 2;
}else {
b = i * (1D / (getChildCount() - 1)) * arcRadians;
}
menuPoints.add(PointUtils.getPoint(new PointF(x, y), radius,
Math.PI + alpha - arcRadians / 2 + b));
}
requestLayout();
}
public void setOnClickMenuListener(OnClickMenuListener onClickMenuListener) {
this.onClickMenuListener = onClickMenuListener;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -84,34 +93,27 @@ public class ArcMenuLayout extends ViewGroup {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (!show) return ;
if (!show) return;
int childCount = this.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = this.getChildAt(i);
child.setAlpha(0L);
if (i == 0) {
child.layout((int)xFirst - child.getMeasuredWidth()/2,
(int)yFirst - child.getMeasuredHeight()/2,
(int)xFirst + child.getMeasuredWidth()/2,
(int)yFirst + child.getMeasuredHeight()/2);
} else {
child.layout((int)xEnd - child.getMeasuredWidth()/2,
(int)yEnd - child.getMeasuredHeight()/2,
(int)(xEnd + child.getMeasuredWidth()/2),
(int)(yEnd + child.getMeasuredHeight()/2));
}
child.layout((int) (menuPoints.get(i).x - child.getMeasuredWidth() / 2),
(int) (menuPoints.get(i).y - child.getMeasuredHeight() / 2),
(int) (menuPoints.get(i).x + child.getMeasuredWidth() / 2),
(int) (menuPoints.get(i).y + child.getMeasuredHeight() / 2));
}
AnimatorUtils.showMenu(this, touchPoint, animListener);
}
private int lastFocusIndex = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = MotionEventCompat.getX(event, 0);
float y = MotionEventCompat.getY(event, 0);
switch (event.getAction()){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
hideOnTouchUp = true;
break;
@@ -123,12 +125,12 @@ public class ArcMenuLayout extends ViewGroup {
AnimatorUtils.openMenu(this, lastFocusIndex, animListener);
if (onClickMenuListener != null) {
View clickedView = getChildAt(lastFocusIndex);
onClickMenuListener.onClickArcMenu(arcMenu, (int)clickedView.getTag());
onClickMenuListener.onClickArcMenu(arcMenu, (int) clickedView.getTag());
}
} else if (hideOnTouchUp) {
AnimatorUtils.hideMenu(this, touchPoint);
show = false;
}else {
} else {
hideOnTouchUp = true;
}
lastFocusIndex = -1;
@@ -137,12 +139,13 @@ public class ArcMenuLayout extends ViewGroup {
if (!animFinished) break;
tempRect = new Rect();
boolean isOverMenu = false;
for (int i=0; i<getChildCount(); i++) {
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).getGlobalVisibleRect(tempRect);
if (tempRect.contains((int)x, (int)y)) {
if (tempRect.contains((int) x, (int) y)) {
isOverMenu = true;
if (lastFocusIndex == i) break;
if (lastFocusIndex != -1) AnimatorUtils.clearFocusChild(this, lastFocusIndex);
if (lastFocusIndex != -1)
AnimatorUtils.clearFocusChild(this, lastFocusIndex);
AnimatorUtils.focusChild(this, i);
lastFocusIndex = i;
break;
@@ -163,9 +166,9 @@ public class ArcMenuLayout extends ViewGroup {
int w = resolveSizeAndState(0, widthMeasureSpec, 1);
int h = resolveSizeAndState(0, heightMeasureSpec, 0);
int childCount = getChildCount();
for(int i = 0 ; i < childCount ; i ++){
for (int i = 0; i < childCount; i++) {
View children = getChildAt(i);
measureChild(children,widthMeasureSpec,heightMeasureSpec);
measureChild(children, widthMeasureSpec, heightMeasureSpec);
}
setMeasuredDimension(w, h);
}

View File

@@ -0,0 +1,19 @@
package com.hackplan.androidarcmenu;
import android.graphics.PointF;
class PointUtils {
/**
* Polar coordinates to Rectangular coordinates
*
* @param origin of the coordinate system
* @param distance this really means "radius"
* @param angle from the x-axis in radians; positive increases in the counterclockwise direction
*/
static PointF getPoint(PointF origin, float distance, double angle) {
PointF newPoint = new PointF();
newPoint.x = origin.x + (float) (distance * Math.cos(angle));
newPoint.y = origin.y + (float) (distance * Math.sin(angle));
return newPoint;
}
}

View File

@@ -1,42 +0,0 @@
/**
* Copyright (C) 2015 ogaclejapan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hackplan.androidarcmenu;
/**
* Modified by Dacer.
* from https://github.com/ogaclejapan/ArcLayout
*/
public class Utils {
public static int x(int radius, float degrees) {
return Math.round(Utils.computeCircleX(radius, degrees));
}
public static int y(int radius, float degrees) {
return Math.round(computeCircleY(radius, degrees));
}
private static float computeCircleX(float r, float degrees) {
return (float) (r * Math.cos(Math.toRadians(degrees)));
}
private static float computeCircleY(float r, float degrees) {
return (float) (r * Math.sin(Math.toRadians(degrees)));
}
}