Android中的全屏DialogFragment
我试图展示一个几乎全屏的DialogFragment。 但是我不知道怎么做。
我显示片段的方式是从android开发人员文档直接
FragmentManager f = ((Activity)getContext()).getFragmentManager(); FragmentTransaction ft = f.beginTransaction(); Fragment prev = f.findFragmentByTag("dialog"); if (prev != null) { ft.remove(prev); } ft.addToBackStack(null); // Create and show the dialog. DialogFragment newFragment = new DetailsDialogFragment(); newFragment.show(ft, "dialog");
我知道天真地试图设置RelativeLayout在片段fill_parent和一些minWidth和minHeight。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:minWidth="1000px" android:minHeight="600px" android:background="#ff0000">
我会知道期待DialogFragment填补大部分的屏幕。 但我似乎只能调整垂直,但只有一些固定的宽度水平。
我也尝试在代码中设置窗口属性,如下所示: http : //groups.google.com/group/android-developers/browse_thread/thread/f0bb813f643604ec 。 但是这也没有帮助。
我可能会误解一些关于Android如何处理对话框的东西,因为我是全新的。 我怎么能做这样的事情? 有没有其他的方法来达到我的目标?
Android设备:
华硕EeePad变压器
Android 3.0.1
更新:我现在设法把它放到全屏中,在片段中有下面的代码
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_FRAME, android.R.style.Theme_Holo_Light); }
不幸的是,这不是我想要的。 我肯定需要在对话框中使用一个小的“填充”来显示背景。
任何想法如何做到这一点?
尝试切换到LinearLayout
而不是RelativeLayout
。 我在testing时瞄准了3.0 Honeycomb api。
public class FragmentDialog extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.show); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { showDialog(); } }); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } void showDialog() { FragmentTransaction ft = getFragmentManager().beginTransaction(); DialogFragment newFragment = MyDialogFragment.newInstance(); newFragment.show(ft, "dialog"); } public static class MyDialogFragment extends DialogFragment { static MyDialogFragment newInstance() { MyDialogFragment f = new MyDialogFragment(); return f; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_dialog, container, false); return v; } } }
和布局 : fragment_dialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="1000dp" android:minHeight="1000dp"> </LinearLayout>
main.xml中
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"> <Button android:id="@+id/show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" android:text="show"> </Button> </LinearLayout>
全屏显示DialogFragment
覆盖你的DialogFragment的onStart
像这样:
@Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { int width = ViewGroup.LayoutParams.MATCH_PARENT; int height = ViewGroup.LayoutParams.MATCH_PARENT; dialog.getWindow().setLayout(width, height); } }
非常感谢这篇文章: android-full-screen-dialog-fragments的神秘面纱
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen); }
根据这个链接的DialogFragment全屏显示填充两侧,这将像一个魅力工作。
@Override public Dialog onCreateDialog(final Bundle savedInstanceState) { // the content final RelativeLayout root = new RelativeLayout(getActivity()); root.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); // creating the fullscreen dialog final Dialog dialog = new Dialog(getActivity()); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(root); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); return dialog; }
在使用全屏对话框之前,我遇到了这个问题。片段:在设置全屏的时候总是有一个填充。 在dialogFragment的onActivityCreated()方法中尝试下面的代码:
public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Window window = getDialog().getWindow(); LayoutParams attributes = window.getAttributes(); //must setBackgroundDrawable(TRANSPARENT) in onActivityCreated() window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); if (needFullScreen) { window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } }
在我的情况下,我使用了以下的方法:
@Override public void onStart() { super.onStart(); getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } }
加上LinearLayout来填充所有空间的内容。
但是在对话框的左右边缘和一些Lollipop +设备上的屏幕边缘(例如Nexus 9)之间仍然存在很小的差距 。
这并不明显,但最终我发现为了在所有设备和平台上使用全部窗口,应该在styles.xml中指定窗口背景 ,如下所示:
<style name="Dialog.NoTitle" parent="Theme.AppCompat.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:padding">0dp</item> <item name="android:windowBackground">@color/window_bg</item> </style>
当然,这个样式需要在创build对话框时使用,如下所示:
public static DialogFragment createNoTitleDlg() { DialogFragment frag = new Some_Dialog_Frag(); frag.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Dialog_NoTitle); return frag; }
尝试在onCreate中使用setStyle()并覆盖onCreateDialog使对话框没有标题
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); return dialog; }
或者只是覆盖onCreate()和setStyle同事的代码。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme); }
就Android API更新而言,build议的显示全屏对话框的方法如下:
FragmentTransaction transaction = this.mFragmentManager.beginTransaction(); // For a little polish, specify a transition animation transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); // To make it fullscreen, use the 'content' root view as the container // for the fragment, which is always the root view for the activity transaction.add(android.R.id.content, this.mFragmentToShow).commit();
否则,如果你不希望它被全屏显示,你可以这样做:
this.mFragmentToShow.show(this.mFragmentManager, LOGTAG);
希望它有帮助。
编辑
要知道,我给的解决scheme,但有一个弱点,有时可能是麻烦的。 将DialogFragment添加到android.R.id.content
容器中将不允许您正确处理DialogFragment#setCancelable()
function,并且在将DialogFragment本身添加到后退堆栈时也可能导致意外的行为。
所以我build议你简单的改变onCreate方法中DialogFragment的样式,如下所示:
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar); }
希望它有帮助。
它的确可以取决于如何定义布局。 但为了确保对话框获得所需的大小,最好的解决scheme是在显示对话框(而不是创build时)时提供LayoutParams。 在DialogFragment上,对话框显示在onStart方法上,所以一个有效的方法来获得全宽度:
@Override public void onStart() { super.onStart(); Dialog d = getDialog(); if (d!=null){ d.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); } }
要提供一个像NO_TITLE风格的主题或样式,最好的位置在onCreate方法上:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog); }
这是我如何解决这个问题的解决scheme
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); return dialog; } @Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } }
如果有其他人遇到这种情况,我有类似的经验,但事实certificate,问题是,我忘记了从onCreateView(而不是返回默认的super.onCreateView)返回充气的视图。 我只是返回了正确的膨胀视图,并解决了这个问题。
Chirag Nagariya是正确的,除了“_Fullscreen”加法。 它可以使用任何不是从Dialog风格派生的基础样式来解决。 'android.R.style.Theme_Black_NoTitleBar'也可以使用。
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new Dialog(getActivity(), android.R.style.Theme_Holo_Light); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); return dialog; }
该解决scheme在对话框上应用全屏主题,与onCreate中的Chirag的setStyle类似。 缺点是不使用savedInstanceState。
这是你需要设置的片段:
/* theme is optional, I am using leanback... */ setStyle(STYLE_NORMAL, R.style.AppTheme_Leanback);
在你的情况下:
DialogFragment newFragment = new DetailsDialogFragment(); newFragment.setStyle(STYLE_NORMAL, R.style.AppTheme_Leanback); newFragment.show(ft, "dialog");
为什么? 因为DialogFragment(当没有明确告诉的时候)会使用它的内部样式来包裹你的自定义布局(没有全屏等)。
和布局? 没有hacky的方式需要,这是工作得很好:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> ... </RelativeLayout>
请享用
即使您正在处理相对布局,以下方法也可以工作。 遵循以下步骤:
- 转到主题编辑器(在工具 – > Android – >主题编辑器下可用)
- select显示所有主题。 用AppCompat.Dialogselect一个
- 如果你想要任何特定的彩色背景或透明的背景,请selectandroid窗口背景。
- select颜色并点击确定。select新主题的名称。
-
转到styles.xml ,然后在刚刚添加的主题下,添加这两个属性:
<item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">false</item>
我的对话框主题设置如下:
<style name="DialogTheme" parent="Theme.AppCompat.Dialog" > <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">false</item>
确保主题有一个父母作为Theme.AppCompat.Dialog另一种方法将只是在styles.xml中创build一个新的样式,并根据上面的代码进行更改。
-
进入你的Dialog Fragment类和onCreate()方法,将你的Dialog的样式设置为:
@Override public void onCreate(@Nullable Bundle savedInstanceState){super.onCreate(savedInstanceState); 的setStyle(DialogFragment.STYLE_NORMAL,R.style.DialogTheme); }
通过仅使用样式来创build全屏幕DialogFragment
1.添加到您的style.xml
:
<style name="FullScreenDialog" parent="Theme.AppCompat.Light.Dialog"> <item name="android:backgroundDimEnabled">false</item> <item name="android:windowNoTitle">true</item> <item name="android:padding">0dp</item> <item name="android:windowIsFloating">false</item> <item name="android:windowBackground">@android:color/transparent</item> </style>
2.添加到您的DialogFragment:
@Override public int getTheme() { return R.style.FullScreenDialog; }
对于较旧的设备, window.setLayout
是不够的。
这是我做的:
try { ViewGroup parent = (ViewGroup) view; do { parent = (ViewGroup) parent.getParent(); if (parent == null) break; parent.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; parent.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; parent.requestLayout(); } while (true); } catch (Exception e){}
试试这个用于多个用途的公共片段对话框。 希望这会帮助你打赌
public class DialogFragment extends DialogFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_visit_history_main, container, false); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); initializeUI(rootView); return rootView; } @Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { int width = ViewGroup.LayoutParams.MATCH_PARENT; int height = ViewGroup.LayoutParams.MATCH_PARENT; dialog.getWindow().setLayout(width, height); } } private void initializeUI(View rootView) { //getChildFragmentManager().beginTransaction().replace(R.id.fv_container,FragmentVisitHistory.getInstance(), AppConstant.FRAGMENT_VISIT_HISTORY).commit(); } }
我很晚回答这个问题,我仍然想分享这个答案,以便将来任何人都可以使用这个。
我已经在我的项目中使用了这个代码,它在更低的版本和更高的版本中工作。
只需在onCreateDialog()中使用这个主题就可以了:
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_pump_details, null); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), android.R.style.Theme_Black_NoTitleBar_Fullscreen); return builder.create(); }
android.R.style.Theme_Black_NoTitleBar_Fullscreen – 这里是这个主题的源代码,你可以看到只有这个主题足以让DialogFragment全屏显示。
<!-- Variant of {@link #Theme_Black} that has no title bar and no status bar. This theme sets {@link android.R.attr#windowFullscreen} to true. --> <style name="Theme.Black.NoTitleBar.Fullscreen"> <item name="windowFullscreen">true</item> <item name="windowContentOverlay">@null</item> </style>
请让我知道是否有人遇到任何问题。 希望这是有帮助的。 谢谢 :)