Chciałbym użyć tablicy GridLayout
(nie GridView
) do gry w szachy lub warcaby. Ponieważ jestem trochę niechętny do korzystania z pliku xml z 64 dziećmi View
s, próbowałem je dodawać programowo.Jak ustawić parametr column_columnWeight dla elementu potomnego GridLayout, gdy jest on dodawany programowo?
Aby wszystko było proste, zacząłem od używania TextView
s jako dziecka View
s dla .
Mój problem polega na tym, że View
s nie są rozmieszczone równomiernie, a ja nie wiem, jak uzyskać równomierną dystrybucję w moim kodzie java. Nie ma metody takiej jak "setWeight()" dla ustawienia layout_columnWeight
i layout_rowWeight
.
Obecnie jest to mój 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>
mam ustawić szerokość i wysokość GridLayout
do match_parent
tutaj, ale ja ich zmiany w czasie wykonywania przy użyciu ViewTreeObserver.OnPreDrawListener
w celu zdobądź kwadratową planszę. To działa, kolorowe tło pokazuje kwadratową spację zgodnie z przeznaczeniem.
Moja 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;
}
});
}
Co Próbowałem już:
kładę jeden TextView
dziecko w pliku layoutu i próbował skopiować layout_columnWeight
i layout_rowWeight
z jego GridLayout.LayoutParams
:
<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>
Kod dodatkowy w onCreate()
przed podwójnej pętli:
TextView v = (TextView)gl.findViewById(R.id.clone_my_params);
v.setGravity(Gravity.CENTER);
GridLayout.LayoutParams gridLayoutParamsToCopy = new GridLayout.LayoutParams(v.getLayoutParams());
Wewnątrz pętli pominąłem (i, j) = (0,0) i zmienił
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
do
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
Przed zmianą wszystkie elementy znajdowały się w lewym górnym rogu, nadmiar miejsca był nadawany do ostatniego wiersza/kolumny. Po zmianie pierwszy wiersz/kolumna miał nadmiar przestrzeni, bez zmian dla pozostałych elementów.
Wywołanie gl.invalidate()
i/lub gl.requestLayout()
po tym, jak podwójna pętla nie przyniosła efektu.
Wygląda na to, że nie udało mi się ustawić żądanej wagi za pomocą konstruktora kopii.
Przede wszystkim, jeśli chcesz to kwadrat siatki 8x8 może być łatwiej (i skuteczny), aby zwyczaj ViewGroup (jest wdrożenie byłoby dość proste). Po drugie, czy nie powinieneś używać metody spec, która odbiera float jak http://developer.android.com/reference/android/widget/GridLayout.html#spec(int, int, android.widget.GridLayout.Alignment, float) dla specyfikacji? – Luksprog
@Luksprog - o niestandardowej ViewGroup: Mam prototyp gry z niestandardowym widokiem jako gameboard, przesłaniając "onDraw()", a teraz eksperymentuję z GridView oraz GridLayout. Jestem raczej nowy w rozwoju Androida i staram się dowiedzieć, która wersja będzie najlepsza z punktu widzenia wydajności. O metodzie: OK, tak się dzieje, jeśli poziom API ustawiony jest na 14 - użyłem spec (int start, int size) i dopiero teraz zauważyłem, że istnieje spec (int start, float weight). Myślę, że moje wsparcie GridLayout też je ma, może tego właśnie mi brakowało. Dzięki za podpowiedź! – 0X0nosugar
@Luksprog - misja zakończona :) Dodanie "1f" jako ostatniego parametru w spec() zmyśliło. Czy chciałbyś zapisać to jako odpowiedź, abym mógł przegłosować? – 0X0nosugar