![](/img/trans.png)
[英]Make a Dialogfragment in android full screen without actionbar
[英]Full Screen DialogFragment in Android
我正在嘗試顯示幾乎全屏的 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 會填滿大部分屏幕。 但我似乎只在垂直方向上調整大小,但只能在水平方向上調整到某個固定寬度。
我還嘗試按照此處的建議在代碼中設置 Window 屬性: 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);
}
不幸的是,這並不是我想要的。 我絕對需要在對話框周圍有一個小的“填充”來顯示背景。
任何想法如何做到這一點?
在全屏上獲取 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);
}
}
非常感謝這篇文章: The-mystery-of-androids-full-screen-dialog-fragments
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL,
android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
嘗試切換到LinearLayout
而不是RelativeLayout
。 測試時我的目標是 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>
主文件
<?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>
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>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
2. 添加到您的 DialogFragment:
@Override
public int getTheme() {
return R.style.FullScreenDialog;
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.FullScreenDialog)
}
根據此鏈接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;
}
就我而言,我使用了以下方法:
@Override
public void onStart() {
super.onStart();
getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
}
加上 LinearLayout 用內容填充所有空間。
但是在某些 Lollipop+ 設備(例如 Nexus 9)上,對話框的左右邊緣與屏幕邊緣之間仍然存在小間隙。
這並不明顯,但最后我發現要使其在所有設備和平台上全寬,窗口背景應該在style.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>
當然,當我們創建對話框時需要使用這種樣式,如下所示:
public static DialogFragment createNoTitleDlg() {
DialogFragment frag = new Some_Dialog_Frag();
frag.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Dialog_NoTitle);
return frag;
}
我之前在使用全屏 dialogFragment 時遇到過這個問題:設置全屏時總是有填充。 在 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);
}
}
就 Android API 更新而言,顯示全屏對話框的建議方法如下:
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);
希望能幫助到你。
編輯
請注意,我給出的解決方案有效,但有一個弱點,有時可能會很麻煩。 將 DialogFragment 添加到android.R.id.content
容器將不允許您正確處理DialogFragment#setCancelable()
功能,並且在將 DialogFragment 本身添加到后台堆棧時也可能導致意外行為。
因此,我建議您在 onCreate 方法中簡單地更改 DialogFragment 的樣式,如下所示:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar);
}
希望能幫助到你。
嘗試在 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);
}
還有 kotlin 版本!
override fun onStart() {
super.onStart()
dialog?.let {
val width = ViewGroup.LayoutParams.MATCH_PARENT
val height = ViewGroup.LayoutParams.MATCH_PARENT
it.window?.setLayout(width, height)
}
}
它確實可以取決於布局的定義方式。 但是為了確保對話框獲得所需的大小,最好的解決方案是在顯示對話框后(而不是在創建時)提供 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);
}
注意:即使是一個人也可以在這里找到正確的答案。 但我想澄清一個困惑。
android.app.DialogFragment
使用以下代碼@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.support.v4.app.DialogFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
實現這一目標的最簡單方法是:
將以下主題添加到你的styles.xml
<style name="DialogTheme" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowIsFloating">false</item>
</style>
並在您的類中擴展 DialogFragment,覆蓋
@Override
public int getTheme() {
return R.style.DialogTheme;
}
這也適用於 Android OS 11(R)。
https://anubhav-arora.medium.com/android-full-screen-dialogfragment-1410dbd96d37
這是我如何解決這個問題的解決方案:
@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));
}
}
在 style.xml 中創建以下主題:
<style name="DialogTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:paddingRight">0dp</item>
<item name="android:paddingLeft">0dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:windowNoTitle">true</item>
</style>
然后在 DialogFragment 中設置樣式
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogTheme);
}
除了“_Fullscreen”之外,Chirag Nagariya 是對的。 它可以使用任何不是從 Dialog 樣式派生的基本樣式來解決。 'android.R.style.Theme_Black_NoTitleBar' 也可以使用。
即使您正在處理相對布局,以下方式也將起作用。 請按照以下步驟操作:
轉到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 中創建一個新樣式並按照上面的代碼進行更改。
轉到您的 Dialog Fragment 類並在onCreate()方法中,將您的 Dialog 樣式設置為:
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(DialogFragment.STYLE_NORMAL,R.style.DialogTheme); }
@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;
}
該方案在對話框上應用了全屏主題,類似於 onCreate 中 Chirag 的 setStyle。 一個缺點是不使用savedInstanceState。
試試這個用於多種用途的通用片段對話框。 希望這會幫助您投注
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();
}
}
這是您需要設置為片段的內容:
/* 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>
享受
我回答這個問題已經很晚了,但我想分享這個答案,以便將來任何人都可以使用它。
我在我的項目中使用了這段代碼,它可以在較低版本和較高版本中使用。
只需像這樣在 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>
如果有人遇到任何問題,請告訴我。 希望這是有幫助的。 謝謝 :)
在全屏對話框的樣式中添加以下幾行。
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsFloating">false</item>
萬一其他人遇到這種情況,我也有類似的經歷,但事實證明問題是我忘記從 onCreateView 返回膨脹的視圖(而不是返回默認的 super.onCreateView)。 我只是返回了正確的膨脹視圖並解決了問題。
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){}
This below answer works for me in fragment dialog.
Dialog dialog = getDialog();
if (dialog != null)
{
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
}
通過使用新的溶液ConstraintLayout
被包裹ConstraintLayout
在LinearLayout
與和了minHeight固定minWidth。 如果沒有包裝,ConstraintLayout 將無法獲得正確的 Dialog 大小。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="1000dp"
android:minHeight="1000dp"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_color"
android:orientation="vertical">
<!-- some constrained views -->
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
在 Kotlin 為我工作,
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
以下解決方案對我有用 其他解決方案在側面給了我一些空間,即不是全屏
您需要在 onStart 和 onCreate 方法中進行更改
@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);
}
}
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
final Dialog dialog = new Dialog(requireContext());
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
沒有更多需要更復雜代碼的樣式..帶有狀態欄..
public static void ShowFullScreenDialog(Context context, View contentView, string header)
{
using (Android.Support.V7.App.AlertDialog.Builder builder = new Android.Support.V7.App.AlertDialog.Builder(context, Android.Resource.Style.ThemeBlackNoTitleBarFullScreen))
{
var view = UIHelper.InflaterView(context, Resource.Layout.dialog_full_screen);
builder.SetView(view);
Dialog dialog = builder.Create();
dialog.Window.SetBackgroundDrawableResource(ThemeHelper.GetMainActivityThemeDrawable());
dialog.Window.SetLayout(context.Resources.DisplayMetrics.WidthPixels, context.Resources.DisplayMetrics.HeightPixels);
dialog.Window.DecorView.SystemUiVisibility = StatusBarVisibility.Visible;
//fullLinear
var headtxt = view.FindViewById<TextView>(Resource.Id.headertxt);
headtxt.SetTextColor(Color.White);
headtxt.Text = header;
var fullLinear = view.FindViewById<LinearLayout>(Resource.Id.fullLinear);
var closeBttn = view.FindViewById<ImageButton>(Resource.Id.closeBttn);
closeBttn.ImageTintList = ColorHelper.ConvertColorToStateList(Color.White);
closeBttn.Click += delegate
{
dialog.Hide();
};
if (contentView.Parent != null)
((ViewGroup)contentView.Parent).RemoveView(contentView); // <- fix
fullLinear.AddView(contentView);
dialog.Show();
}
}
重要的
dialog.Window.SetLayout(context.Resources.DisplayMetrics.WidthPixels, context.Resources.DisplayMetrics.HeightPixels);
class NameDialog : DialogFragment(){
lateinit var mDataBinding:NameYourLayoutBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
super.onCreateView(inflater, container, savedInstanceState)
mDataBinding=DataBindingUtil.inflate(
LayoutInflater.from(getContext()),
R.layout.YOUR.LAYOUT.NAME,
null,
false
)
dialog?.let {
it.window?.requestFeature(Window.FEATURE_NO_TITLE)
it.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
return mDataBinding.root
}
override fun onStart() {
super.onStart()
dialog?:return
val width = ViewGroup.LayoutParams.MATCH_PARENT
val height = ViewGroup.LayoutParams.MATCH_PARENT
dialog?.window?.setLayout(width, height)
}
}
這是運行全屏對話框的有效發現:
AlertDialog.Builder(activity, R.style.Theme_AppName_PopupOverlay)
與相應的主題:
<!--night\theme-->
<style name="Theme.AppName.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">
<!--text-->
<item name="colorPrimary">@color/white</item>
<!--title-->
<item name="android:textColor">@color/white</item>
<!--window color-->
<item name="android:backgroundTint">@color/grey_dark</item>
</style>
Alert Dialog Builder 還需要引用 PopupOverlay 以用於日主題。 所以我只有:
<style name="Theme.AppName.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.