Android之輸入框光標和Hint的位置


如圖所示,要實現這一的需求,一般人的布局方式就是左邊一button,右邊一button,中間一個EditText,為了輸入框的響應觸摸范圍更大往往不會把寬度設置為wrap_content,要么設置成match_parent/fill_parent要么給定個minWidth+wrap_content。

無論如何布局,gravity或layout_gravity都應是center才能達到需求所示。然而問題來了,如果gravity設置為了center,很不巧的是大部分手機(筆者某為竟然會自動糾正光標與hint的相對位置)實際運行效果是光標會位於hint的中間,要知道gravity會影響到光標所在位置,gravity為Left光標就在最左邊,graity為right光標就在Hint的最右邊,當然gravity為Center光標自然在hint的中間。

借圖一張(來自萬能的StackOverFlow,可惜萬能的SOF也沒給出答案)

 

遂冥思苦想各種彌救方法,主要有3個方案兩個角度來解決。完美的角度是把光標位置想法設法調正,退而求其次的方法是顯示hint(即輸入框沒有text)的時候隱藏光標。方案觸發點有兩個,一個是第一次沒有任何text但設置了hint此時,入口應為onFocusChange方法;另一個是動態輸入過程中清除了text,這個入口在onTextChange。

我總結出來有三個對策如下。

下策:當需要顯示hint的時候把hint設置為空字符串,不需要顯示hint的時候再把hint還原成需要設置的字符串。這種方法帶來的效果就是,界面一打開能看見hint,當你一點擊輸入框開始輸入就沒有hint了,雖然此時光標可見,但還是有瑕疵,並且在onFocusChange方法里面設置hint會造成要點兩次才會彈起輸入法(具體原因尚未深究)。

中策:當需要顯示hint的時候隱藏光標,一旦用戶開始輸入顯示光標。這種效果類似第一種,一打開界面能看見hint,但看不到光標,你要開始輸入才能看見。這也是有瑕疵的,當用戶點了輸入框(獲得用戶焦點)沒有光標用戶就會很郁悶不知道可不可以輸入,缺乏光標的引導作用。

上策:那上策就是調整位置咯,其實也不是說能調整光標的位置,而是逆向思維把輸入框的位置改變來適用光標所需要擺在的位置。這種方案實現起來有點復雜,改動量大。首先你EditTextd的寬度不能指定,minWidth不能由輸入框來設置而要在它的parent容器設置最小寬度,所以它的width最好是wrap_content,並且設置一定的padding來保留一定用戶觸摸響應區域。然后EditText的Gravity還是Center,需要調整的就是它的LayoutGravity了,當用戶有輸入毫無疑問需要居中,當沒有輸入需要顯示Hint時,那就要設置成Left了,然后計算出需要設置marginLeft距離。這個距離就是EditText(父容器的寬度-hint的寬度)/2,當然要獲取LayoutWdth需要一定的技巧,獲取hint的寬度更需要一點技巧。這樣就能讓光標位於hint的前面了,曲線救國吧。

干貨來了。

android要獲取寬高經常能拿到0這個值,這個一般有經驗的都會在onWindowsFocus里去拿到,然后量字符串的像素,就需要你要用你顯示hint的畫筆去測量字符串,因為需要知道字體屬性,比如字體、大小、粗細等。

直接上代碼咯:

@Override
  public void onWindowFocusChanged(boolean hasWindowFocus) {
   super.onWindowFocusChanged(hasWindowFocus);
        if (mSpaceWidth <= 0) mSpaceWidth = getWidth() - left.getWidth() - right.getWidth();
    }

@Override
public void onFocusChange(View v, boolean hasFocus) {
        adjustCursorPosition(etInput.getText());
    }

@Override
public void afterTextChanged(Editable s) {
        adjustCursorPosition(etInput.getText());
    }

private void adjustCursorPosition(CharSequence text){
        if (!TextUtils.isEmpty(etInput.getHint())){
            adjustGravityForCursor(text);//adjustCursorVisible(text);//adjustHintContent(hasFocus(),text);
        }
    }

    private void adjustGravityForCursor(CharSequence text) {
        LayoutParams lp = (LayoutParams) etInput.getLayoutParams();
        if (mSpaceWidth <= 0) mSpaceWidth = lp.width - left.getWidth() - right.getWidth();
        if (!TextUtils.isEmpty(text)) {
            etInput.setGravity(Gravity.CENTER);
            lp.leftMargin = 0;
        } else {
            etInput.setGravity(Gravity.LEFT);
            lp.leftMargin = (mSpaceWidth - measureText(etInput,mHint)) / 2;
        }
        etInput.setLayoutParams(lp);
    }

    public int measureText(TextView textView, String text) {
        TextPaint paint = textView.getPaint();
        return (int) paint.measureText(text);
    }

    private void adjustCursorVisible(CharSequence text){
        etInput.setCursorVisible(!TextUtils.isEmpty(text));
    }

    private void adjustHintContent(boolean hasFocus, CharSequence text){
        if (TextUtils.isEmpty(text)) {
            etInput.setHint(hasFocus ? "" : mHint);
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM