The Focus part of the record of Focus processing is only the key movement part. It is not clear that the Focus part of Touch Focus should be resolved. What is the next Focus of the control? Analysis: when a user triggers a focus switch by pressing a key (remote control, etc.), the event command is processed through the underlying layer. In ViewRootImpl. there is a method in java, deliverKeyEventPostIme (...), because the underlying code is involved, no detailed trace and Analysis of the call logic of this method is provided. According to the information on the Internet, the processing of the buttons will go through this method. Private void deliverKeyEventPostIme (QueuedInputEvent q ){... // Handle automatic focus changes. if (event. getAction () = KeyEvent. ACTION_DOWN) {int direction = 0; switch (event. getKeyCode () {case KeyEvent. KEYCODE_DPAD_LEFT: if (event. hasNoModifiers () {direction = View. FOCUS_LEFT;} break; case KeyEvent. KEYCODE_DPAD_RIGHT: if (event. hasNoModifiers () {direction = View. FOCUS_RIGHT;} break ;. ..} If (direction! = 0) {View focused = mView. findFocus (); if (focused! = Null) {View v = focused. focusSearch (direction); if (v! = Null & v! = Focused ){..... if (v. requestFocus (direction, mTempRect )){... finishInputEvent (q, true); return ;}}...}} from this method, we can see that the main two core processes are: 12 View v = focused. focusSearch (direction); v. requestFocus (direction, mTempRect) Next, let's take a detailed analysis to see what operations are being performed during the process. Before specific analysis, let's first clarify the definition of related variables. View mView: main View [DecorView] // generally add the main View "DecorView" to WindowManagerImpl (through addView) // WindowManagerImpl. java private void addView (View view...) {ViewRootImpl root; root = new ViewRootImpl (view. getContext ());... root. setView (view, wparams, panelParentView );...} <br> // ViewRootImpl. javapublic void setView (View view ....) {synchronized (this) {if (mView = null) {mView = view ;...}...}} therefore, mView is a variable of the DecorView type. view focused: View focused = mView. findFocus (); <br> // PhoneWindow. java private final class DecorView extends FrameLayout im Plements RootVie .... {...} <br> // FrameLayout. java public class FrameLayout extends ViewGroup {...} <br> // ViewGroup. java // mFocused records the currently selected view @ Override public View findFocus () {if (DBG) {System. out. println ("Find focus in" + this + ": flags =" + isFocused () + ", child =" + mFocused);} if (isFocused ()) {return this;} if (mFocused! = Null) {return mFocused. findFocus () ;}return null ;}so the final focused is the view with the focus on the current page. after specifying the relevant variables, we start to View v = focused. detailed analysis of focusSearch (direction. // View. javapublic View focusSearch (int direction) {// if a parent control exists, execute the focusSearch method of the parent control if (mParent! = Null) {return mParent. focusSearch (this, direction);} else {return null ;}// ViewGroup. java public View focusSearch (View focused, int direction) {// determines whether it is a top-level layout. If so, execute the corresponding method. If not, continue to look up, this section judges from the inside to the outside until the layout of the outermost layer ends. if (isRootNamespace () {return FocusFinder. getInstance (). findNextFocus (this, focused, direction);} else if (mParent! = Null) {return mParent. focusSearch (focused, direction);} return null;} indicates that in this process, the layout of the outermost layer is traversed from the layer, then the processing is handed over to the method in the FocusFinder in the outermost layout. focusFinder. getInstance (). findNextFocus (this, focused, direction); let's take a look at the specific operations of this method. // FocusFinder. javapublic final View findNextFocus (ViewGroup root, View focused, int direction) {return findNextFocus (root, focused, null, direction);} // FocusFinder. javatevate View f IndNextFocus (ViewGroup root, View focused, Rect focusedRect, int direction) {View next = null; if (focused! = Null) {next = findNextUserSpecifiedFocus (root, focused, direction);} if (next! = Null) {return next;} ArrayList <View> focusables = mTempList; try {focusables. clear (); root. addFocusables (focusables, direction); if (! Focusables. isEmpty () {next = findNextFocus (root, focused, focusedRect, direction, focusables) ;}} finally {focusables. clear ();} return next;} found that at the beginning of the execution process of findNextFocus, The findNextUserSpecifiedFocus (...) was first executed (...) the Code shows that this method first checks whether a specific Id value exists. If yes, the view corresponding to the Id is queried. in fact, these IDs are in xml via android: nextFocusUp = "... "or the focus sequence specified by the Code. therefore, in this process, first judge that, if any, the next focus has been found and a direct response is returned. // FocusFinder. javatevate View findNextUserSpecifiedFocus (ViewGro Up root, View focused, int direction) {// check for user specified next focus View userSetNextFocus = focused. findUserSetNextFocus (root, direction); if (userSetNextFocus! = Null & userSetNextFocus. isFocusable ()&&(! UserSetNextFocus. isInTouchMode () | userSetNextFocus. isFocusableInTouchMode () {return userSetNextFocus;} return null ;}< br> // View. javaView findUserSetNextFocus (View root, int direction) {switch (direction) {case FOCUS_LEFT: if (mNextFocusLeftId = View. NO_ID) return null; return findViewInsideOutShouldExist (root, mNextFocusLeftId); case FOCUS_RIGHT: if (mNextFocusRightId = View. NO_ID) return Null; return findViewInsideOutShouldExist (root, mNextFocusRightId); case FOCUS_UP: if (mNextFocusUpId = View. NO_ID) return null; return findViewInsideOutShouldExist (root, mNextFocusUpId); case FOCUS_DOWN: if (mNextFocusDownId = View. NO_ID) return null; return findViewInsideOutShouldExist (root, mNextFocusDownId); case FOCUS_FORWARD: if (mNextFocusForwardId = View. NO_ID) return null; return findV IewInsideOutShouldExist (root, mNextFocusForwardId); case FOCUS_BACKWARD: {if (mID = View. NO_ID) return null; final int id = mID; return root. findViewByPredicateInsideOut (this, new Predicate <View> () {@ Override public boolean apply (View t) {return t. mNextFocusForwardId = id ;}}) ;}return null;} if no query is found in the preceding process, findNextFocus (...) is executed (...) method. in this method, use offsetDescendantRectToMyCoords (...) method to obtain the position matrix of the focus control. however Then, the control of the next focus is obtained through comparison. For specific comparison rules, see findNextFocusInRelativeDirection (...) methods and findNextFocusInAbsoluteDirection (...) method. // FocusFinder. javatevate View findNextFocus (ViewGroup root, View focused, Rect focusedRect, int direction, ArrayList <View> focusables) {if (focused! = Null) {if (focusedRect = null) {focusedRect = mFocusedRect;} // fill in interesting rect from focused. getFocusedRect (focusedRect); root. reset (focused, focusedRect);} else {if (focusedRect = null) {focusedRect = mFocusedRect; // make up a rect at top left or bottom right of root switch (direction) {case View. FOCUS_RIGHT: case View. FOCUS_DOWN: setFocusTopLeft (root, focusedRect); break; case View. FOCUS_FORWARD: if (root. isLayoutRtl () {setFocusBottomRight (root, focusedRect);} else {setFocusTopLeft (root, focusedRect);} break; case View. FOCUS_LEFT: case View. FOCUS_UP: setFocusBottomRight (root, focusedRect); break; case View. FOCUS_BACKWARD: if (root. isLayoutRtl () {setFocusTopLeft (root, focusedRect);} else {setFocusBottomRight (root, focusedRect); break ;}}} switch (direction) {case View. FOCUS_FORWARD: case View. FOCUS_BACKWARD: return findNextFocusInRelativeDirection (focusables, root, focused, focusedRect, direction); case View. FOCUS_UP: case View. FOCUS_DOWN: case View. FOCUS_LEFT: case View. FOCUS_RIGHT: return second (focusables, root, focused, focusedRect, direction); default: throw new IllegalArgumentException ("Unknown direction:" + direction);} the process of finding the focus, mainly from the View's focusSearch (...) method, start from the current focus layer by layer, and finally execute the core method in the FocusFinder in the outermost layout to obtain the view of the next focus. if you need to specify a jump, you can perform the step-by-step focusSearch (...) returns a specific view.