从多宫格的Z型布局到圈式布局

 前言

        最近在研究九宫格一直往上兼容到n宫格的时候发现一个很有意思的问题,就是如果使用flex布局实现多宫格布局的话,不处理的话,进行生成的时候展示的dom节点顺序是Z型布局:

        

         这和九宫格抽奖转动的顺序不能说是完全相反,但是可以说是毫不沾边。

        理想状态的布局顺序应该是圈式布局,也就是多宫格高亮块的移动顺序和输入数据的顺序应该是完全一致的:

        

        也就是移动顺序应该是从“宇宙战将1”→ “白起2”→“太阳系级宇宙战舰3”→“小破木船4”→“地球级宇宙战将5”→“月球级蘸酱6”→“太阳级蘸酱7”→“大西洋级蘸酱8”→“宇宙战将1”→……

         那么同样都是输入:

['宇宙战将1','白起2','太阳系级宇宙战舰3','大西洋级蘸酱8','小破木船4','太阳级蘸酱7','月球级蘸酱6','地球级宇宙战将5']

        到底应该怎么样处理才能实现圈式分布呢?

        首先明确基调,为了生成多宫格布局,使用的是flex布局,所以就得把输入的

[1,2,3,4,5,6,7,8]

         调整转化为:(为了方便用数字来表示初始顺序)

[1,2,3,8,4,7,6,5]

        而且这个转化方式还得兼容3*3,4*4,5*5……n*n等多级多宫格的顺序改变。

        我们可以将3*3,4*4,5*5先并列列出来感受一下他们的顺序:

规律探究

     1.  3x3,八宫格

         可以看出:

        Z型布局:[1,2,3,4,5,6,7,8]

        圈型布局:[1,2,3,8,4,7,6,5]

      2.  4x4,十二宫格

         可以看出:

        Z型布局:[1,2,3,4,5,6,7,8,9,10,11,12]

        圈型布局:[1,2,3,4,12,5,11,6,10,9,8,7]

      3.  5x5,十六宫格

         可以看出:

        Z型布局:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]

        圈型布局:[1,2,3,4,5,16,6,15,7,14,8,13,12,11,10,9]

        当我们将这些数据排列出来:

 规律总结: 

        经过将以上结果比较,发现了一个规律:(以3*3为例)

         就3*3而言,将最后一个数移动到三和四之间,然后截取后三位,进行顺序反转后再重新接回,这样就得到了圈型布局的顺序。

         4*4:

         5*5:

        之前我们也知道了,当n*n布局时,应该会有4n-4个元素,根据前面规律我们就可以大胆推测,n*n的Z型布局到圈型布局的变化方法应该是,从尾部截取n个数据,分别对应插到 数组的第n下标,第n+2下标,n+4,……一直到截取的数据插入完成,然后再取尾部的n个数据,进行翻转处理,最后组合起来就得到了能在flex布局下形成圈式布局的元素排列。

        对应代码:

/**
 *  function, 将顺序从Z型布局变成圈型布局
 *  @param arr Array, 待改变顺序的数组
 *  @param level Number, 所希望生成的多宫格的层级
 *  @return 改变顺序后的数组
 * */
function nineGridOrder(arr,level){
    if(Array.isArray(arr) && arr.length==(4*level-4)){
        // 对数据进行浅拷贝
        let list = [...arr];
        // 在当前层级下期望的元素总个数
        const expectCount = 4*level - 4;
        // 取要进行对应插入的尾部
        let tailArr = list.splice(expectCount-level+2,expectCount).reverse();
        // 取要进行翻转处理的尾部
        let otherTail = list.splice(expectCount-2*level+2,expectCount).reverse();
        // 进行对应插入
        for (let i = 0; i < tailArr.length; i++) {
            list.splice(level+2*i, 0, tailArr[i])
        }
        // 重新组合后输出
        return list.concat(otherTail)
    }else{
        throw('层级与数据对应不正确,请检查输入层级后重试')
    }
}

 结果验证:

        为保证正确,我们取该程序验证6*6,二十宫格情况下的排列是否正确。

        运行程序我们可以得到:

         如果用图形验证:

         由上图可以看出,

        Z型布局:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

        圈型布局:[1,2,3,4,5,6,20,7,19,8,18,9,17,10,16,15,14,13,12,11]

         与运算结果一致。

 实际应用:

        当用到九宫格及其拓展上时候,效果如下:

         我们可以看出,不管咋样增加层级,奖品的排列顺序始终是抽奖的顺序。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android中的宫格布局可以使用GridView来实现。GridView是一个可滚动的视图,其中的元素按照网格形式排列。GridView需要一个adapter来提供数据和视图,可以使用ArrayAdapter或自定义的Adapter。 下面是一个简单的宫格布局实现: 1. 在XML布局文件中添加GridView组件: ``` <GridView android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:columnWidth="100dp" android:numColumns="auto_fit" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" android:gravity="center"/> ``` 2. 在Activity中获取GridView组件,并设置Adapter: ``` GridView gridview = (GridView) findViewById(R.id.gridview); gridview.setAdapter(new ImageAdapter(this)); ``` 3. 自定义Adapter实现getView方法: ``` public class ImageAdapter extends BaseAdapter { private Context mContext; public ImageAdapter(Context c) { mContext = c; } public int getCount() { return mThumbIds.length; } public Object getItem(int position) { return null; } public long getItemId(int position) { return 0; } // create a new ImageView for each item referenced by the Adapter public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { // if it's not recycled, initialize some attributes imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(100, 100)); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setPadding(8, 8, 8, 8); } else { imageView = (ImageView) convertView; } imageView.setImageResource(mThumbIds[position]); return imageView; } // references to our images private Integer[] mThumbIds = { R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5, R.drawable.image6, R.drawable.image7, R.drawable.image8, R.drawable.image9, R.drawable.image10 }; } ``` 这里使用了ImageView作为GridView的子项,并设置了每个子项的大小、填充和缩放方式。在getView方法中,将图片资源设置为ImageView的图像。 这样就可以实现一个简单的宫格布局
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YOLO浪漫收藏家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值