Android: 自定义对话框的尺寸不精确
Android: Custom Dialog's sizing is unprecise
我正在尝试为我的应用程序创建自定义对话框视图。
当运行程序运行时,结果和我预想的大相径庭
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:orientation="vertical"
android:background="@color/colorPrimaryDark">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/colorAccent">
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary">
<Button
android:id="@+id/button10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</LinearLayout>
Java class:
public class SinglePSettings extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.layout_singlepsettings, null);
builder.setView(view)
.setTitle("Settings");
return builder.create();
}
public void onResume()
{
super.onResume();
Window window = getDialog().getWindow();
Point size = new Point();
Display display = window.getWindowManager().getDefaultDisplay();
display.getSize(size);
int width = (int)(size.x * 0.90);
int height = (int)(size.y * 0.90);
window.setLayout(width, height);
window.setGravity(Gravity.CENTER);
}
我不太明白为什么主要的LinearLayout是'invisible'。里面的物品似乎也不依赖于它。有没有办法用布局填充对话框块的全尺寸?
(当然后面我可以进一步定制。)
这是因为您对话的根布局的高度为 match_parent
,第一个内容的总大小为 200dp child Linearlayout
+ 第二个为 ~24 dp child Linearlayout
小于对话框的总大小。
您应该将 parent LinearLayout
的高度更改为 wrap_content
或将 android:weight=1
添加到任一 child LinearLayouts。
让我试着解释一下线性布局的工作原理。请注意,这些都是经验之谈,您应该阅读官方文档以更好地理解。
符合orientation
的维度对于线性布局的children起着至关重要的作用。因此,如果方向是水平的,那么所有的children都会水平堆叠,需要控制它们的width
属性。
将水平线性布局想象成一个家。目前,假设您始终必须在 parent 线性布局中将 crucial 属性保持为 match_parent
。因此我们的线性布局/家有 width=match_parent
。 children的加法主要有3种:
将每个 child 保持为 wrap_content
这意味着每个 child 将占用屏幕 space 等于其自身大小的数量。
如果项目数量较少或屏幕尺寸足够大,此方法可行。
但是如果有很多大件,那么他们所需要的总space=他们所有的宽度之和。如果此总和大于屏幕尺寸,则 部分项目会超出屏幕。
在我们家的类比中,就好像我们把所有的table、椅子、床等堆成一条直线。如果space比两个端墙之间的space少,那很好,但如果他们需要更多的水平space,那我们就必须打破墙来调整它们。
因此不建议将所有项目都保留为 wrap content
保持一个或多个children作为match_parent
这是一种非常错误的做法。当您将 child 的宽度保持为 match_parent
时,您基本上是在告诉编译器为这个单一视图提供 完整屏幕 space。
而且编译器肯定会这样做。即使它是一个按钮,它也会在整个屏幕上展开并且其他视图将不可见,因为它们实际上在屏幕之外。
当有多个视图 width=match_parent
时,它会简单地将整个屏幕 space 分配给左数第一个视图。
在我们家的类比中,就像您将椅子的宽度属性更改为 match_parent
一样,房间神奇地扩展了它以占据完整的 space,并且因此你的床,table,等等现在都被挤在房间的一侧。
保持 layout_weight=x
一或多个 children
这是线性布局中使用的最佳方法。我将其视为 将屏幕百分比 分配给视图。
如果您的 child 视图具有 weight=x
,则它不会受到您视图 crucial attribute
中存在的值的影响。这意味着您可以有 width= match_parent
或 wrap_content
甚至 1000000dp
,如果它有 weight=x
,它将呈现为全屏视图。请注意,我只是在谈论一个关键属性,即本例中的宽度。
了解具有权重的视图将如何影响其他视图也很有趣。
- 如果另一个视图具有
width = match_parent
(并且没有权重属性),则该视图将占据整个屏幕 space,但是这次 我们的权重视图不会被压扁。相反,这会得到它应该得到的最小值 space(即 wrap_content 或我们为 width=x
传递的固定值)。这就像我们为我们的椅子添加了 weight
属性,为我们的床添加了 match_parent
属性。床压扁了所有其他物品,但椅子仍然占据了它需要的 space。
当其他项目将 wrap_content
作为其关键属性(但没有权重属性)的值时,也会发生类似的情况。这一次,有权重的视图将占用所有 space,除了其他视图所需的 space(将下图与第一种情况进行比较,注意圆圈现在如何占用所有剩余的space 不挤压其他视图)
当每个属性都有权重时,这就变成了一个有趣的百分比游戏。如果我们有两个项目,并且每个项目都有 layout_weight=1
,那么不管它们的宽度是多少,两者都会占用 space 的 50%。如果其中之一有 layout_weight=2
,则分配将为 2:1,即 66%:33%。这使得视图响应不同屏幕尺寸和方向。
因此,在线性布局中使用 children 视图的最佳方法 是在其关键维度中使用 wrap_content
属性和 layout_weight=x
。这将使它更加灵敏并且更易于控制。此外,我没有过多谈论在关键维度属性中使用固定权重,因为处理它们总是一团糟。我不会详细介绍(您可以自己尝试),但它们总是会被压扁或压扁其他视图。
我正在尝试为我的应用程序创建自定义对话框视图。 当运行程序运行时,结果和我预想的大相径庭
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:orientation="vertical"
android:background="@color/colorPrimaryDark">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/colorAccent">
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary">
<Button
android:id="@+id/button10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</LinearLayout>
Java class:
public class SinglePSettings extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.layout_singlepsettings, null);
builder.setView(view)
.setTitle("Settings");
return builder.create();
}
public void onResume()
{
super.onResume();
Window window = getDialog().getWindow();
Point size = new Point();
Display display = window.getWindowManager().getDefaultDisplay();
display.getSize(size);
int width = (int)(size.x * 0.90);
int height = (int)(size.y * 0.90);
window.setLayout(width, height);
window.setGravity(Gravity.CENTER);
}
我不太明白为什么主要的LinearLayout是'invisible'。里面的物品似乎也不依赖于它。有没有办法用布局填充对话框块的全尺寸?
(当然后面我可以进一步定制。)
这是因为您对话的根布局的高度为 match_parent
,第一个内容的总大小为 200dp child Linearlayout
+ 第二个为 ~24 dp child Linearlayout
小于对话框的总大小。
您应该将 parent LinearLayout
的高度更改为 wrap_content
或将 android:weight=1
添加到任一 child LinearLayouts。
让我试着解释一下线性布局的工作原理。请注意,这些都是经验之谈,您应该阅读官方文档以更好地理解。
符合orientation
的维度对于线性布局的children起着至关重要的作用。因此,如果方向是水平的,那么所有的children都会水平堆叠,需要控制它们的width
属性。
将水平线性布局想象成一个家。目前,假设您始终必须在 parent 线性布局中将 crucial 属性保持为 match_parent
。因此我们的线性布局/家有 width=match_parent
。 children的加法主要有3种:
将每个 child 保持为 wrap_content
这意味着每个 child 将占用屏幕 space 等于其自身大小的数量。
如果项目数量较少或屏幕尺寸足够大,此方法可行。
但是如果有很多大件,那么他们所需要的总space=他们所有的宽度之和。如果此总和大于屏幕尺寸,则 部分项目会超出屏幕。
在我们家的类比中,就好像我们把所有的table、椅子、床等堆成一条直线。如果space比两个端墙之间的space少,那很好,但如果他们需要更多的水平space,那我们就必须打破墙来调整它们。
因此不建议将所有项目都保留为
wrap content
保持一个或多个children作为match_parent
这是一种非常错误的做法。当您将 child 的宽度保持为
match_parent
时,您基本上是在告诉编译器为这个单一视图提供 完整屏幕 space。而且编译器肯定会这样做。即使它是一个按钮,它也会在整个屏幕上展开并且其他视图将不可见,因为它们实际上在屏幕之外。
当有多个视图
width=match_parent
时,它会简单地将整个屏幕 space 分配给左数第一个视图。在我们家的类比中,就像您将椅子的宽度属性更改为
match_parent
一样,房间神奇地扩展了它以占据完整的 space,并且因此你的床,table,等等现在都被挤在房间的一侧。
保持 layout_weight=x
一或多个 children
这是线性布局中使用的最佳方法。我将其视为 将屏幕百分比 分配给视图。
如果您的 child 视图具有
weight=x
,则它不会受到您视图crucial attribute
中存在的值的影响。这意味着您可以有width= match_parent
或wrap_content
甚至1000000dp
,如果它有weight=x
,它将呈现为全屏视图。请注意,我只是在谈论一个关键属性,即本例中的宽度。了解具有权重的视图将如何影响其他视图也很有趣。
- 如果另一个视图具有
width = match_parent
(并且没有权重属性),则该视图将占据整个屏幕 space,但是这次 我们的权重视图不会被压扁。相反,这会得到它应该得到的最小值 space(即 wrap_content 或我们为width=x
传递的固定值)。这就像我们为我们的椅子添加了weight
属性,为我们的床添加了match_parent
属性。床压扁了所有其他物品,但椅子仍然占据了它需要的 space。
- 如果另一个视图具有
当其他项目将
wrap_content
作为其关键属性(但没有权重属性)的值时,也会发生类似的情况。这一次,有权重的视图将占用所有 space,除了其他视图所需的 space(将下图与第一种情况进行比较,注意圆圈现在如何占用所有剩余的space 不挤压其他视图)当每个属性都有权重时,这就变成了一个有趣的百分比游戏。如果我们有两个项目,并且每个项目都有
layout_weight=1
,那么不管它们的宽度是多少,两者都会占用 space 的 50%。如果其中之一有layout_weight=2
,则分配将为 2:1,即 66%:33%。这使得视图响应不同屏幕尺寸和方向。
因此,在线性布局中使用 children 视图的最佳方法 是在其关键维度中使用 wrap_content
属性和 layout_weight=x
。这将使它更加灵敏并且更易于控制。此外,我没有过多谈论在关键维度属性中使用固定权重,因为处理它们总是一团糟。我不会详细介绍(您可以自己尝试),但它们总是会被压扁或压扁其他视图。