Beispiel #1
0
        /// <summary>Find the nearest touchable view to the specified view.</summary>
        /// <remarks>Find the nearest touchable view to the specified view.</remarks>
        /// <param name="root">The root of the tree in which to search</param>
        /// <param name="x">X coordinate from which to start the search</param>
        /// <param name="y">Y coordinate from which to start the search</param>
        /// <param name="direction">Direction to look</param>
        /// <param name="deltas">
        /// Offset from the <x, y> to the edge of the nearest view. Note that this array
        /// may already be populated with values.
        /// </param>
        /// <returns>The nearest touchable view, or null if none exists.</returns>
        public virtual android.view.View findNearestTouchable(android.view.ViewGroup root
                                                              , int x, int y, int direction, int[] deltas)
        {
            java.util.ArrayList <android.view.View> touchables = root.getTouchables();
            int minDistance = int.MaxValue;

            android.view.View closest = null;
            int numTouchables         = touchables.size();
            int edgeSlop = android.view.ViewConfiguration.get(root.mContext).getScaledEdgeSlop
                               ();

            android.graphics.Rect closestBounds   = new android.graphics.Rect();
            android.graphics.Rect touchableBounds = mOtherRect;
            {
                for (int i = 0; i < numTouchables; i++)
                {
                    android.view.View touchable = touchables.get(i);
                    // get visible bounds of other view in same coordinate system
                    touchable.getDrawingRect(touchableBounds);
                    root.offsetRectBetweenParentAndChild(touchable, touchableBounds, true, true);
                    if (!isTouchCandidate(x, y, touchableBounds, direction))
                    {
                        continue;
                    }
                    int distance = int.MaxValue;
                    switch (direction)
                    {
                    case android.view.View.FOCUS_LEFT:
                    {
                        distance = x - touchableBounds.right + 1;
                        break;
                    }

                    case android.view.View.FOCUS_RIGHT:
                    {
                        distance = touchableBounds.left;
                        break;
                    }

                    case android.view.View.FOCUS_UP:
                    {
                        distance = y - touchableBounds.bottom + 1;
                        break;
                    }

                    case android.view.View.FOCUS_DOWN:
                    {
                        distance = touchableBounds.top;
                        break;
                    }
                    }
                    if (distance < edgeSlop)
                    {
                        // Give preference to innermost views
                        if (closest == null || closestBounds.contains(touchableBounds) || (!touchableBounds
                                                                                           .contains(closestBounds) && distance < minDistance))
                        {
                            minDistance = distance;
                            closest     = touchable;
                            closestBounds.set(touchableBounds);
                            switch (direction)
                            {
                            case android.view.View.FOCUS_LEFT:
                            {
                                deltas[0] = -distance;
                                break;
                            }

                            case android.view.View.FOCUS_RIGHT:
                            {
                                deltas[0] = distance;
                                break;
                            }

                            case android.view.View.FOCUS_UP:
                            {
                                deltas[1] = -distance;
                                break;
                            }

                            case android.view.View.FOCUS_DOWN:
                            {
                                deltas[1] = distance;
                                break;
                            }
                            }
                        }
                    }
                }
            }
            return(closest);
        }
Beispiel #2
0
        private android.view.View findNextFocus(android.view.ViewGroup root, android.view.View
                                                focused, android.graphics.Rect focusedRect, int direction)
        {
            java.util.ArrayList <android.view.View> focusables = root.getFocusables(direction);
            if (focusables.isEmpty())
            {
                // The focus cannot change.
                return(null);
            }
            if (direction == android.view.View.FOCUS_FORWARD || direction == android.view.View
                .FOCUS_BACKWARD)
            {
                if (focused != null && !focusables.contains(focused))
                {
                    // Add the currently focused view to the list to have it sorted
                    // along with the other views.
                    focusables.add(focused);
                }
                try
                {
                    // Note: This sort is stable.
                    mSequentialFocusComparator.setRoot(root);
                    java.util.Collections.sort(focusables, mSequentialFocusComparator);
                }
                finally
                {
                    mSequentialFocusComparator.recycle();
                }
                int count = focusables.size();
                switch (direction)
                {
                case android.view.View.FOCUS_FORWARD:
                {
                    if (focused != null)
                    {
                        int position = focusables.lastIndexOf(focused);
                        if (position >= 0 && position + 1 < count)
                        {
                            return(focusables.get(position + 1));
                        }
                    }
                    return(focusables.get(0));
                }

                case android.view.View.FOCUS_BACKWARD:
                {
                    if (focused != null)
                    {
                        int position = focusables.indexOf(focused);
                        if (position > 0)
                        {
                            return(focusables.get(position - 1));
                        }
                    }
                    return(focusables.get(count - 1));
                }
                }
                return(null);
            }
            // initialize the best candidate to something impossible
            // (so the first plausible view will become the best choice)
            mBestCandidateRect.set(focusedRect);
            switch (direction)
            {
            case android.view.View.FOCUS_LEFT:
            {
                mBestCandidateRect.offset(focusedRect.width() + 1, 0);
                break;
            }

            case android.view.View.FOCUS_RIGHT:
            {
                mBestCandidateRect.offset(-(focusedRect.width() + 1), 0);
                break;
            }

            case android.view.View.FOCUS_UP:
            {
                mBestCandidateRect.offset(0, focusedRect.height() + 1);
                break;
            }

            case android.view.View.FOCUS_DOWN:
            {
                mBestCandidateRect.offset(0, -(focusedRect.height() + 1));
                break;
            }
            }
            android.view.View closest = null;
            int numFocusables         = focusables.size();

            {
                for (int i = 0; i < numFocusables; i++)
                {
                    android.view.View focusable = focusables.get(i);
                    // only interested in other non-root views
                    if (focusable == focused || focusable == root)
                    {
                        continue;
                    }
                    // get visible bounds of other view in same coordinate system
                    focusable.getDrawingRect(mOtherRect);
                    root.offsetDescendantRectToMyCoords(focusable, mOtherRect);
                    if (isBetterCandidate(direction, focusedRect, mOtherRect, mBestCandidateRect))
                    {
                        mBestCandidateRect.set(mOtherRect);
                        closest = focusable;
                    }
                }
            }
            return(closest);
        }