Android 异构网格布局
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10812552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Heterogeneous GridLayout
提问by C.d.
UPDATE - my working solution:https://stackoverflow.com/a/21233824/902172
更新 - 我的工作解决方案:https : //stackoverflow.com/a/21233824/902172
I am trying to implement the layout below:
我正在尝试实现以下布局:
I guess GridLayoutis suitable for my needs but after 2 hours of struggle I couldn't create even a similar layout.. The layout is resizing itself wrongly, it exceeds the screenof the phone and it also does not spanthe specified rows and columns.
我猜的GridLayout是适合我的需要,但后2小时的奋斗,我不能创造出一个类似的布局。该布局是错误地调整自身,它超出了屏幕的手机,它也不会跨越指定的行和列.
Here I selected a button so you can see how it exceeds the boundaries:
在这里,我选择了一个按钮,以便您可以看到它是如何超出边界的:
and here is the associated xml code: https://gist.github.com/2834492
这是相关的 xml 代码:https: //gist.github.com/2834492
I have reached a similar layout with nested linearlayouts but it's not possible to properly resizeit for different screen sizes.
我已经使用嵌套的线性布局达到了类似的布局,但无法针对不同的屏幕尺寸正确调整其大小。
UPDATE - approximate LinearLayout implementation:
更新 - 近似 LinearLayout 实现:
The XML code: https://gist.github.com/cdoger/2835887However, the problem is it does not resize itself properly here some screenshots with different screen configurations:
XML 代码:https: //gist.github.com/cdoger/2835887然而,问题是它没有正确调整自己的大小,这里有一些不同屏幕配置的屏幕截图:
TLDR:Can someone show me a heterogeneous layout implementation with GridLayout like in the first picture?
TLDR:有人可以像第一张图片一样向我展示具有 GridLayout 的异构布局实现吗?
采纳答案by C.d.
So here is the solution I promised after one year =) It basically uses the ViewTreeObserverto get the dimensions of the parent layout and create custom views accordingly. Since this code is one year old ViewTreeObserver might not be the best way to get the dimensions dynamically.
所以这是我在一年后承诺的解决方案 =) 它基本上使用ViewTreeObserver来获取父布局的尺寸并相应地创建自定义视图。由于此代码已有一年历史,因此 ViewTreeObserver 可能不是动态获取维度的最佳方式。
You can find the full source code here: https://github.com/cdoger/Android_layout
你可以在这里找到完整的源代码:https: //github.com/cdoger/Android_layout
I divided the screen into 8 equal widths and 6 equal heights. Here is a snapshot of how I laid out the views:
我将屏幕分成 8 个等宽和 6 个等高。这是我如何布置视图的快照:
final RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
ViewTreeObserver vto = mainLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final int oneUnitWidth = mainLayout.getMeasuredWidth() / 8;
final int oneUnitHeight = mainLayout.getMeasuredHeight() / 6;
/**
* 1
***************************************************************/
final RelativeLayout.LayoutParams otelParams = new RelativeLayout.LayoutParams(
oneUnitWidth * 4, oneUnitHeight);
otelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
otelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
// otelParams.setMargins(0, 0, 2, 0);
View1.setLayoutParams(otelParams);
/***************************************************************/
/**
* 2
***************************************************************/
final RelativeLayout.LayoutParams otherParams = new RelativeLayout.LayoutParams(
oneUnitWidth * 4, oneUnitHeight);
otherParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
otherParams.addRule(RelativeLayout.RIGHT_OF, View1.getId());
otherParams.setMargins(2, 0, 0, 0);
View2.setLayoutParams(otherParams);
/***************************************************************/
//... goes on like this
Here is the final screenshot:
这是最终的屏幕截图:
回答by Fuzzical Logic
C.d.,
光盘,
The issue you are facing is due to inappropriate use of the GridLayout. The GridLayout is made to show its children in a grid and you are trying to override that without extending the GridLayout. While what you want may be accomplished in code (utilizing numcolumns and columnsize), it will not be useful for multiple screen sizes without a heck of a lot of code.
您面临的问题是由于 GridLayout 使用不当。GridLayout 用于在网格中显示其子项,并且您试图在不扩展 GridLayout 的情况下覆盖它。虽然你想要的东西可以在代码中完成(使用 numcolumns 和 columnsize),但如果没有大量代码,它对于多种屏幕尺寸没有用处。
The only adequate solution that won't require a ton of hacking is judicious use of both LinearLayout and RelativeLayout. LinearLayout should not be used exclusively as it is made to drop items in a line (horizontally or vertically only). This becomes especially apparent when you try and do the bottom four buttons. While the buttons above may be done with LinearLayout with very little effort, RelativeLayout is what you need for the bottom four buttons.
唯一不需要大量黑客攻击的适当解决方案是明智地使用 LinearLayout 和 RelativeLayout。LinearLayout 不应单独使用,因为它用于将项目放置在一行中(仅水平或垂直)。当您尝试执行底部的四个按钮时,这一点尤其明显。虽然上面的按钮可以通过 LinearLayout 轻松完成,但RelativeLayout 是底部四个按钮所需要的。
Note:RelativeLayout can be a little bit tricksy for those with little experience using them. Some pitfalls include: children overlapping, children moving off the screen, height and width rendering improperly applied. If you would like an example, let me know and I will edit my answer.
注意:对于那些没有使用它们的经验的人来说,RelativeLayout 可能有点棘手。一些陷阱包括:孩子重叠、孩子离开屏幕、高度和宽度渲染应用不当。如果你想要一个例子,让我知道,我会编辑我的答案。
Final Note:I'm all for utilizing the current framework objects in unique ways, and genuinely prefer to provide the requested solution. The solution, however, is not viable given the constraints of the question.
最后说明:我完全赞成以独特的方式利用当前的框架对象,并且真正喜欢提供所需的解决方案。然而,鉴于问题的限制,该解决方案是不可行的。
(Revision) Solution 1
(修订)解决方案1
After some careful thought last night, this may be accomplished with a pure LinearLayout. While I do not like this solution, it should be multi-screen friendly and requires no tooling around from me. Caution should be used with too many LinearLayouts, as according to Google's developers, it can result in slow loading UIs due to the layout_weight property. A second solution utilizing RelativeLayout will be provided when I return home. Now TestedThis provides the desired layout parameters on all screen-sizes and orientations.
经过昨晚的一些仔细考虑,这可以通过纯 LinearLayout 来完成。虽然我不喜欢这个解决方案,但它应该是多屏幕友好的,不需要我的工具。使用过多的 LinearLayout 时应谨慎,因为根据 Google 的开发人员的说法,由于 layout_weight 属性,它可能会导致 UI 加载缓慢。当我回家时,将提供使用RelativeLayout 的第二个解决方案。Now Tested这提供了所有屏幕尺寸和方向上所需的布局参数。
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/Button01"
android:layout_width="0"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/Button02"
android:layout_width="0"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.00"
android:orientation="horizontal">
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="@+id/button6"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:text="Button" />
<Button
android:id="@+id/button7"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Solution 1 Explanation
方案一说明
The key to LinearLayouts is to define your imperatives as separate Layouts and nest the others in them. As you apply constraints to more dimensions, more LinearLayouts must be added to encapsulate the others. For yours, it was crucial to have two more parents in order to maintain the proportion. A great indicator of when you should add another level is when you haveto utilize layout_weight using anything other than an integer value. It simply becomes to hard to calculate properly. From there it was relatively simple to break it into columns.
LinearLayouts 的关键是将您的命令定义为单独的 Layouts,并将其他的嵌套在其中。当您将约束应用于更多维度时,必须添加更多 LinearLayout 以封装其他维度。对你来说,为了保持比例,多有两个父母是至关重要的。何时应该添加另一个级别的一个很好的指标是当您必须使用除整数值以外的任何内容来使用 layout_weight 时。它只是变得难以正确计算。从那里将其分成几列相对简单。
Solution 2 (Failed)
解决方案2(失败)
While I was able to achieve desirable results utilizing RelativeLayout and "struts", I could only do so with layouts that were multiples of 2 buttons in height. Such a trick would be awesome as the levels of layout are greatly reduced, so I will work on a pure XML solution and post the answer here if and when I achieve it. In the meantime, the LinearLayout above should suit your needs perfectly.
虽然我能够使用 RelativeLayout 和“struts”获得理想的结果,但我只能使用高度为 2 个按钮的倍数的布局。这样的技巧会很棒,因为布局级别大大降低,所以我将研究纯 XML 解决方案,并在我实现时在此处发布答案。同时,上面的 LinearLayout 应该可以完美地满足您的需求。
Hope this helps,
希望这可以帮助,
FuzzicalLogic
模糊逻辑
回答by Risch
I read this thread and realised that I wanted a flatter solution than those with linear layout. After some research I ended up making my own layout. It is inspired by a GridLayout but differs a bit.
我阅读了这个线程并意识到我想要一个比线性布局更扁平的解决方案。经过一番研究,我最终做出了自己的布局。它受 GridLayout 的启发,但略有不同。
Please note that if you are going to copy-paste the code you'll need to change package names in some places.
请注意,如果您要复制粘贴代码,则需要在某些地方更改包名称。
This layout has 4 layout parameters that children use to position themselves.These are layout_left, layout_top, layout_right, layout_bottom. The ICGridLayout itself has two attributes: layout_spacing and columns.
这个布局有 4 个布局参数,孩子们用来定位自己。这些是layout_left, layout_top, layout_right, layout_bottom。ICGridLayout 本身有两个属性:layout_spacing 和 columns。
Columnstells the layout how many columns you want it to contain. It will then calculate the size of a cell with the same height as width. Which will be the layouts width/columns.
Columns告诉布局您希望它包含多少列。然后它将计算高度与宽度相同的单元格的大小。这将是布局宽度/列。
The spacingis the amount of space you want between each child.
该间距是你要每个孩子之间的空间量。
The layout_left|top|right|bottom attributes are the coordinates for each side. The layout does no calculations in order to avoid collision or anything. It just puts the children where they want to be.
layout_left|top|right|bottom 属性是每边的坐标。布局不进行计算以避免碰撞或任何事情。它只是把孩子放在他们想去的地方。
If you'd like to have smaller squares you just have to increase the columns attribute.
如果你想要更小的方块,你只需要增加 columns 属性。
Keep in mind that this is a quick prototype, I will continue working on it and when I feel that it's ready I'll upload it to Github and put a comment here.
请记住,这是一个快速原型,我将继续研究它,当我觉得它准备好了时,我会将它上传到 Github 并在此处发表评论。
All of my code below should produce the following result:
我下面的所有代码都应该产生以下结果:
*****EDIT***** Added the call to measure for the children, forgot that the first time around. END EDITICGridLayout.java:
*****编辑***** 为孩子们添加了测量的调用,第一次忘记了。 结束编辑ICGridLayout.java:
package com.risch.evertsson.iclib.layout;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.risch.evertsson.iclib.R;
/**
* Created by johanrisch on 6/13/13.
*/
public class ICGridLayout extends ViewGroup {
private int mColumns = 4;
private float mSpacing;
public ICGridLayout(Context context) {
super(context);
}
public ICGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ICGridLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(
attrs,
R.styleable.ICGridLayout_Layout);
this.mColumns = a.getInt(R.styleable.ICGridLayout_Layout_columns, 3);
this.mSpacing = a.getDimension(R.styleable.ICGridLayout_Layout_layout_spacing, 0);
a.recycle();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
int width = (int) (r - l);
int side = width / mColumns;
int children = getChildCount();
View child = null;
for (int i = 0; i < children; i++) {
child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
int left = (int) (lp.left * side + mSpacing / 2);
int right = (int) (lp.right * side - mSpacing / 2);
int top = (int) (lp.top * side + mSpacing / 2);
int bottom = (int) (lp.bottom * side - mSpacing / 2);
child.layout(left, top, right, bottom);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureVertical(widthMeasureSpec, heightMeasureSpec);
}
private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = 0;
int height = 0;
if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) {
width = MeasureSpec.getSize(widthMeasureSpec);
} else {
throw new RuntimeException("widthMeasureSpec must be AT_MOST or " +
"EXACTLY not UNSPECIFIED when orientation == VERTICAL");
}
View child = null;
int row = 0;
int side = width / mColumns;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.bottom > row) {
row = lp.bottom;
}
int childHeight = (lp.bottom - lp.top)*side;
int childWidth = (lp.right-lp.left)*side;
int heightSpec = MeasureSpec.makeMeasureSpec(childHeight, LayoutParams.MATCH_PARENT);
int widthSpec = MeasureSpec.makeMeasureSpec(childWidth, LayoutParams.MATCH_PARENT);
child.measure(widthSpec, heightSpec);
}
height = row * side;
// TODO: Figure out a good way to use the heightMeasureSpec...
setMeasuredDimension(width, height);
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new ICGridLayout.LayoutParams(getContext(), attrs);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof ICGridLayout.LayoutParams;
}
@Override
protected ViewGroup.LayoutParams
generateLayoutParams(ViewGroup.LayoutParams p) {
return new ICGridLayout.LayoutParams(p);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams();
}
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
int right = 1;
int bottom = 1;
int top = 0;
int left = 0;
int width = -1;
int height = -1;
public LayoutParams() {
super(MATCH_PARENT, MATCH_PARENT);
top = 0;
left = 1;
}
public LayoutParams(int width, int height) {
super(width, height);
top = 0;
left = 1;
}
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(
attrs,
R.styleable.ICGridLayout_Layout);
left = a.getInt(R.styleable.ICGridLayout_Layout_layout_left, 0);
top = a.getInt(R.styleable.ICGridLayout_Layout_layout_top, 0);
right = a.getInt(R.styleable.ICGridLayout_Layout_layout_right, left + 1);
bottom = a.getInt(R.styleable.ICGridLayout_Layout_layout_bottom, top + 1);
height = a.getInt(R.styleable.ICGridLayout_Layout_layout_row_span, -1);
width = a.getInt(R.styleable.ICGridLayout_Layout_layout_col_span, -1);
if (height != -1) {
bottom = top + height;
}
if (width != -1) {
right = left + width;
}
a.recycle();
}
public LayoutParams(ViewGroup.LayoutParams params) {
super(params);
}
}
}
ICGridLayout.java is pretty straight forward. It takes the values provided by the children and lays them out. attrs.xml:
ICGridLayout.java 非常简单。它接受孩子们提供的价值观,并把它们列出来。attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ICGridLayout_Layout">
<attr name="columns" format="integer"/>
<attr name="layout_left" format="integer"/>
<attr name="layout_top" format="integer"/>
<attr name="layout_right" format="integer"/>
<attr name="layout_bottom" format="integer"/>
<attr name="layout_col_span" format="integer"/>
<attr name="layout_row_span" format="integer"/>
<attr name="layout_spacing" format="dimension"/>
</declare-styleable>
</resources>
example_layout.xml:
example_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.rischit.projectlogger"
android:id="@+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.risch.evertsson.iclib.layout.ICGridLayout
android:id="@+id/ICGridLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_spacing="4dp"
app:columns="4" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="1"
app:layout_left="0"
app:layout_right="4"
app:layout_top="0"
android:background="#ff0000"
android:text="TextView" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="3"
app:layout_left="3"
app:layout_right="4"
app:layout_top="1"
android:background="#00ff00"
android:text="TextView" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="4"
app:layout_left="0"
app:layout_right="3"
app:layout_top="1"
android:background="#0000ff"
android:text="TextView" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="4"
app:layout_left="3"
app:layout_right="4"
app:layout_top="3"
android:background="#ffff00"
android:text="TextView" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="6"
app:layout_left="0"
app:layout_right="1"
app:layout_top="4"
android:background="#ff00ff"
android:text="TextView" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="6"
app:layout_left="1"
app:layout_right="4"
app:layout_top="4"
android:background="#ffffff"
android:text="TextView" />
</com.risch.evertsson.iclib.layout.ICGridLayout>
</ScrollView>
-- Johan Risch
——约翰·里施
P.S This is my first long answer, I've tried to do it in a correct way. If I've failed please tell me without flaming :) D.S
PS 这是我的第一个长答案,我尝试以正确的方式进行。如果我失败了,请不要生气地告诉我 :) DS
回答by Skies
Like this ?
像这样 ?
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.54" >
<Button
android:id="@+id/Button01"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.00"
android:text="Button" />
<Button
android:id="@+id/Button02"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.00"
android:text="Button" />
</LinearLayout>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="99dp" >
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="152dp"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="@+id/button6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button7"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
回答by Gene
As many have said, nested linear layouts seem the only way to win here. Some of the solutions have not used the layout parameters in the most flexible manner. Code below seeks to do that, and in a way that's robust with aspect ratio changes. Details are in the comments.
正如许多人所说,嵌套线性布局似乎是在这里获胜的唯一方法。一些解决方案没有以最灵活的方式使用布局参数。下面的代码试图做到这一点,并且以一种对宽高比变化很健壮的方式。详情见评论。
<?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" >
<!-- First row. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Equal weights cause two columns of equal width. -->
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="A" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="B" />
</LinearLayout>
<!-- Second row. -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="C" />
<!-- Third row. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Equal weights cause two columns of equal width. -->
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="D" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="E" />
</LinearLayout>
<!-- Uneven fourth and fifth rows. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:baselineAligned="false" >
<!-- Left column. Equal weight with right column gives them equal width. -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<!--
The use of weights below assigns all extra space to G. There
are other choices. LinearLayout computes sizes along its
axis as given, then divides the remaining extra space using
weights. If a component doesn't have a weight, it keeps
the specified size exactly.
-->
<!-- Fill width of layout and use wrap height (because there's no weight). -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="F" />
<!-- Fill width of layout and put all the extra space here. -->
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="G" />
</LinearLayout>
<!-- Right column. Equal weight with left column gives them equal width. -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<!-- Same as above except top button gets all the extra space. -->
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="H" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
回答by Skies
I've try this tuto
我试过这个教程
I'm blocked here :
我被阻止在这里:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:columnCount="2"
android:orientation="horizontal" >
<Button android:text="1" />
<Button android:text="2" />
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill"
android:text="3" />
<Button android:text="4" />
<Button android:text="5" />
<Button
android:layout_gravity="fill"
android:layout_rowSpan="2"
android:text="6" />
<Button android:text="7" />
<Button android:text="8" />
<Button android:text="9" />
</GridLayout>
Impossible to me to expand the 8th button. :s
我无法展开第 8 个按钮。:s
I've try
我试过了
<Button android:text="8" android:layout_gravity="fill" android:layout_rowSpan="2"/>
But it's ineffec. :s
但它是无效的。:s
回答by Shankar Agarwal
Embed your GridLayout in LinearLayout as below and try it worked for me.
将您的 GridLayout 嵌入到 LinearLayout 中,如下所示,并尝试它对我有用。
<?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="horizontal" >
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2" >
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="start|end"
android:layout_row="0"
android:text="ASDFASDF" />
<Button
android:layout_column="1"
android:layout_gravity="start|end"
android:layout_row="0"
android:text="SDAVDFBDFB" />
<Button
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_gravity="fill|center"
android:layout_row="1"
android:text="ASDVADFBFDAFEW" />
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="2"
android:text="FWEA AWFWEA" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_row="2"
android:text="BERWEfasf" />
<Button
android:layout_width="94dp"
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="3"
android:text="SDFVBFAEVSAD" />
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="4"
android:layout_rowSpan="2"
android:text="GVBAERWEFSD" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="3"
android:layout_rowSpan="2"
android:text="VSDFAVE SDFASDWA SDFASD" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="5"
android:text="FWEWEGAWEFWAE"/>
</GridLayout>
</LinearLayout>