quick3.3 UIListview扩展应用

--[[
    自定义滑动列表控件
    1.支持UIListView所有功能
    2.额外增加让条目滑动后始终显示全部功能
    3.额外增加当条目滑过指定区域时发生放大缩小变化,调用enableAreaChange()方法即可开启
 author:chjh0540237
]]
local c = cc
local UIScrollView = cc.ui.UIScrollView
local CustomListView = class("CustomListView",cc.ui.UIListView)

--设置滑动中指定区域内有放大缩小过渡变化
--_areaParam:{point=xxx,areaValue=xxx,scaleRate=xxx}
--若滑动列表为横向,则 point 代表X轴的该点以areaValue 为 区域的中心点来作条目在该区域变化判断
--若滑动列表为竖向,则 point 代表Y轴的该点以areaValue 为 区域的中心点来作条目在该区域变化判断
--scaleRate滑动条目缩放比例,可以不填
--不传参数则取当前列表大小中心位置
function CustomListView:enableAreaChange(_areaParam)
    self.m_isAreaEnabled_ = true
    self.m_area_ = _areaParam
    self.m_rate_ = 1
    return self
end

function CustomListView:autoFixScroll()
    if UIScrollView.DIRECTION_VERTICAL == self.direction then
        self:autoFixY()
    else
        self:autoFixX()
    end
end

--横向滑动时,使条目显示全
function CustomListView:autoFixX()
    local item, pos = self:getFirstVisibleItem()
    local bound = item:getBoundingBox()
    local nodePoint = self.container:convertToWorldSpace(
        c.p(bound.x + bound.width/2, bound.y))
    local index
    if c.rectContainsPoint(self.viewRect_, nodePoint) then
        index = pos
    else
        index = pos + 1
    end
    local toItem = self.items_[index]
    bound = toItem:getBoundingBox()
    self:scrollToPos(-bound.x + self.viewRect_.x, 0)
end
--竖向滑动时,使条目显示全
function CustomListView:autoFixY()
    local item, pos = self:getFirstVisibleItem()
    local bound = item:getBoundingBox()
    local nodePoint = self.container:convertToWorldSpace(
        c.p(bound.x, bound.y+bound.height*0.5))
    local index
    if c.rectContainsPoint(self.viewRect_, nodePoint) then
        index = pos
    else
        index = pos + 1
    end
    local toItem = self.items_[index]
    bound = toItem:getBoundingBox()
    self:scrollToPos(0, -bound.y-bound.height+self.viewRect_.height+self.viewRect_.y)
end

function CustomListView:getFirstVisibleItem()
    for i=1,#self.items_ do
        if self:isItemInViewRect(self.items_[i]) then
            return self.items_[i], i
        end
    end
end

function CustomListView:scrollToPos(x, y)
--    local scrollLength = c.pGetLength(c.pSub(c.p(x, y), self.position_))
    self.position_ = c.p(x, y)
    local action = c.MoveTo:create(0.5, self.position_)
    self.scrollNode:runAction(transition.sequence({c.EaseExponentialOut:create(action),
        c.CallFunc:create(function()
            if self.m_isAreaEnabled_ then
                local _item,_index = self:getScaledItem_()
                self:callListener_{name = "scrollStop",item=_item,pos=_index}
            end
        end)
    }))
    self:scrollChange(x,y)
--    self.scrollNode:runAction(c.EaseElasticOut:create(action))
end

function CustomListView:getAllItem()
    return self.items_
end

function CustomListView:getFirstItem()
    return self.items_[1]
end

function CustomListView:getLastItem()
    return self.items_[#self.items_]
end
-- override
function CustomListView:onTouch_(event)
    if "began" == event.name and not self:isTouchInViewRect(event) then
        printInfo("UIScrollView - touch didn't in viewRect")
        return false
    end

    if "began" == event.name and self.touchOnContent then
        local cascadeBound = self.scrollNode:getCascadeBoundingBox()
        if not cc.rectContainsPoint(cascadeBound, cc.p(event.x, event.y)) then
            return false
        end
    end

    if "began" == event.name then
        self.prevX_ = event.x
        self.prevY_ = event.y
        self.bDrag_ = false
        local x,y = self.scrollNode:getPosition()
        self.position_ = {x = x, y = y}

        transition.stopTarget(self.scrollNode)
        self:callListener_{name = "began", x = event.x, y = event.y}

        self:enableScrollBar()
        -- self:changeViewRectToNodeSpaceIf()

        self.scaleToWorldSpace_ = self:scaleToParent_()

        return true
    elseif "moved" == event.name then
        if self:isShake(event) then
            return
        end

        self.bDrag_ = true
        self.speed.x = event.x - event.prevX
        self.speed.y = event.y - event.prevY

        if self.direction == UIScrollView.DIRECTION_VERTICAL then
            self.speed.x = 0
        elseif self.direction == UIScrollView.DIRECTION_HORIZONTAL then
            self.speed.y = 0
        else
            -- do nothing
        end

        self:scrollBy(self.speed.x, self.speed.y)
        self:scrollChange()
        self:callListener_{name = "moved", x = event.x, y = event.y}
    elseif "ended" == event.name then
        if self.bDrag_ then
            self.bDrag_ = false
            self:scrollAuto()
         -- self:autoFixScroll()
            self:callListener_{name = "ended", x = event.x, y = event.y}

            self:disableScrollBar()
        else
            self:callListener_{name = "clicked", x = event.x, y = event.y}
        end
    end
end

 --滚动变化
function CustomListView:scrollChange(x,y)
    if not self.m_isAreaEnabled_ then
    	return
    end
    local scrollX,scrollY = x or self:getScrollNode():getPositionX(),y or self:getScrollNode():getPositionY()
--    printf("当前正在滚动 scrollNode.pos=(%f,%f)",scrollX,scrollY)
    local line  -- = self.viewRect_.width*0.5
    local min,max -- = lineX-80,lineX+80
    local bound
    local _w,_h = self.items_[1]:getItemSize()
    local item

    if UIScrollView.DIRECTION_VERTICAL == self.direction then
        if self.m_area_ then
        	line = self.m_area_.point or self.viewRect_.height*0.5
        	_h = self.m_area_.areaValue or _h
            self.m_rate_ = self.m_area_.scaleRate or 1
        else
            line = self.viewRect_.height*0.5
        end
        min,max = line-_h*0.5,line+_h*0.5
        for i=1,#self.items_ do
            item = self.items_[i]
            local _x,_y = item:getPosition()
            bound = {x=_x,y=_y-self.viewRect_.y,width=_w,height=_h}
            local cury = bound.y+bound.height*0.5+scrollY
            if cury>min and cury<=line then
                self.items_[i]:getContent():setScale(cury/min*self.m_rate_)
                item._isScaled = true
                item:setLocalZOrder(1)
            elseif cury>line and cury<max then
                self.items_[i]:getContent():setScale((line-(cury-line))/min*self.m_rate_)
                item._isScaled = true
                item:setLocalZOrder(1)
            else
                self.items_[i]:getContent():setScale(1)
                item._isScaled = false
                item:setLocalZOrder(0)
            end
        end
    else
        if self.m_area_ then
            line = self.m_area_.point or self.viewRect_.width*0.5
            _w = self.m_area_.areaValue or _w
            self.m_rate_ = self.m_area_.scaleRate or 1
        else
            line = self.viewRect_.width*0.5
        end
        min,max = line-_w*0.5,line+_w*0.5
        for i=1,#self.items_ do
            item = self.items_[i]
            local _x,_y = item:getPosition()

            bound = {x=_x-self.viewRect_.x,y=_y,width=_w,height=_h}
            local curX = bound.x+bound.width*0.5+scrollX
            if curX>min and curX<=line then
                self.items_[i]:getContent():setScale(curX/min*self.m_rate_)
                item._isScaled = true
                item:setLocalZOrder(1)
            elseif curX>line and curX<max then
                self.items_[i]:getContent():setScale((line-(curX-line))/min*self.m_rate_)
                item._isScaled = true
                item:setLocalZOrder(1)
            else
                self.items_[i]:getContent():setScale(1)
                item._isScaled = false
                item:setLocalZOrder(0)
            end
        end
    end
end

function CustomListView:scrollAuto()
    local status = self:twiningScroll()
    if status == "normal" then
        self:elasticScroll(true)
    elseif status == "sideShow" then
        self:elasticScroll(false)
    end
end

function CustomListView:twiningScroll()
    if self:isSideShow() then
        -- printInfo("UIScrollView - side is show, so elastic scroll")
        return "sideShow"
    end
    if math.abs(self.speed.x) < 10 and math.abs(self.speed.y) < 10 then
        -- printInfo("#DEBUG, UIScrollView - isn't twinking scroll:"
        --     .. self.speed.x .. " " .. self.speed.y)
        return "normal"
    end

    local disX, disY = self:moveXY(0, 0, self.speed.x*6, self.speed.y*6)

    transition.moveBy(self.scrollNode,
                      {x = disX, y = disY, time = 0.3,
                       easing = "sineOut",
                       onComplete = function()
                           self:elasticScroll(true)
    end})
end

function CustomListView:elasticScroll(fix)
    local cascadeBound = self:getScrollNodeRect()
    local disX, disY = 0, 0
    local viewRect = self:getViewRectInWorldSpace()

    -- dump(cascadeBound, "UIScrollView - cascBoundingBox:")
    -- dump(viewRect, "UIScrollView - viewRect:")

    if cascadeBound.width < viewRect.width then
        disX = viewRect.x - cascadeBound.x
    else
        if cascadeBound.x > viewRect.x then
            disX = viewRect.x - cascadeBound.x
        elseif cascadeBound.x + cascadeBound.width < viewRect.x + viewRect.width then
            disX = viewRect.x + viewRect.width - cascadeBound.x - cascadeBound.width
        end
    end

    if cascadeBound.height < viewRect.height then
        disY = viewRect.y + viewRect.height - cascadeBound.y - cascadeBound.height
    else
        if cascadeBound.y > viewRect.y then
            disY = viewRect.y - cascadeBound.y
        elseif cascadeBound.y + cascadeBound.height < viewRect.y + viewRect.height then
            disY = viewRect.y + viewRect.height - cascadeBound.y - cascadeBound.height
        end
    end
    if 0 == disX and 0 == disY then
        if fix then
            self:autoFixScroll()
        end
        return
    end
    self:scrollChange(self.scrollNode:getPositionX()+disX,self.scrollNode:getPositionY()+disY)
    transition.moveBy(self.scrollNode,
                      {x = disX, y = disY, time = 0.3,
                       easing = "backout",
                       onComplete = function()
                           self:callListener_{name = "scrollEnd"}
--                            self:callListener_{name = "scrollStop"}
    end})
end

function CustomListView:getScaledItem_()
    for i=1,#self.items_ do
        if self.items_[i]._isScaled then
            return self.items_[i],i
        end
    end
    return nil
end

return CustomListView

时间: 2024-08-29 10:21:49

quick3.3 UIListview扩展应用的相关文章

基于android-uitableview扩展-uilistview项目

这个项目是正如标题说的那样,是基于uitableview项目为基础进行二次封装的,目的是实现更多的展现形式,项目地址:点击打开 不过,这个使用起来你还必须得会用uitableview扩展(项目地址:点击打开),如果这个你会了那么基本上该项目就是在标签内加入一些项目定义的属性,比如: <com.shelwee.uilistview.ui.UiListView android:id="@+id/uilist3" android:layout_width="match_par

用Quick3.3简单开发微信打飞机 (三)----------------------------- 添加爆炸动画和子弹与敌机的碰撞

用Quick3.3简单开发微信打飞机03 添加爆炸动画和子弹与敌机的碰撞 这个就作为最后一篇吧,当然,可以扩展的方面还有很多,比如分数的记录,结算界面还有一些小道具等,就不添加了.这只是当作一个简单的入门,而在这个入门中确实学到了不少东西.而那些没添加的东西呢,其实,就没那么重要了.没有太难的知识点.所以,就没必要纠结太长时间了. 碰撞检测: 碰撞检测重新写了一个计时器,这个计时器是每帧调用的,也就是每秒调用60次.但是,没有用updata. 检测碰撞的函数如下: [plain] view pl

quick cocos UIListView之isItemInViewRect方法修正

功能描述:一个滚动列表,当列表可视区域上部有内容时则上部出现向上箭头提示,当列表可视区域下部有内容则下部出现向下箭头提示. 功能实现:应用cocos studio1.6制作界面,上面放置一个背景,一个滚动列表,然后程序加载解析这个界面的json文件,应用quick3.3final下的UIListView的方法isItemInViewRect进行检测第一条与最后一条是否在可视区域内. 问题:当界面加载进来,坐标设置0,0时,isItemInViewRect方法判断都没问题,但当把界面调整位置时,i

iOS8扩展插件开发配置

一.iOS8扩展插件概述 WWDC14除了发布了OS X v10.10和switf外,iOS8.0也开始变得更加开放了.说到开放,当然要数应用扩展(App Extension)了.顾名思义,应用扩展允许开发者扩展应用的自定义功能和内容,能够让用户在使用其他应用程序时使用该项功能,从而实现各个应用程序间的功能和资源共享.可以将扩展理解为一个轻量级(nimble and lightweight)的分身. 以下为常见的三类插件: Target Type Extension point identifi

扩展欧几里得算法的模板实现

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组ax+by=gcd(a,b),求他的一组整数解 先给出实现代码 void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0;//gcd(a,0)显然等于1*a-0*0=a return a; } int ans=exgcd(b,a%b,x,y); int tem=x; x=y; y-=tem-(a/b)*y; return ans;} 但实

c# 扩展方法奇思妙用基础篇五:Dictionary&lt;TKey, TValue&gt; 扩展

Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多时候,我们是不敢轻易添加的,因为 Dictionary<TKey, TValue>不允许重复,尝试添加重复的键时 Add 方法引发 ArgumentException. 大多时候,我们都会写成以下的样子: var dict = new Dictionary<int, string>()

C#3.0 扩展方法

扩展方法 在很多时候我们需要编写各种各样的帮助类,因为官方提供的再全面,也会有未包含到的地方,这时一个静态的帮助类就可以帮我们解决问题 举一个不是很恰当的例子,假如要对一个字符串进行验证其内容不为null并且等于admin但是很多地方都要调用,按照封装思想要封装成一个方法,看起来可能是下面这样子的 这并没有任何问题,代码也是比较简单,但是很难会有一种亲近感,因为StringiHelper.ValidArg这样的调用存在.比如这个验证应该是官方应该考虑到的,但是他们忽略了,编写这样一个扩展后会有很

php安装swoole扩展

编译安装 Swoole扩展是按照php标准扩展构建的.使用phpize来生成php编译配置,./configure来做编译配置检测,make进行编译,make install进行安装. 请下载releases版本的swoole,直接从github主干上拉取最新代码可能会编译不过 如果当前用户不是root,可能没有php目录的写权限,安装时需要sudo或者su 如果是在git分支上直接git pull更新代码,重新编译前务必要执行make clean 安装准备 安装swoole前必须保证系统已经安

Linux下利用phpize安装memcashe的php源码扩展包

phpize是php的一种构建工具,为PHP扩展准备构建环境,通过phpize可以编译php的扩展源码文件为php扩展模块. 一.安装 phpize工具可以通过安装php-dev包自动集成安装.安装完成后php的bin目录下会有phpize这个命令. 二.使用 举例:在原来编译好的php中加入memcache扩展模块,使用phpize构建的方式如下. tar zxvf memcache-2.2.5.tgz cd memcache-2.2.5/ /usr/local/php/bin/phpize