Since you say that you have a variable number of squares, I assume that you are willing to create the n*n grid in code. Here is an approach to creating the grid. This is just one way and there are probably others.
First, create a layout with ConstraintLayout
as the root view. In that layout, define a widget that has width and height of match_constraints
and is constrained by the parent. This will give you a square widget regardless of the device orientation. (I use a View
here so it can be seen, but it is better to use a Space
widget although it probably doesn't really matter.)
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/gridFrame"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="16dp"
android:background="@android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the code for the activity that creates a 7*7 grid. We will use the on-screen view from the layout as the "parent" view to contain the squares.
MainActivity.java
public class MainActivity extends AppCompatActivity {
int mRows = 7;
int mCols = 7;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstraintLayout layout = findViewById(R.id.layout);
int color1 = getResources().getColor(android.R.color.holo_red_light);
int color2 = getResources().getColor(android.R.color.holo_blue_light);
TextView textView;
ConstraintLayout.LayoutParams lp;
int id;
int idArray[][] = new int[mRows][mCols];
ConstraintSet cs = new ConstraintSet();
// Add our views to the ConstraintLayout.
for (int iRow = 0; iRow < mRows; iRow++) {
for (int iCol = 0; iCol < mCols; iCol++) {
textView = new TextView(this);
lp = new ConstraintLayout.LayoutParams(ConstraintSet.MATCH_CONSTRAINT,
ConstraintSet.MATCH_CONSTRAINT);
id = View.generateViewId();
idArray[iRow][iCol] = id;
textView.setId(id);
textView.setText(String.valueOf(id));
textView.setGravity(Gravity.CENTER);
textView.setBackgroundColor(((iRow + iCol) % 2 == 0) ? color1 : color2);
layout.addView(textView, lp);
}
}
// Create horizontal chain for each row and set the 1:1 dimensions.
// but first make sure the layout frame has the right ratio set.
cs.clone(layout);
cs.setDimensionRatio(R.id.gridFrame, mCols + ":" + mRows);
for (int iRow = 0; iRow < mRows; iRow++) {
for (int iCol = 0; iCol < mCols; iCol++) {
id = idArray[iRow][iCol];
cs.setDimensionRatio(id, "1:1");
if (iRow == 0) {
// Connect the top row to the top of the frame.
cs.connect(id, ConstraintSet.TOP, R.id.gridFrame, ConstraintSet.TOP);
} else {
// Connect top to bottom of row above.
cs.connect(id, ConstraintSet.TOP, idArray[iRow - 1][0], ConstraintSet.BOTTOM);
}
}
// Create a horiontal chain that will determine the dimensions of our squares.
// Could also be createHorizontalChainRtl() with START/END.
cs.createHorizontalChain(R.id.gridFrame, ConstraintSet.LEFT,
R.id.gridFrame, ConstraintSet.RIGHT,
idArray[iRow], null, ConstraintSet.CHAIN_PACKED);
}
cs.applyTo(layout);
}
}
Just change mRows
and mCols
and the grid will adjust itself. If your grid will always be square, you will not need to set the ratio of the grid container in the code. You can also place your grid within a more complicated layout. Just make sure that the grid container has the right dimensions and you are good to go.
RecyclerView
with a span count of 7? – Infanticide