android中调用requestFocus()的详细过程

view中
        
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
        return requestFocusNoSearch(direction, previouslyFocusedRect);
        }

private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
        // need to be focusable  
        if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
        (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
        return false;
        }

        // need to be focusable in touch mode if in touch mode  
        if (isInTouchMode() &&
        (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
        return false;
        }

        // need to not have any parents blocking us  
        if (hasAncestorThatBlocksDescendantFocus()) {//判断父视图是否阻止子视图获得焦点  
        return false;
        }

        handleFocusGainInternal(direction, previouslyFocusedRect);//进行具体的焦点获取  
        return true;
        }
        
        void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
        if (DBG) {
        System.out.println(this + " requestFocus()");
        }

        if ((mPrivateFlags & FOCUSED) == 0) {
        mPrivateFlags |= FOCUSED;

        if (mParent != null) {
        mParent.requestChildFocus(this, this);//第一个参数是child视图,第二个是focused视图,该函数内部进行递归调用  
        }
        //注意时态,xxxed()和xxx()的区别是,前者是执行完之后回调,后者是在执行前回调  
        onFocusChanged(true, direction, previouslyFocusedRect);
        refreshDrawableState();

        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
        notifyAccessibilityStateChanged();
        }
        }
        }
        一般来说,父视图是ViewGroup,requestChildFocus在ViewGroup中的实现
        
public void requestChildFocus(View child, View focused) {
        if (DBG) {
        System.out.println(this + " requestChildFocus()");
        }
        if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) {
        return;
        }

        // Unfocus us, if necessary  
        super.unFocus();

        // We had a previous notion of who had focus. Clear it.  
        if (mFocused != child) {
        if (mFocused != null) {
        mFocused.unFocus();
        }

        mFocused = child;
        }
        if (mParent != null) {
        mParent.requestChildFocus(this, focused);//最终会递归到ViewRoot中的equestChildFocus  
        }
        }
        ViewRootImpl中的requestChildFocus
        
public void requestChildFocus(View child, View focused) {
        checkThread();//确保在UI线程中  
        if (mFocusedView != focused) {//其实ViewGroup中已经检查过,mFocusedView一定不是目标焦点视图  
        mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused);
        scheduleTraversals();//发起View遍历请求  
        }
        mFocusedView = mRealFocusedView = focused;
        if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now "
        + mFocusedView);  view中
        
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
        return requestFocusNoSearch(direction, previouslyFocusedRect);
        }

private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
        // need to be focusable  
        if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
        (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
        return false;
        }

        // need to be focusable in touch mode if in touch mode  
        if (isInTouchMode() &&
        (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
        return false;
        }

        // need to not have any parents blocking us  
        if (hasAncestorThatBlocksDescendantFocus()) {//判断父视图是否阻止子视图获得焦点  
        return false;
        }

        handleFocusGainInternal(direction, previouslyFocusedRect);//进行具体的焦点获取  
        return true;
        }
        
        void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
        if (DBG) {
        System.out.println(this + " requestFocus()");
        }

        if ((mPrivateFlags & FOCUSED) == 0) {
        mPrivateFlags |= FOCUSED;

        if (mParent != null) {
        mParent.requestChildFocus(this, this);//第一个参数是child视图,第二个是focused视图,该函数内部进行递归调用  
        }
        //注意时态,xxxed()和xxx()的区别是,前者是执行完之后回调,后者是在执行前回调  
        onFocusChanged(true, direction, previouslyFocusedRect);
        refreshDrawableState();

        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
        notifyAccessibilityStateChanged();
        }
        }
        }
        一般来说,父视图是ViewGroup,requestChildFocus在ViewGroup中的实现
        
public void requestChildFocus(View child, View focused) {
        if (DBG) {
        System.out.println(this + " requestChildFocus()");
        }
        if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) {
        return;
        }

        // Unfocus us, if necessary  
        super.unFocus();

        // We had a previous notion of who had focus. Clear it.  
        if (mFocused != child) {
        if (mFocused != null) {
        mFocused.unFocus();
        }

        mFocused = child;
        }
        if (mParent != null) {
        mParent.requestChildFocus(this, focused);//最终会递归到ViewRoot中的equestChildFocus  
        }
        }
        ViewRootImpl中的requestChildFocus
        
public void requestChildFocus(View child, View focused) {
        checkThread();//确保在UI线程中  
        if (mFocusedView != focused) {//其实ViewGroup中已经检查过,mFocusedView一定不是目标焦点视图  
        mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused);
        scheduleTraversals();//发起View遍历请求  
        }
        mFocusedView = mRealFocusedView = focused;
        if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now " + mFocusedView);  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值