【问题标题】:Creating a "map" of the edges of a button创建按钮边缘的“地图”
【发布时间】:2012-09-04 21:16:16
【问题描述】:

所以从这里的这个问题开始:Rounded buttons,我想我需要创建一种视图边缘的地图,假设我有一个看起来像这样的视图:

按钮不会是蓝色或任何特定颜色,因此我们无法检查用户触摸的位置是否为蓝色,这是上一个问题中的一个答案所建议的。

假设我收到了一个触摸事件,我在这个视图中获得了触摸的位置,视图是矩形的,我只想在他们按下蓝色部分时接受输入。我怎么能弄清楚这个?

【问题讨论】:

    标签: java android view


    【解决方案1】:

    让我们假设图形的边界框正好填满了视图。我们可以如下进行。感兴趣的区域以两个同心圆和视图为界。 (圆心是视图的右下角。)当我们得到触摸时,我们只需要计算从触摸坐标到右下角的距离,并将其与两个圆半径进行比较。 (您可以通过将平方距离与平方半径进行比较来避免平方根。)如果距离在半径之间,则触摸为蓝色(或任何颜色)。我们不需要计算触摸是否在边界框内;我们已经知道,因为事件被传递到视图。

    这里有一些示例代码。它用于检测器确定一个点是否在两个同心圆(一个环形)内,如果是,它会击中哪个象限。

    public class ArcHitDetector {
        public enum Quadrant {
            TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
        }
        private int xCenter, yCenter, innerR2, outerR2;
        /**
         * Construct an ArcHitDetector for an annulus centered at given
         * points and with given inner and outer radii.
         *
         * @param xCenter the horizontal center coordinate
         * @param yCenter the vertical center coordinate
         * @param outerR the outer radius of the annulus
         * @param innerR the inner radius of the annulus
         */
        public ArcHitDetector(int xCenter, int yCenter, int outerR, int innerR) {
            this.xCenter = xCenter;
            this.yCenter = yCenter;
            this.outerR2 = outerR * outerR;
            this.innerR2 = innerR * innerR;
        }
    
        /**
         * Classify a point with respect to the annulus. It assumes
         * screen coordinates (x increases to the right; y increases
         * down).
         *
         * @param x the x coordinate of the point to test
         * @param y the y coordinate of the point to test
         *
         * @return the Quadrant of the annulus in which the point falls,
         *    or null if the point does not lie in the annulus
         */
        public Quadrant classifyHit(int x, int y) {
            int dx = x - xCenter;
            int dy = y - yCenter;
            int d2 = dx * dx + dy * dy;
            if (d2 <= outerR2 && d2 >= innerR2) {
                if (x >= xCenter) {
                    return y <= yCenter ? TOP_RIGHT : BOTTOM_RIGHT;
                } else {
                    return y <= yCenter ? TOP_LEFT : BOTTOM_LEFT;
                }
            } else {
                return null;
            }
        }
    }
    

    【讨论】:

    • 我们有一些代码来生成这个吗?假设弧线是“完美的”,但如果不是呢?
    • @SmartLemon - 我添加了一些示例代码。一般来说,不完美的弧线并不是什么大问题。只需在计算中添加一点斜率(例如,增加外半径并减少内半径)。无论如何,触摸事件并不是那么准确。如果曲线与圆显着不同(例如,它们是椭圆),请相应地更改方程。
    • 嗯,谢谢,我会整理一下,谢谢你的帮助。
    【解决方案2】:

    我建议创建代表该形状的顶部和底部曲线的方程,2 个倒置抛物线,并检查 y 是否大于给定底部曲线的 y 方程x 值,并且在给定的 x 值处,y 小于顶部曲线的 y(并且 y 大于 0,假设 0 是底部,但是 x 小于你的按钮在最右边)。

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      相关资源
      最近更新 更多