我在Android中有一个活动,包含两个元素:

编辑文本列表视图

当“活动”启动时,EditText立即具有输入焦点(闪烁光标)。我不希望任何控件在启动时具有输入焦点。我尝试了:

EditText.setSelected(false);
EditText.setFocusable(false);

没有运气。如何说服EditText在“活动”启动时不选择自己?


当前回答

以下内容将阻止EditText在创建时获取焦点,但当您触摸它们时会抓住它。

<EditText
    android:id="@+id/et_bonus_custom"
    android:focusable="false" />

因此,在xml中将focusable设置为false,但关键是在java中,您可以添加以下侦听器:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

因为您返回的是false,即不使用事件,所以聚焦行为将照常进行。

其他回答

在父版面中写入此行。。。

 android:focusableInTouchMode="true"

简单可靠的解决方案,只需重写此方法:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    View v = getCurrentFocus();

    if (v != null &&
            (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) &&
            v instanceof EditText &&
            !v.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        v.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + v.getLeft() - scrcoords[0];
        float y = ev.getRawY() + v.getTop() - scrcoords[1];

        if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())
            hideKeyboard(this);
    }
    return super.dispatchTouchEvent(ev);
}

public static void hideKeyboard(Activity activity) {
    if (activity != null && activity.getWindow() != null && activity.getWindow().getDecorView() != null) {
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
    }
}

它可以通过继承EditText并重写onTouchEvent来实现。

class NonFocusableEditText: EditText {

    constructor(context: Context): super(context)
    constructor(context: Context, attrs: AttributeSet?): super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return if (isFocusable) super.onTouchEvent(event) else false
    }
}

然后,您可以像普通的EditText一样在版面中使用它:

<com.yourpackage.NonFocusableEditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"    
        android:hint="@string/your_hint"
        android:imeOptions="actionDone"
        android:inputType="textNoSuggestions" />

在onCreate()中禁用它

final KeyListener edtTxtMessageKeyListener = edtTxtMessage.getKeyListener();
edtTxtMessage.setCursorVisible(false);
edtTxtMessage.setKeyListener(null);

最后在EditText的onClick()中启用它

edtTxtMessage.setCursorVisible(true);
edtTxtMessage.setKeyListener(edtTxtMessageKeyListener);

但问题是,我们必须在第一次使用OnScreenKeyboard时单击两下。

@变通办法

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

也可以在onClick()中尝试:)

以下内容将阻止EditText在创建时获取焦点,但当您触摸它们时会抓住它。

<EditText
    android:id="@+id/et_bonus_custom"
    android:focusable="false" />

因此,在xml中将focusable设置为false,但关键是在java中,您可以添加以下侦听器:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

因为您返回的是false,即不使用事件,所以聚焦行为将照常进行。