鍍金池/ 問答/Android  網(wǎng)絡(luò)安全/ Android EditText 光標(biāo)顯示在結(jié)尾處問題

Android EditText 光標(biāo)顯示在結(jié)尾處問題

需求

  1. 進入頁面時,EditText不自動獲取焦點(沒有光標(biāo)顯示)
  2. 第一次點擊EditText區(qū)域時,光標(biāo)顯示在結(jié)尾處,并且出現(xiàn)軟鍵盤
  3. 第二次點擊EditText指定位置,光標(biāo)移動到指定位置,用戶進行編輯

代碼

  • 布局
<RelativeLayout
    android:focusable="false"
    android:focusableInTouchMode="true">
    
    <EditText android:background="@null" />
    
</RelativeLayout>

效果

  • 實現(xiàn)了 需求:1
  • 第一次點擊EditText區(qū)域時,鍵盤顯示,但是光標(biāo)位置是用戶點擊的位置,不在結(jié)尾處,除非用戶點擊的位置就是結(jié)尾處。

問題

  • 如何實現(xiàn) 需求:2
回答
編輯回答
久舊酒

問題已經(jīng)解決了

這個問題的 關(guān)鍵點setSelection() 方法的執(zhí)行時機

先說下如何解決

  • 布局中不需要做任何多余的設(shè)置
<RelativeLayout
    <!-- 這兩個設(shè)置不需要了,因為接下來要在程序總設(shè)定 -->
    android:focusable="false"
    android:focusableInTouchMode="true" />
    <EditText />
</RelativeLayout>
  • Java代碼部分
public class MainActivity extends AppCompatActivity {
    private boolean isFirst = true; // 是否是第一次點擊 EditText
    private InputMethodManager mIMM; // 第一次點擊時,軟鍵盤不自動彈出,所以要手動彈出
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mIMM = (InputMethodManager) (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        mEditText = findViewById(R.id.xxx);
        
        // 關(guān)鍵部分
        mEditText.setFocusable(false);
        mEditText.setOnClickListener( v -> {
            if(isFirst) {
                mEditText.setFocusableInTouchMode(true);
                mEditText.requestFocus();
                mEditText.setSelection(mEditText.getText().length());
                mIMM.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                isFirst = false;
            }
        });
    }
}

再說下嘗試的過程

1. 直接設(shè)置 setSelection()

因為之前設(shè)置了 android:focusabelInTouchMode="true",所以直接設(shè)置是沒有效果的,第一次點擊EditText區(qū)域,會自動彈出軟鍵盤,并且光標(biāo)位置是手指點擊的位置

2. 自定義 EditText,重寫 onSelectionChanged(int selStart, int selEnd)方法

這個方法感知光標(biāo)位置的變化,編寫如下代碼,可控制光標(biāo)始終在結(jié)尾處:

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
            if (selStart == selEnd) { // 不考慮多個文字被選中
                setSelection(getText().length());
            }
    }

這個方法的執(zhí)行時機在自定義EditText對象初始化之前,并且在沒點擊之前,或者點擊時會多次執(zhí)行該方法,不好控制是否是第一次點擊。因此也沒有嘗試成功

總結(jié)

不知道有沒有更好的解決方案?期待你的回答。


2018-05-28 補充

實際項目總可能會遇到一個頁面中有多個EditText,那么 isFirstTouch 就可能被多個EditText共用,如果有這個問題存在的話,一種解決方案是自定義EditText:

public class MyEditText extends EditText {
    private boolean isFirstTouch = true;
    // 構(gòu)造方法中調(diào)用 init() 方法
    private void init() {
        post( () -> {
            setFocusable(false);
            if(isFirst) {
                setFocusableInTouchMode(true);
                requestFocus();
                setSelection(mEditText.getText().length());
                inputMethodManger.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                isFirst = false;
            }
        });
    }
}
2017年12月26日 11:56
編輯回答
尐潴豬

EditText有個setSelection方法,應(yīng)該可以滿足你的需求

2017年5月23日 06:54