[英]How to set layout_columnWeight for a GridLayout child when added programmatically?
I'd like to use a GridLayout
(not GridView
) as board for a game like chess or checkers. 我想使用
GridLayout
(不是GridView
)作为象棋或棋子等游戏的棋盘。 As I'm a little reluctant to use an xml file with 64 child View
s, I've tried adding them programmatically. 由于我有点不愿意使用带有64个子
View
的xml文件,我尝试以编程方式添加它们。
To keep things simple, I started with using TextView
s as child View
s for the GridLayout
. 为了简单
TextView
,我开始使用TextView
作为GridLayout
子View
。
My problem is that the View
s are not distributed evenly, and that I don't know how to get an even distribution in my java code. 我的问题是
View
不是均匀分布的,而且我不知道如何在我的java代码中获得均匀分布。 There is no method like "setWeight()" for setting layout_columnWeight
and layout_rowWeight
. 没有类似“setWeight()”的方法来设置
layout_columnWeight
和layout_rowWeight
。
At present, this is my activity_dynamic_grid_layout.xml : 目前,这是我的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>
I've set the GridLayout
width and height to match_parent
here, but I'm changing them at runtime using a ViewTreeObserver.OnPreDrawListener
in order to get a square board. 我在这里将
GridLayout
宽度和高度设置为match_parent
,但我在运行时使用ViewTreeObserver.OnPreDrawListener
更改它们以获得方板。 This works, the colored background is showing a square space as intended. 这是有效的,彩色背景显示了预期的方形空间。
My onCreate() 我的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;
}
});
}
What I've tried already: 我已经尝试过了:
I put one TextView
child in the layout file and tried to copy the layout_columnWeight
and layout_rowWeight
from its GridLayout.LayoutParams
: 我在布局文件中放了一个
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>
Additional code in onCreate()
, before the double loop: 在double循环之前
onCreate()
附加代码:
TextView v = (TextView)gl.findViewById(R.id.clone_my_params);
v.setGravity(Gravity.CENTER);
GridLayout.LayoutParams gridLayoutParamsToCopy = new GridLayout.LayoutParams(v.getLayoutParams());
Inside the loop, I skipped (i,j) = (0,0) and changed 在循环内部,我跳过(i,j)=(0,0)并更改
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
to 至
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
Before the change, all elements were in the upper left corner, the excess space was given to the last row/ column. 在更改之前,所有元素都在左上角,多余的空间被赋予最后一行/列。 After the change, the first row/ column had the excess space, no change for the other elements.
更改后,第一行/列具有多余空间,其他元素没有变化。
Calling gl.invalidate()
and/or gl.requestLayout()
after the double loop had no effect. 双循环后调用
gl.invalidate()
和/或gl.requestLayout()
无效。
So it seems that I did not manage to set the desired weight by using the copy constructor. 因此,似乎我没有设法通过使用复制构造函数来设置所需的权重。
-Here you are ! -这个给你 ! :>
:>
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);
To set the weight on the children of your Gridlayout use one of the spec()(like this one ) methods that takes a float value. 要在Gridlayout的子项上设置权重,请使用其中一个采用浮点值的spec()(如此)方法。
Another approach would be a either make a custom View(in which case you'll need to manually draw the pieces) or a custom ViewGroup(in which case the custom ViewGroup will just take care of the pieces positioning, this will be appropriate if you plan to have more complex view hierarchies than a simple TextView). 另一种方法是制作自定义视图(在这种情况下,您需要手动绘制碎片)或自定义ViewGroup(在这种情况下,自定义ViewGroup将只处理碎片定位,这将是合适的,如果你计划拥有比简单TextView更复杂的视图层次结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.