I have the following GridLayout which stores a number of 6 maximum columns :
<androidx.gridlayout.widget.GridLayout
android:id="@+id/pokemonTeambuilderSpritesLayout"
android:layout_width="match_parent"
android:layout_height="100dp"
app:columnCount="6"
app:rowCount="1"
app:useDefaultMargins="true" />
And here I populate it :
List<Pokemon> pokemonList = pokemonTeam.getPokemonList();
for (Pokemon pokemon : pokemonList) {
CircularImageView ivPokemonSprite = new CircularImageView(mContext);
String pokemonId = pokemon.get_id();
int pokemonImageId = PokemonUtils.getPokemonSugimoriImageById(pokemonId, mContext);
Picasso.get().load(pokemonImageId).into(ivPokemonSprite);
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams(
GridLayout.spec(GridLayout.UNDEFINED, 1f),
GridLayout.spec(GridLayout.UNDEFINED, 1f)
);
layoutParams.width = 0;
ivPokemonSprite.setLayoutParams(layoutParams);
holder.teamSpritesGridLayout.addView(ivPokemonSprite);
}
My current output with 6 images is this :
With 3 images :
With 2 images:
My desired output would be :
For 6 images:
For 2 images:
For 4 images:
I want it to add them starting from left to right uniform and If the image doesn't have enough space to fit on its own I want it to "collide" with the others instead of letting margin between them (as you can see in the examples). Thats how I see that the GridLayoutManager works . How can I achieve this ?
you can create custom layout for handling your different cases. something like below:
public class PokemonLayout extends FrameLayout {
private int height;
private int width;
private int childWidth;
public PokemonLayout(Context context) {
this(context, null);
}
public PokemonLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PokemonLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public PokemonLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = Integer.MIN_VALUE;
childWidth = Integer.MIN_VALUE;
measureChildren(widthMeasureSpec, heightMeasureSpec);
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
height = Math.max(child.getMeasuredHeight(), height);
childWidth = Math.max(child.getMeasuredWidth(), childWidth);
}
setMeasuredDimension(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
@Override
protected void onLayout(boolean changed, int leftParent, int topParent, int rightParent, int bottomParent) {
int count = getChildCount();
boolean overlap = count * childWidth > width;
int widthOffset = childWidth;
if(overlap) {
widthOffset = childWidth - (Math.abs(width - (count * childWidth)) / (count-1));
}
for (int i = 0; i < getChildCount(); i++) {
View child = (View) getChildAt(i);
child.layout(i*widthOffset,
0,(i*widthOffset) + childWidth
, child.getMeasuredHeight());
}
}
}
For 3 images:
For 5 images:
UPDATE 1: change onLayout method to positioning children at the center of layout
@Override
protected void onLayout(boolean changed, int leftParent, int topParent, int rightParent, int bottomParent) {
int count = getChildCount();
boolean overlap = count * childWidth > width;
int widthOffset = childWidth;
int startOffest = (width - (count * childWidth)) / 2;
if(overlap) {
startOffest = 0;
widthOffset = childWidth - (Math.abs(width - (count * childWidth)) / (count-1));
}
for (int i = 0; i < getChildCount(); i++) {
View child = (View) getChildAt(i);
child.layout(startOffest+ (i*widthOffset),
0,(i*widthOffset) + childWidth + startOffest
, child.getMeasuredHeight());
}
}