1. 程式人生 > >Android EditText setFoucsable(true)無效、空指標問題

Android EditText setFoucsable(true)無效、空指標問題

前言

最近一個需求,未登入狀態點選評論框去登入,登入成功後回來評論框正常使用。

    // p層
    @Override
    public void initEditTextStatus() {
        if (UserRepository.getInstance().isSaleIdentity() || !UserRepository.getInstance().userIsLogin()){
            mView.setEditTextStatus(false);
        } else {
            mView.setEditTextStatus(true);
        }
    }


// p層調此方法
@Override
    public void setEditTextStatus(boolean enable) {
        // 主要加了這句程式碼
        etCommentContent.setFocusableInTouchMode(enable);
        etCommentContent.setFocusable(enable);
        etCommentContent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!UserRepository.getInstance().userIsLogin()) {
                    toLoginActivity();
                } else if (UserRepository.getInstance().isSaleIdentity()) {
                    toastMsg("銷售身份無法發表評論");
                }
            }
        });
    }
  • 一開始進去介面初始化的時候,這個編輯框的Focusable狀態是false
  • 登入回來去重置這個編輯框的狀態,setFocuable(true),無效,打個斷點,直接捕獲了一個空指標異常
  • 編輯框是空的,百思不得其解,介面又沒銷燬,怎麼能是空的呢,後來加個setFocusableInTouchMode()就ok了
  • 找下原始碼,不往深看,簡單看一下這三個方法
    public void setFocusable(boolean focusable) {
        setFocusable(focusable ? FOCUSABLE : NOT_FOCUSABLE);
    }

   
    public void setFocusable(@Focusable int focusable) {
        if ((focusable & (FOCUSABLE_AUTO | FOCUSABLE)) == 0) {
            setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
        }
        setFlags(focusable, FOCUSABLE_MASK);
    }

    
    public void setFocusableInTouchMode(boolean focusableInTouchMode) {
        // Focusable in touch mode should always be set before the focusable flag
        // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
        // which, in touch mode, will not successfully request focus on this view
        // because the focusable in touch mode flag is not set
        setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);

        // Clear FOCUSABLE_AUTO if set.
        if (focusableInTouchMode) {
            // Clears FOCUSABLE_AUTO if set.
            setFlags(FOCUSABLE, FOCUSABLE_MASK);
        }
    }

重點是這段註釋:

  •  // Focusable in touch mode should always be set before the focusable flag
  •  // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
  •  // which, in touch mode, will not successfully request focus on this view
  •  // because the focusable in touch mode flag is not set

用本人撇腳的英語翻譯一下就是:

  • 應該始終獲取焦點標誌前去設定在可觸控模式下聚焦
  • 否則,設定ficusable標誌將觸發focusableViewAvailable()
  • 所以在觸控模式下,將不會成功的請求到檢視的焦點
  • 因為沒有設定可觸控模式標誌中的可聚焦

所以說在調setFocusable之前得調一下setFocusableInTouchMode

最後

我被這個問題困擾了,而且不知道為啥,他就不管用,而且打斷點還空指標

現在是明白了,記錄一下,開發中遇到的坑。。。

如果幫到你給個贊~