Loading core/java/android/view/View.java +51 −10 Original line number Diff line number Diff line Loading @@ -4898,22 +4898,22 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit switch (direction) { case FOCUS_LEFT: if (mNextFocusLeftId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusLeftId); return findViewInsideOutShouldExist(root, mNextFocusLeftId); case FOCUS_RIGHT: if (mNextFocusRightId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusRightId); return findViewInsideOutShouldExist(root, mNextFocusRightId); case FOCUS_UP: if (mNextFocusUpId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusUpId); return findViewInsideOutShouldExist(root, mNextFocusUpId); case FOCUS_DOWN: if (mNextFocusDownId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusDownId); return findViewInsideOutShouldExist(root, mNextFocusDownId); case FOCUS_FORWARD: if (mNextFocusForwardId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusForwardId); return findViewInsideOutShouldExist(root, mNextFocusForwardId); case FOCUS_BACKWARD: { final int id = mID; return root.findViewByPredicate(new Predicate<View>() { return root.findViewByPredicateInsideOut(this, new Predicate<View>() { @Override public boolean apply(View t) { return t.mNextFocusForwardId == id; Loading @@ -4924,8 +4924,14 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit return null; } private static View findViewShouldExist(View root, int childViewId) { View result = root.findViewById(childViewId); private View findViewInsideOutShouldExist(View root, final int childViewId) { View result = root.findViewByPredicateInsideOut(this, new Predicate<View>() { @Override public boolean apply(View t) { return t.mID == childViewId; } }); if (result == null) { Log.w(VIEW_LOG_TAG, "couldn't find next focus view specified " + "by user for id " + childViewId); Loading Loading @@ -11746,9 +11752,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit /** * {@hide} * @param predicate The predicate to evaluate. * @param childToSkip If not null, ignores this child during the recursive traversal. * @return The first view that matches the predicate or null. */ protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { if (predicate.apply(this)) { return this; } Loading Loading @@ -11792,7 +11799,41 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit * @return The first view that matches the predicate or null. */ public final View findViewByPredicate(Predicate<View> predicate) { return findViewByPredicateTraversal(predicate); return findViewByPredicateTraversal(predicate, null); } /** * {@hide} * Look for a child view that matches the specified predicate, * starting with the specified view and its descendents and then * recusively searching the ancestors and siblings of that view * until this view is reached. * * This method is useful in cases where the predicate does not match * a single unique view (perhaps multiple views use the same id) * and we are trying to find the view that is "closest" in scope to the * starting view. * * @param start The view to start from. * @param predicate The predicate to evaluate. * @return The first view that matches the predicate or null. */ public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) { View childToSkip = null; for (;;) { View view = start.findViewByPredicateTraversal(predicate, childToSkip); if (view != null || start == this) { return view; } ViewParent parent = start.getParent(); if (parent == null || !(parent instanceof View)) { return null; } childToSkip = start; start = (View) parent; } } /** Loading core/java/android/view/ViewGroup.java +2 −2 Original line number Diff line number Diff line Loading @@ -3038,7 +3038,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * {@hide} */ @Override protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { if (predicate.apply(this)) { return this; } Loading @@ -3049,7 +3049,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < len; i++) { View v = where[i]; if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { if (v != childToSkip && (v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { v = v.findViewByPredicate(predicate); if (v != null) { Loading core/java/android/widget/ListView.java +6 −6 Original line number Diff line number Diff line Loading @@ -3545,16 +3545,16 @@ public class ListView extends AbsListView { * First look in our children, then in any header and footer views that may be scrolled off. */ @Override protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { View v; v = super.findViewByPredicateTraversal(predicate); v = super.findViewByPredicateTraversal(predicate, childToSkip); if (v == null) { v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate); v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate, childToSkip); if (v != null) { return v; } v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate); v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate, childToSkip); if (v != null) { return v; } Loading @@ -3568,7 +3568,7 @@ public class ListView extends AbsListView { * the predicate. */ View findViewByPredicateInHeadersOrFooters(ArrayList<FixedViewInfo> where, Predicate<View> predicate) { Predicate<View> predicate, View childToSkip) { if (where != null) { int len = where.size(); View v; Loading @@ -3576,7 +3576,7 @@ public class ListView extends AbsListView { for (int i = 0; i < len; i++) { v = where.get(i).view; if (!v.isRootNamespace()) { if (v != childToSkip && !v.isRootNamespace()) { v = v.findViewByPredicate(predicate); if (v != null) { Loading Loading
core/java/android/view/View.java +51 −10 Original line number Diff line number Diff line Loading @@ -4898,22 +4898,22 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit switch (direction) { case FOCUS_LEFT: if (mNextFocusLeftId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusLeftId); return findViewInsideOutShouldExist(root, mNextFocusLeftId); case FOCUS_RIGHT: if (mNextFocusRightId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusRightId); return findViewInsideOutShouldExist(root, mNextFocusRightId); case FOCUS_UP: if (mNextFocusUpId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusUpId); return findViewInsideOutShouldExist(root, mNextFocusUpId); case FOCUS_DOWN: if (mNextFocusDownId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusDownId); return findViewInsideOutShouldExist(root, mNextFocusDownId); case FOCUS_FORWARD: if (mNextFocusForwardId == View.NO_ID) return null; return findViewShouldExist(root, mNextFocusForwardId); return findViewInsideOutShouldExist(root, mNextFocusForwardId); case FOCUS_BACKWARD: { final int id = mID; return root.findViewByPredicate(new Predicate<View>() { return root.findViewByPredicateInsideOut(this, new Predicate<View>() { @Override public boolean apply(View t) { return t.mNextFocusForwardId == id; Loading @@ -4924,8 +4924,14 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit return null; } private static View findViewShouldExist(View root, int childViewId) { View result = root.findViewById(childViewId); private View findViewInsideOutShouldExist(View root, final int childViewId) { View result = root.findViewByPredicateInsideOut(this, new Predicate<View>() { @Override public boolean apply(View t) { return t.mID == childViewId; } }); if (result == null) { Log.w(VIEW_LOG_TAG, "couldn't find next focus view specified " + "by user for id " + childViewId); Loading Loading @@ -11746,9 +11752,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit /** * {@hide} * @param predicate The predicate to evaluate. * @param childToSkip If not null, ignores this child during the recursive traversal. * @return The first view that matches the predicate or null. */ protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { if (predicate.apply(this)) { return this; } Loading Loading @@ -11792,7 +11799,41 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit * @return The first view that matches the predicate or null. */ public final View findViewByPredicate(Predicate<View> predicate) { return findViewByPredicateTraversal(predicate); return findViewByPredicateTraversal(predicate, null); } /** * {@hide} * Look for a child view that matches the specified predicate, * starting with the specified view and its descendents and then * recusively searching the ancestors and siblings of that view * until this view is reached. * * This method is useful in cases where the predicate does not match * a single unique view (perhaps multiple views use the same id) * and we are trying to find the view that is "closest" in scope to the * starting view. * * @param start The view to start from. * @param predicate The predicate to evaluate. * @return The first view that matches the predicate or null. */ public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) { View childToSkip = null; for (;;) { View view = start.findViewByPredicateTraversal(predicate, childToSkip); if (view != null || start == this) { return view; } ViewParent parent = start.getParent(); if (parent == null || !(parent instanceof View)) { return null; } childToSkip = start; start = (View) parent; } } /** Loading
core/java/android/view/ViewGroup.java +2 −2 Original line number Diff line number Diff line Loading @@ -3038,7 +3038,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * {@hide} */ @Override protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { if (predicate.apply(this)) { return this; } Loading @@ -3049,7 +3049,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < len; i++) { View v = where[i]; if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { if (v != childToSkip && (v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { v = v.findViewByPredicate(predicate); if (v != null) { Loading
core/java/android/widget/ListView.java +6 −6 Original line number Diff line number Diff line Loading @@ -3545,16 +3545,16 @@ public class ListView extends AbsListView { * First look in our children, then in any header and footer views that may be scrolled off. */ @Override protected View findViewByPredicateTraversal(Predicate<View> predicate) { protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) { View v; v = super.findViewByPredicateTraversal(predicate); v = super.findViewByPredicateTraversal(predicate, childToSkip); if (v == null) { v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate); v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate, childToSkip); if (v != null) { return v; } v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate); v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate, childToSkip); if (v != null) { return v; } Loading @@ -3568,7 +3568,7 @@ public class ListView extends AbsListView { * the predicate. */ View findViewByPredicateInHeadersOrFooters(ArrayList<FixedViewInfo> where, Predicate<View> predicate) { Predicate<View> predicate, View childToSkip) { if (where != null) { int len = where.size(); View v; Loading @@ -3576,7 +3576,7 @@ public class ListView extends AbsListView { for (int i = 0; i < len; i++) { v = where.get(i).view; if (!v.isRootNamespace()) { if (v != childToSkip && !v.isRootNamespace()) { v = v.findViewByPredicate(predicate); if (v != null) { Loading