quick3.3 UIListview扩展应用

来源:互联网 发布:近邻算法 编辑:程序博客网 时间:2024/05/18 14:23
--[[    自定义滑动列表控件    1.支持UIListView所有功能    2.额外增加让条目滑动后始终显示全部功能    3.额外增加当条目滑过指定区域时发生放大缩小变化,调用enableAreaChange()方法即可开启 author:chjh0540237]]local c = cclocal UIScrollView = cc.ui.UIScrollViewlocal 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 selfendfunction CustomListView:autoFixScroll()    if UIScrollView.DIRECTION_VERTICAL == self.direction then        self:autoFixY()    else        self:autoFixX()    endend--横向滑动时,使条目显示全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    endend  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-- overridefunction 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    endend --滚动变化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    endend function CustomListView:scrollAuto()    local status = self:twiningScroll()    if status == "normal" then        self:elasticScroll(true)    elseif status == "sideShow" then        self:elasticScroll(false)    endend 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})endfunction CustomListView:getScaledItem_()    for i=1,#self.items_ do        if self.items_[i]._isScaled then            return self.items_[i],i        end    end    return nilendreturn CustomListView

0 0
原创粉丝点击