Android 关于一些首页复杂布局的写法

在这里插入图片描述

好久没有更新文章了,呈这几天有空把。关于自己在实际项目中遇到的首页布局,以及一些自己的做法分享给大家把。=v=!,望大家取其精华去其糟粕。

对应的blog链接【Android 关于一些首页复杂布局的写法】

效果图-v-!!

效果图

大家如果遇到这总一般新手肯定会先采取这个RecycleView与NestedScrollView的嵌套。或者是一个大的RecycleView+RecycleView进行嵌套。这样做也不是不可以,只是性能方面不尽人意。

思路:所以最终的方案还是一个RecycleView+多布局+GridLayoutManager SpanSize 搞定所有首页布局,总之就是避免嵌套

先看看怎么做吧。

布局拆分类型

看到上面的效果,我们主要可以划分为几个类型

在这里插入图片描述

companion object {
        const val TITLE_TYPE = 1
        const val CONTENT_STYLE_1 = 2
        const val CONTENT_STYLE_2 = 3
        const val BANNER_TYPE = 4
        const val LIST_SQUARE_TYPE = 5
        const val LIST_RECTANGLE_TYPE = 6
        const val HEARD_TYPE = 7
    }

布局划分完后,我们来看看大概的实现思路

GridLayoutManager SpanSize(核心)

这里面就是用到一个小技巧,就是GridLayoutManager里面的setSpanSizeLookup方法

final GridLayoutManager gridManager = (GridLayoutManager)manager;
            gridManager.setSpanSizeLookup(new androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup() {
                public int getSpanSize(int position) {
                   return 1
                    }
                }
            });

要求返回一个int类型,什么意思呢?简单的说就是你一个item占用几格

公式是这样子的

item占用的列数 = spanCount / getSpanSize返回的int值

所以有了这个东西,看效果图,分析一下把
在这里插入图片描述

数据平整化。处理数据

知道了每个类型Item所需分配的SpanSize之后,这一步的目的在于拼装数据。组合成你想要的布局集合。
就拿下面的布局来说,服务器大概会返回一些与我们预期不一样的一段数据
在这里插入图片描述
要做的就是把gridVideos 拆分为标题类型和内容类型数据。

it.data.gridVideos.forEach {
       //构建标题
        val titleInfo = HomeListInfo()
        titleInfo.currType = HomeListInfo.TITLE_TYPE
        titleInfo.title = title
        list.add(titleInfo)
            for (index in it.videoTemplates!!.indices) {
                 val videoTemplatesBean = it.videoTemplates[index]
                 //构建内容模块
                 val contentInfo = HomeListInfo()
                 contentInfo.currType = HomeListInfo.CONTENT_STYLE_2
                 //当前在list位置
                 contentInfo.listIndex = index
                 contentInfo.videoTemplatesBean = videoTemplatesBean
                 list.add(contentInfo)
              }
       } 

这样的话在配合SpanSize分配每个类型占用的列数。就ok

布局间距

没啥好说的,就是自定义RecyclerView.ItemDecoration 然后根据spanSize去调整偏移量咯

 GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
        int itemPosition = parent.getChildAdapterPosition(view);
        if (layoutManager != null) {
            int spanSize = layoutManager.getSpanSizeLookup().getSpanSize(itemPosition);
            //一列的时候
            if (spanSize == layoutManager.getSpanCount()) {
                if (layoutManager.getItemViewType(view) != HomeListInfo.HEARD_TYPE &&
                        layoutManager.getItemViewType(view) != HomeListInfo.LIST_SQUARE_TYPE &&
                        layoutManager.getItemViewType(view) != HomeListInfo.LIST_RECTANGLE_TYPE) {
                    outRect.left = headSpace;
                    outRect.right = footSpace;
                }
            }
            //三列的时候
            else if (spanSize == 2) {
                int infoListIndex = getListPosition(parent, view);
                //如果是在左边
                if (isFirstColumn(3, infoListIndex)) {
                    outRect.left = headSpace;
                    outRect.right = space;
                    //如果是在右边
                } else if (isLastColumn(parent, infoListIndex, 3)) {
                    outRect.left = space;
                    outRect.right = footSpace;
                } else {
                    //在中间
                    outRect.left = space;
                    outRect.right = space;
                }
            }
            //二列的时候怎么
            else if (spanSize == 3) {
                int infoListIndex = getListPosition(parent, view);
                //如果在左边
                if (isFirstColumn(2, infoListIndex)) {
                    outRect.left = headSpace;
                    outRect.right = space;
                } else {
                    //右边
                    outRect.left = space;
                    outRect.right = footSpace;
                }
            }
        }

总结

Demo

以上就是自己写这种首页布局的常用的方法,如果大家觉得有什么比较好的做法可以留言告知。希望能够帮到大家!!完

Android 中使用 Socket 进行通讯可以分为服务端和客户端两种角色,下面分别介绍它们的写法: ### 服务端 服务端需要监听一个端口,并在有客户端连接时接受客户端的请求并返回响应。以下是服务端的基本写法: ```java try { // 创建一个 ServerSocket 对象,指定监听的端口号 ServerSocket serverSocket = new ServerSocket(8888); Log.d("Server", "Server started: " + serverSocket); while (true) { // 接受客户端的连接请求,返回一个 Socket 对象 Socket clientSocket = serverSocket.accept(); Log.d("Server", "Client connected: " + clientSocket); // 从输入流中读取客户端发送的数据 InputStream inputStream = clientSocket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String request = reader.readLine(); // 读取一行数据 // 向输出流中写入响应数据 OutputStream outputStream = clientSocket.getOutputStream(); outputStream.write("Hello, client!\n".getBytes()); // 关闭连接 clientSocket.close(); } } catch (IOException e) { e.printStackTrace(); } ``` ### 客户端 客户端需要连接到服务端指定的端口,并向服务端发送请求并接收响应。以下是客户端的基本写法: ```java try { // 创建一个 Socket 对象,指定服务端的 IP 地址和端口号 Socket socket = new Socket("server-ip-address", 8888); Log.d("Client", "Connected to server: " + socket); // 向输出流中写入请求数据 OutputStream outputStream = socket.getOutputStream(); outputStream.write("Hello, server!\n".getBytes()); // 从输入流中读取服务端的响应数据 InputStream inputStream = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String response = reader.readLine(); // 读取一行数据 Log.d("Client", "Response from server: " + response); // 关闭连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } ``` 注意,在 Android 中访问网络需要在 AndroidManifest.xml 中声明网络访问权限:`<uses-permission android:name="android.permission.INTERNET" />`。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值