Adi*_*ain 157 android android-fragments android-dialog android-dialogfragment
我指定我DialogFragment的布局在XML布局文件(让我们称之为layout_mydialogfragment.xml),它layout_width和layout_height属性,特别是(为100dp每个假设).然后我在DialogFragment的onCreateView(...)方法中扩充这个布局,如下所示:
View view = inflater.inflate(R.layout.layout_mydialogfragment, container, false);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我发现当我的对话框(DialogFragment)出现时,它不尊重layout_width和layout_height在其xml布局文件中指定(并且我的对话框根据内容收缩或扩展可变).任何人都知道我是否或如何让我的对话框尊重layout_width和layout_height在其xml布局文件中指定?目前我必须在DialogFragment的onResume()方法中再次指定对话框的宽度和高度,如下所示......
getDialog().getWindow().setLayout(width, height);
Run Code Online (Sandbox Code Playgroud)
...因此,不可取的是,必须记住在两个地方对对话框的宽度和高度进行任何改进.
小智 159
如果直接从资源值转换:
int width = getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);
getDialog().getWindow().setLayout(width, height);
Run Code Online (Sandbox Code Playgroud)
然后在对话框的布局中指定match_parent:
android:layout_width="match_parent"
android:layout_height="match_parent"
Run Code Online (Sandbox Code Playgroud)
你只需要担心一个地方(把它放在你的地方DialogFragment#onResume).它并不完美,但至少它适用于将RelativeLayout作为对话框布局文件的根目录.
jma*_*ate 126
我最终覆盖Fragment.onResume()并从底层对话框中获取属性,然后在那里设置宽度/高度参数.我将最外面的布局高度/宽度设置为match_parent.请注意,此代码似乎也遵循我在xml布局中定义的边距.
@Override
public void onResume() {
super.onResume();
ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.MATCH_PARENT;
getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*_GD 93
我有一个固定大小的DialogFragment在XML主布局中定义了以下内容(在我的例子中是LinearLayout):
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="1000dp"
android:minHeight="450dp"
Run Code Online (Sandbox Code Playgroud)
小智 51
在我的案例中唯一有用的是这里提出的解决方案:http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html
来自Adil博文的片段:
@Override
public void onStart()
{
super.onStart();
// safety check
if (getDialog() == null)
return;
int dialogWidth = ... // specify a value here
int dialogHeight = ... // specify a value here
getDialog().getWindow().setLayout(dialogWidth, dialogHeight);
// ... other stuff you want to do in your onStart() method
}
Run Code Online (Sandbox Code Playgroud)
jpm*_*sta 42
控制DialogFragment宽度和高度的一种方法是确保其对话框尊重视图的宽度和高度(如果它们的值)WRAP_CONTENT.
ThemeOverlay.AppCompat.Dialog实现此目的的一种简单方法是使用ThemeOverlay.AppCompat.DialogAndroid支持库中包含的样式.
DialogFragment用Dialog:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
dialog.setContentView(view);
return dialog;
}
Run Code Online (Sandbox Code Playgroud)
DialogFragment与AlertDialog(警告:) minHeight="48dp":
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
builder.setView(view);
return builder.create();
}
Run Code Online (Sandbox Code Playgroud)
您还可以ThemeOverlay.AppCompat.Dialog在创建对话框时将其添加到应用程序的xml主题中,将其设置为默认主题.
要小心,因为许多对话框确实需要默认的最小宽度才能看起来很好.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- For Android Dialog. -->
<item name="android:dialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- For Android AlertDialog. -->
<item name="android:alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- For AppCompat AlertDialog. -->
<item name="alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- Other attributes. -->
</style>
Run Code Online (Sandbox Code Playgroud)
DialogFragment用Dialog,利用android:dialogTheme:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext());
dialog.setContentView(view);
return dialog;
}
Run Code Online (Sandbox Code Playgroud)
DialogFragment用AlertDialog,使得使用android:alertDialogTheme或alertDialogTheme(警告:minHeight="48dp"):
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(view);
return builder.create();
}
Run Code Online (Sandbox Code Playgroud)
在较旧的Android API上,Dialogs似乎有一些宽度问题,因为它们的标题(即使你没有设置).
如果您不想使用ThemeOverlay.AppCompat.Dialog样式并且您Dialog不需要标题(或具有自定义标题),您可能希望禁用它:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
return dialog;
}
Run Code Online (Sandbox Code Playgroud)
我试图让对话框尊重我的布局的宽度和高度,而不是以编程方式指定固定大小.
我想到了android:windowMinWidthMinor并android:windowMinWidthMajor导致了这个问题.即使他们没有在我的主题包括Activity或者Dialog,他们仍然被应用到Activity主题,不知何故.
我提出了三种可能的解决方案.
解决方案1:创建自定义对话框主题,并在创建对话框时使用它DialogFragment.
<style name="Theme.Material.Light.Dialog.NoMinWidth" parent="android:Theme.Material.Light.Dialog">
<item name="android:windowMinWidthMinor">0dip</item>
<item name="android:windowMinWidthMajor">0dip</item>
</style>
Run Code Online (Sandbox Code Playgroud)
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth);
}
Run Code Online (Sandbox Code Playgroud)
解决方法2:创建一个使用自定义主题ContextThemeWrapper,将作为Context该对话框.如果您不想创建自定义对话框主题(例如,当您要使用指定的主题时),请使用此选项android:dialogTheme.
<style name="Theme.Window.NoMinWidth" parent="">
<item name="android:windowMinWidthMinor">0dip</item>
<item name="android:windowMinWidthMajor">0dip</item>
</style>
Run Code Online (Sandbox Code Playgroud)
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme());
}
Run Code Online (Sandbox Code Playgroud)
解决方案3(带有AlertDialog):强制执行android:windowMinWidthMinor并android:windowMinWidthMajor进入ContextThemeWrapper创建者AlertDialog$Builder.
<style name="Theme.Window.NoMinWidth" parent="">
<item name="android:windowMinWidthMinor">0dip</item>
<item name="android:windowMinWidthMajor">0dip</item>
</style>
Run Code Online (Sandbox Code Playgroud)
@Override
public final Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new View(); // Inflate your view here.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
// Make sure the dialog width works as WRAP_CONTENT.
builder.getContext().getTheme().applyStyle(R.style.Theme_Window_NoMinWidth, true);
return builder.create();
}
Run Code Online (Sandbox Code Playgroud)
rmi*_*lle 35
DialogFragment布局这真的麻木了.
创建a时DialogFragment,您可以选择覆盖onCreateView(传递a ViewGroup以将.xml布局附加到),或者onCreateDialog不会.
你不能覆盖这两种方法,因为你很可能会混淆Android的时间或对话框的布局是否膨胀!WTF?
是否覆盖OnCreateDialog或OnCreateView取决于您打算如何使用对话框的选择.
OnCreateDialog.OnCreateView.这可能是世界上最糟糕的事情.
onCreateDialog 疯狂因此,您将覆盖onCreateDialog您DialogFragment创建AlertDialog要在窗口中显示的自定义实例.凉.但请记住,onCreateDialog收到no ViewGroup以将自定义.xml布局附加到.没问题,你只需传递null给inflate方法.
让疯狂开始吧.
当您覆盖时onCreateDialog,Android COMPLETELY忽略您膨胀的.xml布局的根节点的几个属性.这包括但可能不限于:
background_colorlayout_gravitylayout_widthlayout_height这几乎是滑稽的,因为你需要设置
layout_width和layout_heightEVERY .XML布局或Android Studio会拍你的耻辱一个可爱的小红色徽章.
只是这个词 DialogFragment让我想要呕吐.我可以写一本充满Android陷阱和snafus的小说,但这是一个最内心的.
为了恢复理智,首先,我们声明一种样式来恢复JUST background_color,layout_gravity我们期望:
<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:layout_gravity">center</item>
</style>
Run Code Online (Sandbox Code Playgroud)
上面的样式继承自Dialogs的基本主题(AppCompat在本例中的主题中).
接下来,我们以编程方式应用该样式,将Android放弃的值放回原处并恢复标准AlertDialog外观:
public class MyDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View layout = getActivity().getLayoutInflater().inflate(R.layout.my_dialog_layout, null, false);
assert layout != null;
//build the alert dialog child of this fragment
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
//restore the background_color and layout_gravity that Android strips
b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true);
b.setView(layout);
return b.create();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码会让你AlertDialog看起来像个样子AlertDialog.也许这足够好了.
如果你想设置一个SPECIFIC layout_width或layout_height你的AlertDialog时间(非常可能),那么猜猜看,你还没有完成!
当你意识到如果你试图设置一个特定的layout_width或layout_height你喜欢的新风格时,欢乐仍在继续,Android也将完全忽略它:
<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:layout_gravity">center</item>
<!-- NOPE!!!!! --->
<item name="android:layout_width">200dp</item>
<!-- NOPE!!!!! --->
<item name="android:layout_height">200dp</item>
</style>
Run Code Online (Sandbox Code Playgroud)
要设置SPECIFIC窗口的宽度或高度,您可以继续使用整个'nuther方法并处理LayoutParams:
@Override
public void onResume() {
super.onResume();
Window window = getDialog().getWindow();
if(window == null) return;
WindowManager.LayoutParams params = window.getAttributes();
params.width = 400;
params.height = 400;
window.setAttributes(params);
}
Run Code Online (Sandbox Code Playgroud)
许多人都遵循Android的一个不好的例子,
WindowManager.LayoutParams即更加通用ViewGroup.LayoutParams,只是向右转,然后再ViewGroup.LayoutParams回到WindowManager.LayoutParams几行.有效的Java被诅咒,除了使代码更难破译之外,不必要的铸造提供了许多东西.附注:
LayoutParamsAndroid SDK 中有两次重复- 这是一个极其糟糕的设计的完美示例.
对于DialogFragment覆盖的s onCreateDialog:
AlertDialog外观,请创建一个设置background_color= transparent和layout_gravity=的center样式并应用该样式onCreateDialog.layout_width和/或以layout_height编程方式onResume执行LayoutParamsAnd*_*rey 13
当我需要使DialogFragment更宽一点时,我设置minWidth:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="320dp"
... />
Run Code Online (Sandbox Code Playgroud)
N1h*_*1hk 10
我看不出一个令人信服的理由来覆盖onResume或onStart设置的宽度和高度Window范围内DialogFragment的Dialog-这些特定的生命周期方法可以得到反复和不必要的称为执行该调整的代码不止一次因之类的多窗口切换,backgrounding然后将应用程序置于前台,依此类推。这种重复的后果相当微不足道,但为什么要满足于此呢?
在重写的onActivityCreated()方法中设置宽度/高度将是一种改进,因为实际上每个DialogFragment. 例如:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Window window = getDialog().getWindow();
assert window != null;
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
window.setAttributes(layoutParams);
}
Run Code Online (Sandbox Code Playgroud)
上面我只是将宽度设置为match_parent与设备方向无关。如果您希望您的横向对话框不那么宽,您可以getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT事先检查是否。
小智 6
最外层布局中的尺寸在对话框中不起作用.您可以添加一个布局,其中设置尺寸位于最外层.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="xxdp"
android:layout_height="xxdp"
android:orientation="vertical">
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
小智 5
我修复了它设置根元素布局参数.
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
content.setLayoutParams(new LinearLayout.LayoutParams(width, height));
Run Code Online (Sandbox Code Playgroud)
这是在xml中设置DialogFragment宽度/高度的方法。只需将viewHierarchy包装在具有透明背景的Framelayout中(任何布局都可以使用)。
透明背景似乎是一个特殊的标志,因为这样做时,它会自动将frameLayout的子项在窗口中居中。您的片段后面仍将全屏变暗,表明您的片段是活动元素。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@color/background_material_light">
.....
Run Code Online (Sandbox Code Playgroud)
您可以使用百分比表示宽度。
<style name="Theme.Holo.Dialog.MinWidth">
<item name="android:windowMinWidthMajor">70%</item>
Run Code Online (Sandbox Code Playgroud)
我在这个例子中使用了 Holo 主题。
这是 kotlin 版本
override fun onResume() {
super.onResume()
val params:ViewGroup.LayoutParams = dialog.window.attributes
params.width = LinearLayout.LayoutParams.MATCH_PARENT
params.height = LinearLayout.LayoutParams.MATCH_PARENT
dialog.window.attributes = params as android.view.WindowManager.LayoutParams
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,DialogFragment像Fragment. 它DialogFragment基于 XML 布局,而不是AlertDialog. 我的错误是将对话框片段添加FragmentManager为通常的片段:
fragmentManager?.beginTransaction()?.run {
replace(R.id.container, MyDialogFragment.newInstance(), MyDialogFragment.TAG)
addToBackStack(MyDialogFragment.TAG)
}?.commitAllowingStateLoss()
Run Code Online (Sandbox Code Playgroud)
相反,我需要show对话片段:
val dialogFragment = MyDialogFragment.newInstance()
fragmentManager?.let { dialogFragment.show(it, MyDialogFragment.TAG) }
Run Code Online (Sandbox Code Playgroud)
经过一些编辑(我ViewPager2在布局中),对话框片段变得太窄了:
我使用了N1hk的解决方案:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dialog?.window?.attributes?.width = ViewGroup.LayoutParams.MATCH_PARENT
dialog?.window?.attributes?.height = ViewGroup.LayoutParams.MATCH_PARENT
}
Run Code Online (Sandbox Code Playgroud)
现在它定义了宽度和高度,而不是完整的活动大小。
我想说一下onCreateView和onCreateDialog。如果你有一个基于布局的对话框片段,你可以使用这两种方法中的任何一种。
如果您使用onCreateView,那么您应该使用onActivityCreated来设置宽度。
如果使用onCreateDialog代替onCreateView,则可以在那里设置参数。onActivityCreated将不需要。
覆盖乐趣 onCreateDialog(savedInstanceState: Bundle?): Dialog { super.onCreateDialog(savedInstanceState)
val view = activity?.layoutInflater?.inflate(R.layout.your_layout, null)
val dialogBuilder = MaterialAlertDialogBuilder(context!!).apply { // Or AlertDialog.Builder(context!!).apply
setView(view)
// setCancelable(false)
}
view.text_view.text = "Some text"
val dialog = dialogBuilder.create()
// You can access dialog.window here, if needed.
return dialog
Run Code Online (Sandbox Code Playgroud)
}
我采纳了 @rmirabella 的答案并更新了它以处理高度:
private fun DialogFragment.setSize(widthPercentage: Int, heightPercentage: Int) {
val newWidth = widthPercentage.toFloat() / 100
val newHeight = heightPercentage.toFloat() / 100
val dm = Resources.getSystem().displayMetrics
val rect = dm.run { Rect(0, 0, widthPixels, heightPixels) }
val percentWidth = rect.width() * newWidth
val percentHeight = rect.height() * newHeight
dialog?.window?.setLayout(percentWidth.toInt(), percentHeight.toInt())
}
Run Code Online (Sandbox Code Playgroud)
然后在你的DialogFragmentin 或 after中onStart():
override fun onStart() {
super.onStart()
setSize(
widthPercentage = 100,
heightPercentage = 80
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
147625 次 |
| 最近记录: |