Fel*_*das 6 android modal-dialog android-fragments
我知道这个问题已经在这里多次询问,但是在花了最后1.5小时阅读并试图解决我的问题后,我不能.
问题陈述:
setStyle
在DialogFragment
i中调用方法时,会在标题中声明RuntimeException错误.
这是我的原始代码,它不会抛出此异常:
public class MapDialogFragment extends DialogFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.maps_dialog, container, false);
return view;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我刚刚在我的应用程序中添加了ImmersiveMode.正如你们中的一些人可能知道的那样,沉浸式模式在显示Dialogs时会丢失,因此必须覆盖这些片段并设置适当的标志以保持模式.我成功地完成了这项工作 - 它有效.但是,我必须评论一下:setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
所以我失去了对话框的风格,这就是问题所在.
仔细看看setStyle
DialogFragment 中的方法,我无法真正看到如何requestFeature()
调用它:
public void setStyle(int style, int theme) {
mStyle = style;
if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
mTheme = com.android.internal.R.style.Theme_DeviceDefault_Dialog_NoFrame;
}
if (theme != 0) {
mTheme = theme;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是我的DialogFragment类,其中发生异常.注意getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
以及clearFlag,它们是使ImmersiveMode工作所必需的(希望这对某人有用):
public class MapDialogFragmentv2 extends DialogFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
//I have also tried the code here, before the super.OnCreate but to no avail
//setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
super.onCreate(savedInstanceState);
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
MyDialog mDialog = new MyDialog(getActivity());
mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
view = getActivity().getLayoutInflater().inflate(R.layout.maps_dialog, null);
//Line below throws exception. Needs to be commented out
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
mDialog.setContentView(view);
return mDialog;
}
public class MyDialog extends Dialog {
public MyDialog(Context context) {
super(context);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
getWindow().getDecorView().setSystemUiVisibility(MainActivity.getImmersiveModeFlags());
}
@Override
public void show() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
super.show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在使用的混合也试过onCreate
,onCreateView
而且onCreateDialog
但没有奏效.我还在Stackoverflow上看到有人评论说同时拥有onCreateView和onCreateDialog并不是一个好主意.
并尝试将样式添加到我的xml布局本身,但也没有工作:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/lib/com.google.android.gms.plus"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/transparent"
style="@android:style/Theme.Holo.Dialog" >
Run Code Online (Sandbox Code Playgroud)
谢谢
问题在于,您将太多不同的东西混合在一起,并且您不尊重每个类的生命周期.
首先,你需要像你一样停止嵌套类.这部分是错误的根源.如果你真的想/有嵌套Fragment
或Dialog
则你声明嵌套是很重要的Fragments
,Dialogs
因为静态的.如果您不将它们声明为静态,则可能导致内存泄漏和类似您的问题.但是你能做的最好的事情就是每个文件只限制一个类,除非你有实际的理由来嵌套它.这还有一个额外的好处,即提高代码的可读性和可维护性.
但是你的错误的主要原因是你完全忽略了生命周期Dialog
.几乎所有以下代码都应该在以下的适当生命周期方法中Dialog
:
mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
view = getActivity().getLayoutInflater().inflate(R.layout.maps_dialog, null);
//Line below throws exception. Needs to be commented out
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
mDialog.setContentView(view);
Run Code Online (Sandbox Code Playgroud)
因此,要修复错误,您需要做3件事:
像这样声明MapDialogFragmentv2
和MyDialog
静态:
public class MainActivity extends Activity {
...
public static class MapDialogFragmentv2 extends Fragment {
...
public static class MyDialog extends Dialog {
...
}
}
}
Run Code Online (Sandbox Code Playgroud)或者甚至更好地将它们一起移动到自己的文件中.
从移动代码onCreateDialog()
在MapDialogFragmentv2
在正确的生命周期方法MyDialog
.它应该看起来像这样:
public static class MyDialog extends Dialog {
private final LayoutInflater mInflater;
public MyDialog(Context context) {
super(context);
mInflater = LayoutInflater.from(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
getWindow().getDecorView().setSystemUiVisibility(MainActivity.getImmersiveModeFlags());
View view = mInflater.inflate(R.layout.maps_dialog, null);
setContentView(view);
}
@Override
public void show() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
super.show();
}
}
Run Code Online (Sandbox Code Playgroud)在通话结束后添加setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
到onCreate()
您的方法中.MapDialogFragmentv2
super.onCreate()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
}
Run Code Online (Sandbox Code Playgroud)你MapDialogFragmentv2
应该看起来像这样:
public static class MapDialogFragmentv2 extends DialogFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo);
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
return new MyDialog(getActivity());
}
}
Run Code Online (Sandbox Code Playgroud)
我在运行Android 5.0.1(Lollipop)的Nexus 5上测试了所有内容,但它确实有效.
归档时间: |
|
查看次数: |
5066 次 |
最近记录: |