android - 回按时Android隐藏键盘并关闭bottomsheetfragment
问题描述
我在bottomsheetfragment
通过单击后隐藏键盘和键盘时遇到问题。当前的实现要求用户单击两次以关闭键盘和底页。
我实现setOnKeyListener
但第一次后退单击隐藏键盘和第二次单击触发后退事件
对话风格
<style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
class CommentInputFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NORMAL, R.style.BottomSheetDialog);
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
var view= inflater.inflate(R.layout.fragment_comment_input, container, false)
return view;
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
var dialog= super.onCreateDialog(savedInstanceState)
return dialog
}
override fun onResume() {
super.onResume()
dialog?.setOnKeyListener(object: DialogInterface.OnKeyListener
{
override fun onKey(p0: DialogInterface?, keyCode: Int, p2: KeyEvent?): Boolean {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
// To dismiss the fragment when the back-button is pressed.
dismiss();
return true;
}
// Otherwise, do nothing else
else return false;
}
})
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
et_add_comment.requestFocus();
}
}
解决方案
问题:
如果您注意到后退箭头指向底部(在最近的设备中)而不是左侧,则在这种情况下,对话框不会拦截后按,因为它是由软键盘触发的。dialog?.setOnKeyListener
因此不会触发的回调。
所以,你需要通过一些键盘监听器来拦截按键事件;好吧,对于这里和那里的许多帖子来说,这是一个挑战,并且每个解决方案都可以在特定情况下工作。
解决方案
当被调用时,我们将ViewGroup
在BottomSheetFragment
布局的根 ( R.layout.fragment_comment_input
)中注册一个监听器。dispatchKeyEventPreIme()
这会为附加到此布局的关键事件调用。
创建监听器:
interface OnBackPressListener {
fun onBackPressed(event: KeyEvent)
}
因此,作为根目录FrameLayout
,然后对其进行自定义:
class DispatchKeyFrameLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private var listener: OnBackPressListener? = null
fun setOnBackPressListener (listener: OnBackPressListener) {
this.listener = listener
}
override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
// Trigger the listener callback
listener?.onBackPressed(event)
return super.dispatchKeyEventPreIme(event)
}
}
并将其用作以下中的根布局R.layout.fragment_comment_input
:
<com.example.kotlintest.DispatchKeyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Other views-->
</com.example.kotlintest.DispatchKeyFrameLayout>
然后将侦听器设置BottomSheetFragment
onResume()
为关闭对话框。
override fun onResume() {
super.onResume()
layout.setOnBackPressListener(object : OnBackPressListener{
override fun onBackPressed(event: KeyEvent) {
if (event.keyCode == android.view.KeyEvent.KEYCODE_BACK)
dismiss()
}
})
}
现在您可以安全地删除dialog?.setOnKeyListener
预习:
推荐阅读
- php - 在php中使用命名空间的变量类名
- c++ - 如何将 int 数组转换为 OpenSSL BIGNUM?
- javascript - 通过 request.body 将元数据添加到 GridFS 文件
- python - 根据条件 Python Pandas 删除行
- c# - 如何在 XML 序列化中省略前缀
- python - ImportError:烧瓶应用程序中没有名为“Adafruit_DHT”的模块
- django - Nginx+Django 错误:ERR_TOO_MANY_REDIRECTS 或 502 Bad Gateway
- python - 如何将 tensorflow.metrics.x 与 SummarySaverHook 和 Estimator 一起使用?
- amazon-dynamodb - 使用分层键保存数据或复制 DynamoDB 表中的数据
- python - 有没有一种简单的方法来计算非简单自相交曲线的轮廓?