如何在以编程方式添加时为 GridLayout 子项设置 layout_columnWeight?
How to set layout_columnWeight for a GridLayout child when added programmatically?
我想使用 GridLayout
(不是 GridView
)作为国际象棋或西洋跳棋等游戏的棋盘。由于我不太愿意使用包含 64 个子 View
的 xml 文件,因此我尝试以编程方式添加它们。
为了简单起见,我开始使用 TextView
作为 GridLayout
的子 View
。
我的问题是 View
分布不均匀,而且我不知道如何在我的 java 代码中获得均匀分布。没有像"setWeight()"这样的方法来设置layout_columnWeight
和layout_rowWeight
.
目前这是我的activity_dynamic_grid_layout.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/ivLogo"
android:background="#ff0000"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<android.support.v7.widget.GridLayout
android:id="@+id/grid_layout"
android:background="#004080"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ivLogo"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="36dp">
</android.support.v7.widget.GridLayout>
我在这里将 GridLayout
宽度和高度设置为 match_parent
,但我在运行时使用 ViewTreeObserver.OnPreDrawListener
更改它们以获得方形板。这有效,彩色背景按预期显示正方形 space。
我的onCreate()
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_grid_layout);
GridLayout gl = (GridLayout) findViewById(R.id.grid_layout);
gl.setColumnCount(8);
gl.setRowCount(8);
for(int i=0; i<gl.getRowCount(); i++)
{
GridLayout.Spec rowSpec = GridLayout.spec(i, 1, GridLayout.FILL);
for(int j=0;j<gl.getColumnCount();j++)
{
GridLayout.Spec colSpec = GridLayout.spec(j,1, GridLayout.FILL);
TextView tvChild = new TextView(this);
tvChild.setText("[ " + i + " | " + j + " ]");
tvChild.setTextSize(18f);
tvChild.setTextColor(Color.WHITE);
tvChild.setGravity(Gravity.CENTER);
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
myGLP.rowSpec = rowSpec;
myGLP.columnSpec = colSpec;
gl.addView(tvChild, myGLP );
}
}
final View rootView = findViewById(R.id.dynamic_root);
rootView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
int w = rootView.getMeasuredWidth();
int h = rootView.getMeasuredHeight();
int min = Math.min(w, h);
ViewGroup.LayoutParams lp = gl.getLayoutParams();
lp.width = min - min % 9;
lp.height = lp.width;
gl.setLayoutParams(lp);
rootView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
}
我已经尝试过的:
我在布局文件中放置了一个 TextView
子节点,并尝试从其 GridLayout.LayoutParams
:
中复制 layout_columnWeight
和 layout_rowWeight
<android.support.v7.widget.GridLayout
...>
<TextView
android:id="@+id/clone_my_params"
android:text="[ 0 | 0 ]"
android:textColor="#ffffff"
android:textSize="18sp"
app:layout_column="0"
app:layout_row="0"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
/>
</android.support.v7.widget.GridLayout>
onCreate()
中的附加代码,在双循环之前:
TextView v = (TextView)gl.findViewById(R.id.clone_my_params);
v.setGravity(Gravity.CENTER);
GridLayout.LayoutParams gridLayoutParamsToCopy = new GridLayout.LayoutParams(v.getLayoutParams());
在循环中,我跳过了 (i,j) = (0,0) 并更改了
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
到
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
改变前,所有元素都在左上角,多余的space给到最后一行/列。更改后第一行/列多出space,其他元素无变化
双循环后调用gl.invalidate()
and/orgl.requestLayout()
没有效果
看来我没能使用复制构造函数设置所需的权重。
要为您的 Gridlayout 的子项设置权重,请使用采用浮点值的 spec()(例如 one)方法之一。
另一种方法是制作自定义视图(在这种情况下您需要手动绘制棋子)或自定义 ViewGroup(在这种情况下自定义 ViewGroup 将只负责棋子的定位,这如果您计划拥有比简单的 TextView 更复杂的视图层次结构,这将是合适的。
-给你! :>
Button button = new Button(this);
GridLayout.LayoutParams param= new GridLayout.LayoutParams(GridLayout.spec(
GridLayout.UNDEFINED,GridLayout.FILL,1f),
GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f));
param.height = 0;
param.width = 0;
button.setLayoutParams(param);
我想使用 GridLayout
(不是 GridView
)作为国际象棋或西洋跳棋等游戏的棋盘。由于我不太愿意使用包含 64 个子 View
的 xml 文件,因此我尝试以编程方式添加它们。
为了简单起见,我开始使用 TextView
作为 GridLayout
的子 View
。
我的问题是 View
分布不均匀,而且我不知道如何在我的 java 代码中获得均匀分布。没有像"setWeight()"这样的方法来设置layout_columnWeight
和layout_rowWeight
.
目前这是我的activity_dynamic_grid_layout.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/ivLogo"
android:background="#ff0000"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<android.support.v7.widget.GridLayout
android:id="@+id/grid_layout"
android:background="#004080"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ivLogo"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="36dp">
</android.support.v7.widget.GridLayout>
我在这里将 GridLayout
宽度和高度设置为 match_parent
,但我在运行时使用 ViewTreeObserver.OnPreDrawListener
更改它们以获得方形板。这有效,彩色背景按预期显示正方形 space。
我的onCreate()
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_grid_layout);
GridLayout gl = (GridLayout) findViewById(R.id.grid_layout);
gl.setColumnCount(8);
gl.setRowCount(8);
for(int i=0; i<gl.getRowCount(); i++)
{
GridLayout.Spec rowSpec = GridLayout.spec(i, 1, GridLayout.FILL);
for(int j=0;j<gl.getColumnCount();j++)
{
GridLayout.Spec colSpec = GridLayout.spec(j,1, GridLayout.FILL);
TextView tvChild = new TextView(this);
tvChild.setText("[ " + i + " | " + j + " ]");
tvChild.setTextSize(18f);
tvChild.setTextColor(Color.WHITE);
tvChild.setGravity(Gravity.CENTER);
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
myGLP.rowSpec = rowSpec;
myGLP.columnSpec = colSpec;
gl.addView(tvChild, myGLP );
}
}
final View rootView = findViewById(R.id.dynamic_root);
rootView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
int w = rootView.getMeasuredWidth();
int h = rootView.getMeasuredHeight();
int min = Math.min(w, h);
ViewGroup.LayoutParams lp = gl.getLayoutParams();
lp.width = min - min % 9;
lp.height = lp.width;
gl.setLayoutParams(lp);
rootView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
}
我已经尝试过的:
我在布局文件中放置了一个 TextView
子节点,并尝试从其 GridLayout.LayoutParams
:
layout_columnWeight
和 layout_rowWeight
<android.support.v7.widget.GridLayout
...>
<TextView
android:id="@+id/clone_my_params"
android:text="[ 0 | 0 ]"
android:textColor="#ffffff"
android:textSize="18sp"
app:layout_column="0"
app:layout_row="0"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
/>
</android.support.v7.widget.GridLayout>
onCreate()
中的附加代码,在双循环之前:
TextView v = (TextView)gl.findViewById(R.id.clone_my_params);
v.setGravity(Gravity.CENTER);
GridLayout.LayoutParams gridLayoutParamsToCopy = new GridLayout.LayoutParams(v.getLayoutParams());
在循环中,我跳过了 (i,j) = (0,0) 并更改了
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
到
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
改变前,所有元素都在左上角,多余的space给到最后一行/列。更改后第一行/列多出space,其他元素无变化
双循环后调用gl.invalidate()
and/orgl.requestLayout()
没有效果
看来我没能使用复制构造函数设置所需的权重。
要为您的 Gridlayout 的子项设置权重,请使用采用浮点值的 spec()(例如 one)方法之一。
另一种方法是制作自定义视图(在这种情况下您需要手动绘制棋子)或自定义 ViewGroup(在这种情况下自定义 ViewGroup 将只负责棋子的定位,这如果您计划拥有比简单的 TextView 更复杂的视图层次结构,这将是合适的。
-给你! :>
Button button = new Button(this);
GridLayout.LayoutParams param= new GridLayout.LayoutParams(GridLayout.spec(
GridLayout.UNDEFINED,GridLayout.FILL,1f),
GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f));
param.height = 0;
param.width = 0;
button.setLayoutParams(param);