我想有一个2x2网格内的按钮。这只是ICS,所以我试图使用新的GridLayout给定。
这是我的布局的XML:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/favorites_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:rowCount="2"
android:columnCount="2">
<Button
android:text="Cell 0"
android:layout_row="0"
android:layout_column="0"
android:textSize="14dip" />
<Button
android:text="Cell 1"
android:layout_row="0"
android:layout_column="1"
android:textSize="14dip" />
<Button
android:text="Cell 2"
android:layout_row="1"
android:layout_column="0"
android:textSize="14dip" />
<Button
android:text="Cell 3"
android:layout_row="1"
android:layout_column="1"
android:textSize="14dip" />
</GridLayout>
问题是我的视图没有为每一行均匀地拉伸。这导致GridLayout的右侧有很多额外的空间。
我尝试设置layout_gravity="fill_horizontal",但这只适用于该行的最后一个视图。这意味着单元格1会一直延伸,为单元格0提供足够的空间。
如何解决这个问题?
在我的例子中,我是动态添加按钮,所以我的解决方案需要一些XML部分和一些Java部分。我必须从几个不同的地方找到并混合解决方案,我想我将在这里分享,以便其他人寻找类似的解决方案可能会发现它有帮助。
我的布局文件XML的第一部分…
<android.support.v7.widget.GridLayout
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:id="@+id/gl_Options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
grid:useDefaultMargins="true">
</android.support.v7.widget.GridLayout>
grid: usedefaultmargin ="true"不是必需的,但我添加了,因为这对我来说更好,你可以应用其他视觉影响(例如填充),如在这里的一些答案中提到的。现在对于按钮,因为我必须动态添加它们。这是我的代码的Java部分,使这些按钮,我只包括那些与此上下文相关的行。假设我必须使按钮从许多myOptions可用到我的代码,我没有复制OnClickListener代码以及。
import android.support.v7.widget.GridLayout; //Reference to Library
public class myFragment extends Fragment{
GridLayout gl_Options;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
gl_AmountOptions = (GridLayout)view.findViewById( R.id.gl_AmountOptions );
...
gl_Options.removeAllViews(); // Remove all existing views
gl_AmountOptions.setColumnCount( myOptions.length <= 9 ? 3: 4 ); // Set appropriate number of columns
for( String opt : myOptions ) {
GridLayout.LayoutParams lParams = new GridLayout.LayoutParams( GridLayout.spec( GridLayout.UNDEFINED, 1f), GridLayout.spec( GridLayout.UNDEFINED, 1f));
// The above defines LayoutParameters as not specified Column and Row with grid:layout_columnWeight="1" and grid:layout_rowWeight="1"
lParams.width = 0; // Setting width to "0dp" so weight is applied instead
Button b = new Button(this.getContext());
b.setText( opt );
b.setLayoutParams(lParams);
b.setOnClickListener( myClickListener );
gl_Options.addView( b );
}
}
}
因为我们从支持库中使用GridLayout而不是标准的GridLayout,我们必须在YourProject中告诉它的等级。级文件。
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
...
compile 'com.android.support:gridlayout-v7:23.4.0'
}
关于网格布局的一些技巧。
Default Grid layout works best on min SDK 21+ .
GridLayout's height/width should be either fixed or match_parent .It is because Grid layout calculates the height/width of its child, and having the variable height of its own could cause issues in calculation of the exact height.
Grid layout ignores the margins on children by default, so we should be using android:useDefaultMargins="true" if we want children to control their margins.
To make a dynamic, auto-stretching group of views with Grid layout, either:
the parent would be controlling both: the max height of the total group and number of elements in each row or
the parent would be controlling the number of columns in each row,and the children will be controlling the total height.
第一个场景的优点是我们可以在组中添加任意数量的孩子,他们都将很好地均匀伸展。缺点是我们得到的是一个固定规模的群体。而内容较大的儿童也占据了固定的空间。
第二个场景的优点是我们可以添加更多的子节点,由子节点决定组的高度。在父元素的顶部附加一个嵌套的滚动视图将使整个元素列表可滚动。
缺点是,儿童控制组的高度和变量高度,可能会导致整个视图看起来混乱。
如果我们稍微调整一下,这两种情况都可以发挥它们的优点,它们的缺点可以被最小化。
第一个场景的例子:
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2"
android:useDefaultMargins="true">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<!--
add more elements here with same attributes and they will fit on their own!
-->
</GridLayout>
输出:
第二个场景:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="HardcodedText"
>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:orientation="horizontal"
android:useDefaultMargins="true"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:text="this is a text"
android:textColor="@color/white"
android:layout_gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill_horizontal"
android:text="this is something cool. this should be taking more space but it is also controlling the total height of row"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill_horizontal"
android:text="once the width is determined by any child, the whole column shall take the same height"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:text="this column can only control how they shall look by layout gravity. this should look like column 0,0 but its taking full row height/width"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<!--
-->
</GridLayout>
</FrameLayout>
outpus:
结果:
试试这样做:
final int MAX_COLUMN = gridView.getColumnCount(); //5
final int MAX_ROW = gridView.getRowCount(); //7
final int itemsCount = MAX_ROW * MAX_COLUMN; //35
int row = 0, column = 0;
for (int i = 0; i < itemsCount; i++) {
ImageView view = new ImageView(this);
//Just to provide alternate colors
if (i % 2 == 0) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.GREEN);
}
GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(row, 1F), GridLayout.spec(column, 1F));
view.setLayoutParams(params);
gridView.addView(view);
column++;
if (column >= MAX_COLUMN) {
column = 0;
row++;
}
}
如果你想要单元格的特定宽度和高度,那么使用:
params.width = 100; // Your width
params.height = 100; //your height