Android 14模拟器中Xamarin自定义AlertDialog二次打开后键盘失效问题
自定义AlertDialog在Android 14模拟器上的键盘交互问题
应用类型与测试环境
- Android应用类型:Xamarin.Forms应用、Xamarin.Android应用
- 受影响平台:Android 14模拟器(Pixel 7 Pro)
- 无问题测试平台:Android 13模拟器(Pixel 5)、Android 9模拟器(Pixel 2)、Android 14设备(Samsung S21FE)、Android 13设备(S20FE)
问题描述
使用AlertDialog中的EditText时,第二次打开弹窗后系统内置键盘可见但无法进行交互操作。
重现步骤
- 打开测试应用
- 点击“打开对话框”按钮
- 在EditText中输入任意内容并点击“确定”
- 此时键盘可见但无法交互
自定义AlertDialog代码
CustomAlertDialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:id="@+id/contentview" android:padding="15dp" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/headerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Title" android:textStyle="bold" android:textSize="20dp" android:textColor="@android:color/black"/> <android.support.design.widget.TextInputLayout android:id="@+id/textinputlayout" android:layout_width="match_parent" android:layout_height="50dp"> <EditText android:id="@+id/passwordedit" android:hint="Edit" android:layout_width="match_parent" android:layout_height="50dp" android:password="true" android:textStyle="normal" android:textSize="15dp" android:layout_marginLeft="-5dp" android:inputType="textPassword"/> </android.support.design.widget.TextInputLayout> <TextView android:id="@+id/errorview" android:text="Error" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/holo_red_dark" android:visibility="invisible" /> <LinearLayout android:id="@+id/footerview" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" android:gravity="right" android:paddingRight="-15dp"> <Button android:id="@+id/cancelbutton" android:text="Cancel" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@android:color/transparent" android:textColor="#0080eb"/> <Button android:id="@+id/okbutton" android:text="Ok" android:layout_width="70dp" android:layout_height="match_parent" android:enabled="false" android:textColor="@android:color/darker_gray" android:background="@android:color/transparent" /> </LinearLayout> </LinearLayout>
CustomAlertDialog.cs
using Android.App; using Android.Content; using Android.Graphics.Drawables; using Android.OS; using Android.Runtime; using Android.Views; using Android.Views.InputMethods; using Android.Widget; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AlertDialogIssue { internal class CustomAlertDialog : LinearLayout, IDisposable { private Context mainContext; private LinearLayout contentView; private AlertDialog passwordDialog; private AlertDialog.Builder alertbuilderpassword; internal bool isPasswordDialogAppearing = false; private View currentView; private EditText passwordEdit; private Button okButton; private Button cancelButton; private TextView headerView; private LayoutInflater inflater; internal CustomAlertDialog(Context context) : base(context) { mainContext = context; inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService); View view = inflater.Inflate(Resource.Layout.CustomAlertDialog, this, true); InflateView(view); } internal void InflateView(View view) { currentView = view; contentView = view.FindViewById<LinearLayout>(Resource.Id.contentview); headerView = view.FindViewById<TextView>(Resource.Id.headerView); passwordEdit = view.FindViewById<EditText>(Resource.Id.passwordedit); okButton = view.FindViewById<Button>(Resource.Id.okbutton); cancelButton = view.FindViewById<Button>(Resource.Id.cancelbutton); InitializePasswordView(); DisplayAlertDialog(); } internal void InitializePasswordView() { passwordEdit.TextChanged += PasswordEdit_TextChanged; passwordEdit.KeyPress += PasswordEdit_KeyPress; okButton.Click += OkButton_Click; cancelButton.Click += CancelButton_Click; } internal void ShowPasswordInputDialog() { if (passwordDialog != null) { passwordDialog.Dismiss(); } if (!isPasswordDialogAppearing) { passwordDialog.Show(); isPasswordDialogAppearing = true; } } internal void DisplayAlertDialog() { alertbuilderpassword = new AlertDialog.Builder(mainContext); alertbuilderpassword.SetView(currentView); alertbuilderpassword.SetCancelable(false); passwordDialog = alertbuilderpassword.Create(); passwordDialog.Window.SetSoftInputMode(SoftInput.StateAlwaysVisible); passwordDialog.Window.SetLayout(400, 400); } private void CancelButton_Click(object sender, EventArgs e) { passwordDialog.Dismiss(); isPasswordDialogAppearing = false; } private void OkButton_Click(object sender, EventArgs e) { passwordDialog.Dismiss(); passwordDialog.Show(); passwordEdit.SetSelectAllOnFocus(true); passwordEdit.SetSelection(passwordEdit.Length()); passwordEdit.SelectAll(); } private void PasswordEdit_KeyPress(object sender, KeyEventArgs e) { if (e.KeyCode == Keycode.Enter) { passwordDialog.Dismiss(); } else if (e.KeyCode == Keycode.Back) { passwordDialog.Dismiss(); } else if (e.KeyCode == Keycode.Del) { if (!string.IsNullOrEmpty(passwordEdit.Text)) { string tempString = passwordEdit.Text; if (passwordEdit.HasSelection) { passwordEdit.Text = string.Empty; } else { passwordEdit.Text = tempString.Remove(tempString.Length - 1); int position = passwordEdit.Length(); passwordEdit.SetSelection(position); } } } } private void PasswordEdit_TextChanged(object sender, global::Android.Text.TextChangedEventArgs e) { okButton.Enabled = true; } } }
弹窗调用方式
在主Activity中通过以下代码调用自定义弹窗:
customAlertDialog.ShowPasswordInputDialog();
临时解决方法
移除DisplayAlertDialog方法中的passwordDialog.Window.SetSoftInputMode(SoftInput.StateAlwaysVisible);可避免键盘无法交互的问题,但弹窗再次打开时不会自动唤起键盘。
需求
寻求自定义AlertDialog打开关闭的替代方案,或该BUG的有效上报途径(已尝试Xamarin及微软问答平台,均未被认定为官方问题)。
内容的提问来源于stack exchange,提问作者ManojSF3414
相关产品推荐
相关产品推荐

