本篇记录下Android软键盘的简单使用和一些注意事项,包括如何获取软键盘输入内容、打开弹窗自动进入编辑状态。
软键盘简单使用
软键盘可以通过InputMethodManager来控制键盘的显示和隐藏状态,键盘输入内容可以通过重写dispatchKeyEvent()方法来获取。
<activity_main.xml>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="show"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hide"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<MainActivity.kt>
class MainActivity : AppCompatActivity() {
private lateinit var imm : InputMethodManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
show.setOnClickListener {
// 显示软键盘
imm.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT)
}
hide.setOnClickListener {
// 隐藏软键盘
imm.toggleSoftInput(0, 0)
}
}
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
Log.d("MainActivity", "dispatchKeyEvent = $event ")
if (event != null) {
text.text = event.characters
}
return super.dispatchKeyEvent(event)
}
}
打开弹窗进入编辑状态
编辑弹窗在一打开的时候自动拉起软键盘,可以给用户提供更好的体验,比如修改密码时,打开弹窗无需点击编辑框,直接输入内容,体验感会更好。
接下来实现功能:进入编辑弹窗,EditText获取焦点,软键盘显示。
1. 首先编辑好Dialog的布局文件<dialog_layout.xml>
Dialog包含一个EditText和一个关闭按钮。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/dismiss_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="dismiss"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<EditText
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入内容"
android:textSize="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2. 自定义DialogFragment<MyDialogFragment.java>
其中编写了一个startEdit方法,功能就是为传入的view获取焦点,并显示软键盘。
public class MyDialogFragment extends DialogFragment {
@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_layout, container, false);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// 点击外部区域是否dismiss dialog
dialog.setCanceledOnTouchOutside(false);
// 设置背景
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.GREEN));
return dialog;
}
@Override
public void onStart() {
super.onStart();
Window window = getDialog().getWindow();
// 设置dialog宽高
window.setLayout(500, 300);
// 设置dialog显示位置
window.setGravity(Gravity.CENTER);
}
private void initView(View view){
EditText editText = view.findViewById(R.id.edit);
startEdit(editText);
view.findViewById(R.id.dismiss_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
}
// 获取焦点,显示软键盘
private void startEdit(View view){
view.requestFocus();
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
3. 在主程序中触发弹窗<MainActivity.java>
在MainActivity中添加一个按钮,点击按钮显示编辑弹窗MyDialogFragment。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(getSupportFragmentManager(), "test_dialog");
}
});
}
}
4. 问题:功能未实现
运行程序之后发现,打开弹窗并未显示软键盘,但当在MyDialogFragment中添加按钮来调用startEdit()方法时,方法是可以实现的,EditText获取了焦点,软键盘也正常显示出来了。
这可能是由于在MyDialogFragment刚打开时布局还没有完全初始化就调用startEdit()方法,导致方法未实现,修改MyDialogFragment中的initView,延迟一段时间再调用startEdit()方法就可以实现显示软键盘的效果。
private void initView(View view){
EditText editText = view.findViewById(R.id.edit);
// 添加延迟任务来确保视图已经初始化好
new Handler().postDelayed(() -> {
// 获取焦点,显示软键盘
startEdit(editText);
}, 500);
view.findViewById(R.id.dismiss_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
}
在MyDialogFragment销毁时记得要释放Handler资源。