• 水友的一个循环列表(带下拉刷新,上拉加载)


    cocos论坛原文地址:Cocos Creator ScrollView 性能优化之 UISuperScrollView 开箱即用

    代码下载地址:https://github.com/icipiqkm/UISuperScrollView

    demo下载

    水友的循环列表

    cocos也不提供这样的组件,自己写的列表没有下拉刷新和上拉加载功能,所以如果有项目要用到,直接用水友的好了。

    水友的列表是继承cc.ScrollView扩展的,用法就是先创建一个cocos默认的scrollView,把scrollView节点上的cc.ScrollView删除,替换为UISuperScrollView

    节点content挂上UISuperLayout,这是用于布局。具体使用得看github上demo

     

    一个普通垂直列表

     

    按着demo自己实现一个普通垂直列表,注意到几个问题:

    1 item创建倍率问题

    如下图,在item创建倍率默认2情况下,能看见的item是8个,但是创建的item是15个,有很多item都是浪费的。

    所以设置item倍率为1.2,这样会减少创建多余的item。例如下图,下拉列表效果不变的情况下,ListItem只有10个。

    2 RefreshItemEvents 刷新事件问题

    默认刷新事件是在属性面板中设置的

    我习惯在代码里监听,所以将RefreshItemEvents属性去掉了,改为代码里监听

    UISupserLayout.ts:

    一个普通垂直列表的代码Vertical.ts:

    /**
     * 垂直列表
     */
    @ccclass
    export default class Vertical extends cc.Component {
    
        @property({ type: UISpuerScrollView, tooltip: "列表scrollView" })
        scrollView: UISpuerScrollView = null;
        @property({ type: UISuperLayout, tooltip: "列表layout" })
        layout: UISuperLayout = null;
    
        private testList = [
            { id: 0, msg: "1" },
            { id: 1, msg: "1" },
            { id: 2, msg: "1" },
            { id: 3, msg: "1" },
            { id: 4, msg: "1" },
            { id: 5, msg: "1" },
            { id: 6, msg: "1" },
            { id: 7, msg: "1" },
            { id: 8, msg: "1" },
            { id: 9, msg: "1" },
            { id: 10, msg: "1" },
            { id: 11, msg: "1" },
            { id: 12, msg: "1" },
            { id: 13, msg: "1" },
            { id: 14, msg: "1" },
            { id: 15, msg: "1" },
        ]
    
        onLoad() {
            this.layout.node.on(UISuperLayout.REFRESH_ITEM, this.refreshItem, this);
            this.layout.total(this.testList.length);
        }
    
        /**数据更新 */
        private refreshItem(node: cc.Node, index: number) {
            node.getComponent(ListItem).dataChanged(this.testList[index]);
        }
    }
    

      

    一个普通的水平列表

    只要选择UISuperScrollView和UISuperLayout的Horizontal就行了。

    一个普通的网格列表

     

    网格列表不需要像cc.ScrollView那样选择Grid布局,而是设置UISuperLayout的每组item个数

    例如上图的网格布局,每列3个item。

    一个普通的向上循环

    向上或向下循环,勾选UISuperLayout的头部滑动循环和尾部滑动循环就行。

    但是这个循环功能是有问题的,如上图列表最长是29,向上显示到0以后,理论上是从29接着循环,实际是从10开始接着循环。

     上拉和下拉事件

    UI显示方面,在view节点下放上head和foot两个文本,用于显示刷新状态。

    head和foot节点的高度必须和UISuperScrollView的顶部偏移量和底部偏移量一致。例如下图中设置为50,那么head和foot节点也必须是50,代码中根据这个值来控制刷新时content的位置。

    触发下拉事件的条件是滚动容器滑动距离超过:顶部偏移量*满足触发Header的倍数,如下图就是50*2=100,下拉滑动超过100像素就会触发下拉事件。

    水友使用属性面板中来绑定事件的,我改成了在代码中绑定。

    我修改了源码,让上拉和下拉事件在代码中监听:

    this.scrollView.node.on(UISpuerScrollView.PULL_DOWN, this.pullDown, this);
    this.scrollView.node.on(UISpuerScrollView.PULL_UP, this.pullUp, this);
    
    //下拉事件
    private pullDown(event: UISuperHeaderAndFooterEvent){
    
    }
    
    //上拉事件
    private pullUp(event: UISuperHeaderAndFooterEvent){
    
    }
    

    触发上拉或下拉事件后,需要加载数据并刷新列表,并显示加载和刷新的进度,这些操作需要根据event的值来进行,event意义如下:

    完整代码:

    import UISuperLayout from "../../src/UISuperLayout";
    import UISpuerScrollView, { UISuperHeaderAndFooterEvent } from "../../src/UISuperScrollView";
    import ListItem from "../common/ListItem";
    
    const { ccclass, property } = cc._decorator;
    
    @ccclass
    export default class Refresh extends cc.Component {
    
        @property({ type: UISpuerScrollView, tooltip: "列表scrollView" })
        scrollView: UISpuerScrollView = null;
        @property({ type: UISuperLayout, tooltip: "列表layout" })
        layout: UISuperLayout = null;
    
        @property({ type: cc.Node, tooltip: "头部文字根节点" })
        head: cc.Node = null;
        @property({ type: cc.Node, tooltip: "底部文字根节点" })
        foot: cc.Node = null;
        @property({ type: cc.Label, tooltip: "头部文字" })
        headLab: cc.Label = null;
        @property({ type: cc.Label, tooltip: "底部文字" })
        footLab: cc.Label = null;
    
        private testList = [];
    
        onLoad() {
            for (let i = 0; i < 2; i++) {
                this.testList.push({ id: i, msg: i + "" });
            }
    
            this.head.scaleY = 0;
            this.foot.scaleY = 0;
    
            this.layout.node.on(UISuperLayout.REFRESH_ITEM, this.refreshItem, this);
            this.scrollView.node.on(UISpuerScrollView.PULL_DOWN, this.pullDown, this);
            this.scrollView.node.on(UISpuerScrollView.PULL_UP, this.pullUp, this);
            this.layout.total(this.testList.length);
        }
    
        /**数据更新 */
        private refreshItem(node: cc.Node, index: number) {
            node.getComponent(ListItem).dataChanged(this.testList[index]);
        }
    
        /**下拉事件 */
        private pullDown(event: UISuperHeaderAndFooterEvent) {
            //文字显示
            if (event.progressStage == "wait") {
                this.headLab.string = "下拉刷新";
                this.head.scaleY = 1;
            } else if (event.progressStage == "lock") {
                this.headLab.string = "刷新中";
            }
            //执行刷新操作
            if (event.action == true) {
                for (let i = 0; i < 2; i++) {
                    this.testList.unshift({ id: i, msg: "新增:" + i });
                }
                this.layout.total(this.testList.length);
            }
            //隐藏文字显示
            if (event.action == false && event.progressStage == "release" && event.progress <= 1) {
                this.head.scaleY = 0;
            }
        }
    
        /**上拉事件 */
        private pullUp(event: UISuperHeaderAndFooterEvent) {
            //文字显示
            if (event.progressStage == "wait") {
                this.footLab.string = "上拉刷新";
                this.foot.scaleY = 1;
            } else if (event.progressStage == "lock") {
                this.footLab.string = "刷新中";
            }
            //执行刷新操作
            if (event.action == true) {
                for (let i = 0; i < 2; i++) {
                    this.testList.push({ id: i, msg: "新增:" + i });
                }
                this.layout.total(this.testList.length);
            }
            //隐藏文字显示
            if (event.action == false && event.progressStage == "release" && event.progress <= 1) {
                this.foot.scaleY = 0;
            }
        }
    }
    

      

     

  • 相关阅读:
    iozone
    2019-11-23-WPF-使用-RawInput-接收裸数据
    2019-11-22-Roslyn-在多开发框架让-msbuild-的-Target-仅运行一次
    2019-3-1-C#-json-转-xml-字符串
    2018-11-19-visualStudio-无法登陆
    2019-4-21-Roslyn-通过-NuGet-库修改应用程序入口函数
    2019-8-31-dotnet-core-集成到-Mattermost-聊天工具
    2019-7-29-win10-UWP-使用-MD5算法
    2018-8-10-C#-TimeSpan-时间计算
    2019-6-15-WPF-触摸到事件
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/16149082.html
Copyright © 2020-2023  润新知