API 28中如何在DialogFragment打开时让EditText获取焦点?

4

我希望能够在对话框显示时,将布局中的第一个 TextInputEditText 聚焦并自动显示软键盘。

我正在针对 API 级别 28 进行开发。

布局:

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/d_add_edit_name_til"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/activity_vertical_margin"
            android:layout_marginTop="@dimen/activity_vertical_margin"
            android:layout_marginEnd="@dimen/activity_vertical_margin"
            android:theme="@style/TextInputLayoutAppearance"
            >
            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/d_add_edit_name_et"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="User email"
                android:imeOptions="actionDone"
                android:inputType="textCapSentences"
                android:singleLine="true"
                android:focusableInTouchMode="true"
                android:focusable="true"
            >
                <requestFocus />
            </com.google.android.material.textfield.TextInputEditText>
        </com.google.android.material.textfield.TextInputLayout>

DialogFragment 代码:

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    return dialog;
}

....

@Override
public void onResume(){
    super.onResume();

    int dialogWidth = Functions.convertDpToPixel(300,activity);
    int dialogHeight = Functions.convertDpToPixel(250,activity);

    new Handler().post(() -> {
        getDialog().getWindow().setLayout(dialogWidth, dialogHeight);
    });
}

这个帖子中提供的答案帮助我解决了API < 28的问题。

Android 9版本更改文档中,我知道:

此外,活动不再在触摸模式下隐式分配初始焦点。相反,如果需要,您需要显式请求初始焦点。

其中一种显式请求初始焦点的方法(在这里讨论)是在EditText中添加<requestFocus />标签,但是对于API级别28和DialogFragment仍然没有成功。

*请注意,DialogFragment来自andoridx库(androidx.fragment.app.DialogFragment)

还有其他人遇到这个问题吗?

编辑: 我唯一成功的方法是在onViewCreated添加以下代码:

    new Handler().postDelayed(() -> {
        nameEt.requestFocus();
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(nameEt, InputMethodManager.SHOW_IMPLICIT);
    },200);

我认为这不是一个有效的答案,因为在这种方式下使用线程会使代码变得不可预测。仍在等待好的答案。

onShowListener中尝试使用此代码 - ADM
3个回答

1
使用 OnGlobalLayoutListener 替代 Handler
nameEt.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener{
            override fun onGlobalLayout() {
                nameEt.viewTreeObserver.removeOnGlobalLayoutListener(this)
                nameEt.requestFocus()
            }
        })

在这种情况下,您不需要额外显式调用 dialog.getWindow().setSoftInputMode(..)

0
EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

0
TextInputEditText textInputEditText= (TextInputEditText) findViewById(R.id.d_add_edit_name_et);
textInputEditText.requestFocus();

2
任何解释(文本)都将不胜感激。 - Pochmurnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接