use*_*652 65 android dialog dialogfragment
我有一个浮动对话框的对话框片段,其中包含一个特殊的键盘,当用户按下EditText字段时会弹出(正常的IME停止显示).
当用户按下后退按钮(就像使用普通的IME服务一样)时,我希望键盘被解除(visibility = GONE),但对话框仍然可见.然而,就我在SO和其他地方的相当广泛的阅读中所看到的,似乎没有办法做到这一点.
如果我将对话框设置为不可取消,那么我不会被onCancel()或onDismiss()通知,因为该对话框不可取消.
如果我将对话框设置为可取消,则会收到通知,但对话框将被取消.
我无法将onKeyListener附加到片段中的对话框,因为它被系统替换,以便片段可以处理对话框的生命周期.
有没有办法做到这一点?或者,为了Fragment系统的目的,是否可以访问完全围起来的关键事件的检测?
小智 142
最好的方法和最干净的方法是在onCreateDialog()中创建的对话框中覆盖onBackPressed().
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), getTheme()){
@Override
public void onBackPressed() {
//do your stuff
}
};
}
Run Code Online (Sandbox Code Playgroud)
Jua*_*nez 66
我遇到了与你相同的问题,我已经修复了将onKeyListener附加到dialogfragment的问题.
在onResume()DialogFragment扩展的类的方法中放置这些代码:
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//Hide your keyboard here!!!
return true; // pretend we've processed it
}
else
return false; // pass on to be processed as normal
}
});
Run Code Online (Sandbox Code Playgroud)
在这里你可以找到的一个问题是这个代码将被执行两次:一个是用户按下后退按钮而另一个是当他离开按下它时.在这种情况下,您必须按事件过滤:
@Override
public void onResume() {
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,
android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//This is the filter
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
else
{
//Hide your keyboard here!!!!!!
return true; // pretend we've processed it
}
}
else
return false; // pass on to be processed as normal
}
});
}
Run Code Online (Sandbox Code Playgroud)
Bra*_*don 18
作为Juan Pedro Martinez的回答的补遗,我认为在查看这个帖子时澄清一个特定的问题(我有一个问题)会很有帮助.
如果你想创建一个新的DialogFragment,并且让用户只能使用后退按钮取消它,这会消除随机屏幕触摸过早取消片段,那么这就是你要使用的代码.
在您调用DialogFragment的代码中,您需要将可取消设置设置为false,以便NOTHING解散片段,不会出现杂散屏幕触摸等.
DialogFragment mDialog= new MyDialogFragment();
mDialog.setCancelable(false);
mDialog.show(getFragmentManager(), "dialog");
Run Code Online (Sandbox Code Playgroud)
然后,在DialogFragment中,在本例中为MyDaialogFragment.java,添加onResume覆盖代码以使对话框侦听后退按钮.当它被按下时,它将执行dismiss()来关闭片段.
@Override
public void onResume()
{
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog,
int keyCode,android.view.KeyEvent event)
{
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;
}
});
Run Code Online (Sandbox Code Playgroud)
现在你的对话框将被调用"setCancelable"为false,这意味着什么都没有(没有外部点击)可以取消它并关闭它,并允许(从对话框本身内)只有后退按钮关闭它.
Ganbatte!
小智 9
怎么没有人建议这个?
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// Add back button listener
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {
// getAction to make sure this doesn't double fire
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_UP) {
// Your code here
return true; // Capture onKey
}
return false; // Don't capture
}
});
return dialog;
}
Run Code Online (Sandbox Code Playgroud)
小智 8
使用Fragment onCancel覆盖方法。按下时会调用它。这是一个示例:
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
// Add you codition
}
Run Code Online (Sandbox Code Playgroud)
由于AppCompat 1.5.0-alpha01 AppCompatDialog现在正在扩展ComponentDialog(来源)。这意味着DialogFragment您现在可以轻松地(从片段的对话框中)获得一个有效的值OnBackPressedDispatcher,允许您自己处理后退按键。
科特林:
class MyFragment: androidx.fragment.app.DialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
(dialog as androidx.activity.ComponentDialog)
.onBackPressedDispatcher
.addCallback(viewLifecycleOwner) {
// handle back press
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:当您添加回调时,它可以防止通过按“后退”自动关闭/取消对话框。
创建对话框时,覆盖 onBackPressed 和 onTouchEvent :
final Dialog dialog = new Dialog(activity) {
@Override
public boolean onTouchEvent(final MotionEvent event) {
//note: all touch events that occur here are outside the dialog, yet their type is just touching-down
boolean shouldAvoidDismissing = ... ;
if (shouldAvoidDismissing)
return true;
return super.onTouchEvent(event);
}
@Override
public void onBackPressed() {
boolean shouldAvoidDismissing = ... ;
if (!shouldSwitchToInviteMode)
dismiss();
else
...
}
};
Run Code Online (Sandbox Code Playgroud)
防止取消 DialogFragment:
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.setOnKeyListener { dialog, keyCode, event ->
keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
43168 次 |
| 最近记录: |