提问者:小点点

如何使GridLayout适合屏幕尺寸


GridLayoutAPI文档非常难学……
有没有人能教我如何将childView设置为具有LinearLayout的“权重”?

现在它看起来像所有的左手边,
我已经尝试了很多次,仍然不能使它像每一个屏幕的一半宽度。

编辑:我不知道当孩子们都是wrap_content的时候我能做些什么……即使我想设置一些特定大小的图像,这个类也能帮助我制作ImageViewwrap_content……...它不能正常运行,我错过了一些设置吗?!?


共3个答案

匿名用户

注意:随着Android'Lollipop'5的引入,水平线以下的信息不再准确,因为GridLayout确实适应了21级以来API权重原则。

引用自Javadoc:

多余空间分布

从API21开始,GridLayout的多余空间分布符合权重原则。如果没有指定权重,则尊重以前的约定,如果列和行的视图在其组内指定了某种形式的对齐,则它们将被视为灵活的。因此,视图的灵活性受其对齐方式的影响,而对齐方式通常是通过设置子布局参数的重力属性来定义的。如果沿着给定的轴定义了权重或对齐方式,则组件在该方向上被视为灵活的。如果没有设置权重或对齐方式,则假定组件是不灵活的。

同一行或列组中的多个组件被认为是并行作用的。只有当其中的所有组件都是灵活的时,这样的组才是灵活的。位于公共边界两侧的行和列组被认为是串联作用的。如果这两个元素中的一个元素是灵活的,则由这两个元素组成的复合组是灵活的。

要使柱拉伸,请确保柱内的所有组件都定义了重量或重力。为了防止柱拉伸,请确保柱中的一个组件没有定义重量或重力。

当灵活性原则不能完全消除歧义时,GridLayout的算法倾向于更接近其右边缘和底边的行和列。更准确地说,GridLayout将其每个布局参数视为一组变量中的约束,这些变量定义了沿给定轴的网格线。在布局过程中,GridLayout求解约束,以便将唯一解返回给所有变量都小于或等于任何其他有效解中相应值的约束。

还值得注意的是,android.support. v7.widget.GridLayout包含相同的信息。不幸的是,它没有提到它是用哪个版本的支持库引入的,但是添加功能的提交可以追溯到2014年7月。2014年11月,权重计算和bug的改进被修复。

为安全起见,请确保导入最新版本的gridlayet-v7库。

正如你所描述的,“权重”的原则在GridLayout中不存在。留档中清楚地提到了这个限制;摘录如下。话虽如此,有一些可能性可以使用“重力”来分配多余的空间。我建议你已经通读了链接的留档。

限制

GridLayout不支持以权重定义的权重原则。因此,一般来说,不可能配置GridLayout以在多行或多列之间以非平凡的比例分配多余的空间。尽管如此,一些常见的用例可能会如下所示。要在单元格组中的组件周围放置等量的空间;使用CENTER对齐(或重力)。要完全控制行或列中的多余空间分布;使用LinearLayout子视图来保存相关单元格组中的组件。使用这些技术中的任何一种时,请记住单元格组可能被定义为重叠。

有关示例和一些实用指针,请查看去年介绍GridLayout小部件的博客文章。

编辑:我不认为有一种基于xml的方法可以像在谷歌游戏应用程序中那样将瓷砖缩放成两倍于这些正方形长度的“正方形”或“矩形”。然而,如果你以编程方式构建布局,这当然是可能的。为了实现这一目标,你真正需要知道的就是设备的屏幕尺寸。

下面是(非常!)Google Play应用程序中平铺布局的快速肮脏近似。

Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
int halfScreenWidth = (int)(screenWidth *0.5);
int quarterScreenWidth = (int)(halfScreenWidth * 0.5);

Spec row1 = GridLayout.spec(0, 2);
Spec row2 = GridLayout.spec(2);
Spec row3 = GridLayout.spec(3);
Spec row4 = GridLayout.spec(4, 2);

Spec col0 = GridLayout.spec(0);
Spec col1 = GridLayout.spec(1); 
Spec colspan2 = GridLayout.spec(0, 2);

GridLayout gridLayout = new GridLayout(this);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(15);

TextView twoByTwo1 = new TextView(this);
GridLayout.LayoutParams first = new GridLayout.LayoutParams(row1, colspan2);
first.width = screenWidth;
first.height = quarterScreenWidth * 2;
twoByTwo1.setLayoutParams(first);
twoByTwo1.setGravity(Gravity.CENTER);
twoByTwo1.setBackgroundColor(Color.RED);
twoByTwo1.setText("TOP");
twoByTwo1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByTwo1, first);

TextView twoByOne1 = new TextView(this);
GridLayout.LayoutParams second = new GridLayout.LayoutParams(row2, col0);
second.width = halfScreenWidth;
second.height = quarterScreenWidth;
twoByOne1.setLayoutParams(second);
twoByOne1.setBackgroundColor(Color.BLUE);
twoByOne1.setText("Staff Choices");
twoByOne1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne1, second);

TextView twoByOne2 = new TextView(this);
GridLayout.LayoutParams third = new GridLayout.LayoutParams(row2, col1);
third.width = halfScreenWidth;
third.height = quarterScreenWidth;
twoByOne2.setLayoutParams(third);
twoByOne2.setBackgroundColor(Color.GREEN);
twoByOne2.setText("Games");
twoByOne2.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne2, third);

TextView twoByOne3 = new TextView(this);
GridLayout.LayoutParams fourth = new GridLayout.LayoutParams(row3, col0);
fourth.width = halfScreenWidth;
fourth.height = quarterScreenWidth;
twoByOne3.setLayoutParams(fourth);
twoByOne3.setBackgroundColor(Color.YELLOW);
twoByOne3.setText("Editor's Choices");
twoByOne3.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByOne3, fourth);

TextView twoByOne4 = new TextView(this);
GridLayout.LayoutParams fifth = new GridLayout.LayoutParams(row3, col1);
fifth.width = halfScreenWidth;
fifth.height = quarterScreenWidth;
twoByOne4.setLayoutParams(fifth);
twoByOne4.setBackgroundColor(Color.MAGENTA);
twoByOne4.setText("Something Else");
twoByOne4.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne4, fifth);

TextView twoByTwo2 = new TextView(this);
GridLayout.LayoutParams sixth = new GridLayout.LayoutParams(row4, colspan2);
sixth.width = screenWidth;
sixth.height = quarterScreenWidth * 2;
twoByTwo2.setLayoutParams(sixth);
twoByTwo2.setGravity(Gravity.CENTER);
twoByTwo2.setBackgroundColor(Color.WHITE);
twoByTwo2.setText("BOTOM");
twoByTwo2.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByTwo2, sixth);

结果看起来有点像这样(在我的Galaxy Nexus上):

匿名用户

经过多次尝试,我找到了我在这个布局中寻找的东西。即使是间隔的线性布局,自动安装ImageViews,保持长宽比。适用于任何屏幕和图像分辨率的风景和肖像。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffcc5d00" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">


        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:layout_weight="1"
                android:layout_height="wrap_content">

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:padding="10dip"
                    android:layout_height="fill_parent">

                    <ImageView
                        android:id="@+id/image1"
                        android:layout_height="fill_parent"
                        android:adjustViewBounds="true"
                        android:scaleType="fitCenter"
                        android:src="@drawable/stackoverflow"
                        android:layout_width="fill_parent"
                        android:layout_gravity="center" />
                </LinearLayout>

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:padding="10dip"
                    android:layout_height="fill_parent">

                    <ImageView
                        android:id="@+id/image2"
                        android:layout_height="fill_parent"
                        android:adjustViewBounds="true"
                        android:scaleType="fitCenter"
                        android:src="@drawable/stackoverflow"
                        android:layout_width="fill_parent"
                        android:layout_gravity="center" />
                </LinearLayout>
            </LinearLayout>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_weight="1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:padding="10dip"
                    android:layout_height="fill_parent">

                    <ImageView
                        android:id="@+id/image3"
                        android:layout_height="fill_parent"
                        android:adjustViewBounds="true"
                        android:scaleType="fitCenter"
                        android:src="@drawable/stackoverflow"
                        android:layout_width="fill_parent"
                        android:layout_gravity="center" />
                </LinearLayout>

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:padding="10dip"
                    android:layout_height="fill_parent">

                    <ImageView
                        android:id="@+id/image4"
                        android:layout_height="fill_parent"
                        android:adjustViewBounds="true"
                        android:scaleType="fitCenter"
                        android:src="@drawable/stackoverflow"
                        android:layout_width="fill_parent"
                        android:layout_gravity="center" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</FrameLayout>

匿名用户

从21API开始,权重的概念被添加到GridLayout中。

要支持较旧的android设备,您可以使用v7支持库中的GridLayout。

compile 'com.android.support:gridlayout-v7:22.2.1'

以下XML给出了如何使用权重填充屏幕宽度的示例。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:grid="http://schemas.android.com/apk/res-auto"

    android:id="@+id/choice_grid"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:padding="4dp"

    grid:alignmentMode="alignBounds"
    grid:columnCount="2"
    grid:rowOrderPreserved="false"
    grid:useDefaultMargins="true">

    <TextView
        android:layout_width="0dp"
        android:layout_height="100dp"
        grid:layout_columnWeight="1"
        grid:layout_gravity="fill_horizontal"
        android:gravity="center"
        android:background="#FF33B5E5"
        android:text="Tile1" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="100dp"
        grid:layout_columnWeight="1"
        grid:layout_gravity="fill_horizontal"
        android:gravity="center"
        android:background="#FF33B5E5"
        android:text="Tile2" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="100dp"
        grid:layout_columnWeight="1"
        grid:layout_gravity="fill_horizontal"
        android:gravity="center"
        android:background="#FF33B5E5"
        android:text="Tile3" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="100dp"
        grid:layout_columnWeight="1"
        grid:layout_gravity="fill_horizontal"
        android:gravity="center"
        android:background="#FF33B5E5"
        android:text="Tile4" />

</android.support.v7.widget.GridLayout>