Android网格布局像GridLayoutManager样式一样对齐

问题描述

我有以下GridLayout,它存储最多6个最大列:

<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" />

在这里填充它:

  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);

    }

我当前具有6张图像的输出是这样的:

enter image description here

具有3张图片

enter image description here

有2张图片

enter image description here

我想要的输出是:

对于6张图片

enter image description here

对于2张图片

enter image description here

对于4张图片

enter image description here

我希望它从左到右均匀地添加它们,如果图像没有足够的空间适合自己放置,我希望它与其他“碰撞”而不是在它们之间留出空白(您可以参见示例)。那就是我看到GridLayoutManager起作用的方式。我该如何实现?

解决方法

您可以创建自定义布局来处理您的不同案例。如下所示:

<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" type="text/css" href="style.css"> 
</head>

<body> 


<div class="box-container">

<div class="subbox-container">

    <!-- Start Box -->
    <div id="box1" class ="box" style="margin: 0; z-index: 4; width: 257.829px; height: 42.6555px; opacity: 1; transform-origin: 128.914px 21.3277px; transform: translate(139px,84px) rotate(0deg) scale(1,1);" aria-label="do you ever">

        <svg height="42.655499999999996" width="162" viewBox="0 0 172 45">
            <text font-family="Heebo-Light" font-size="24px" fill="#595959" fill-opacity="1" x="50%" y="53%" dominant-baseline="middle" text-anchor="middle">
              <tspan>do you ever</tspan>
           </text> 
        </svg>

        <svg height="42.655499999999996" width="162" viewBox="0 0 272 45" preserveAspectRatio="none">

            <defs>

               <linearGradient gradientTransform="rotate(90,0.5,0.5)" id="uniqueDomId-1114">
                  <stop offset="0%" stop-color="#AFAFAF" stop-opacity="1"></stop>
                  <stop offset="0%" stop-color="#F5F3F8" stop-opacity="1"></stop>
                  <stop offset="69.804%" stop-color="#F9F9F9" stop-opacity="1"></stop>
                  <stop offset="100%" stop-color="#FFFFFF" stop-opacity="1"></stop>
               </linearGradient>

               <filter id="uniqueDomId-1115" filterUnits="userSpaceOnUse" x="-15.75" y="-15.75" width="303.5" height="76.5">
                  <feFlood result="floodOut" flood-color="#CCC1DA" flood-opacity="0.29"></feFlood>
                  <feGaussianBlur result="gaussOut" in="SourceAlpha" stdDeviation="2.450000047683716,2.450000047683716">
                  </feGaussianBlur>
                  <feComposite in="floodOut" in2="gaussOut" operator="in"></feComposite>
               </filter>

            </defs>

            <use transform="translate(-2.72,-0.45) scale(1.0199999809265137,1.0199999809265137) translate(0,0)" xlink:href="#uniqueDomId-1116" filter="url(#uniqueDomId-1115)" data-angle="0" data-distance="0" data-height="45" data-scale="1.02" data-adornment-type="drop-shadow" data-width="272" data-transform="[{&quot;type&quot;:&quot;translate&quot;,&quot;args&quot;:[-2.72,-0.45]},{&quot;type&quot;:&quot;scale&quot;,&quot;args&quot;:[1.0199999809265137,1.0199999809265137]}]"></use>

            <g id="uniqueDomId-1116">
               <g id="uniqueDomId-1117">
                  <path d="M0,0L272,0 272,45 0,45z" id="uniqueDomId-1118" fill="url(#uniqueDomId-1114)"></path>
               </g>
               
            </g>
        </svg>
    </div>
    <!-- End Box -->


    <!-- Start Box -->
    <div id="box2" class ="box" style="margin: 0; z-index: 4; width: 257.829px; height: 42.6555px; opacity: 1; transform-origin: 128.914px 21.3277px; transform: translate(139px,45z" id="uniqueDomId-1118" fill="url(#uniqueDomId-1114)"></path>
               </g>
               
            </g>
        </svg>
    </div>
    <!-- End Box -->

    <!-- Start Box -->
    <div id="box3" class ="box" style="margin: 0; z-index: 4; width: 257.829px; height: 42.6555px; opacity: 1; transform-origin: 128.914px 21.3277px; transform: translate(139px,45z" id="uniqueDomId-1118" fill="url(#uniqueDomId-1114)"></path>
               </g>
               
            </g>
        </svg>
    </div>
    <!-- End Box -->

</div>

<!-- background rectangle -->
<div class="background-rectangle" style="height: 230px; width: 162px; transform: translate(139px,-79px);">
    <svg height="230" width="162" viewBox="-1 -1 274 186" data-commandset-id="35">
        <g >
            <path d="M259.147003,1E-06C266.245483,-1.2E-05 271.999939,5.754436 271.999969,12.852937 271.999969,12.85294 271.999969,12.852942 271.999969,12.852945L271.999969,171.147034C271.999969,178.245529 266.245514,183.999985 259.147034,183.999985L259.147034,183.999985L12.852946,183.999985C5.754463,183.999985 3E-06,178.245529 0,171.147049L0,12.85295C-5E-06,5.754468 5.754446,7E-06 12.852927,-1E-06z" id="uniqueDomId-1466" fill="#E6E0EC" fill-opacity="0.7" stroke-width="1" stroke="#CCC1DA" stroke-opacity="0.14" stroke-linecap="flat" stroke-linejoin="round" data-stroke-sharpened="true" transform="translate(0.5,0.5)"></path>
        </g>
    </svg>
</div>

</div>





<script src="script.js"></script>
</body>

</html>

对于3张图片:

enter image description here

对于5张图片:

enter image description here

更新1: 更改onLayout方法以将子级放置在布局的中心


 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,defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public PokemonLayout(Context context,int defStyleAttr,int defStyleRes) {
        super(context,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,(i*widthOffset) + childWidth,child.getMeasuredHeight());
        }
    }
}