Java – how to programmatically add the layout of GridLayout children_ columnWeight?
I want to use GridLayout (not GridView) as a board for games such as chess or chess Since I was a little reluctant to use XML files with 64 subviews, I tried to add them programmatically
For simplicity, I started using textviews as a child view of GridLayout
My problem is that the views are not evenly distributed. I don't know how to get uniform distribution in my java code Set layout_ Columnweight and layout_ Rowweight has no method like "setweight()"
At present, this is my 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>
Here I set the width and height of the GridLayout to match_ Parent, but I use viewtreeobserver at runtime Onpredrawlistener changes them to get a square board In this way, the color background shows the square space
My 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,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; } }); }
I've tried:
I put a textview subitem in the layout file and tried to get it from its GridLayout Copy layout in layoutparams_ Columnweight and 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 double loop:
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 skip (I, J) = (0,0) and change
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
to
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
Before the change, all elements are in the upper left corner, and the extra space is given to the last row / column After the change, the first row / column has extra space, and other elements do not change
After double loop, call gl.. Invalidate() and / or GL Requestlayout() is invalid
So I don't seem to have managed to set the required weight by using the copy constructor
Solution
To set weights on children of a GridLayout, use one of the spec() (one) methods that take floating-point values
Another method is to make a custom view (in this case, you need to draw fragments manually) or a custom ViewGroup (in this case, the custom ViewGroup will only deal with fragment positioning, which will be appropriate if you plan to have a more complex view hierarchy than a simple textview