您的位置:首页 > 其它

实现一个简单的滚动条

2015-10-23 15:58 232 查看
bones 没有自带一个滚动条,主要是考虑到滚动条的样式非常多变,可以看下qq系列的滚动条

QQ新闻里的滚动条,如下



异于通常的windows风格滚动条

QQ电脑管家



典型的移动平台风格

再看下QQ聊天框的



类似于windows风格但垂直滚动条两边多了一个直接到顶部和底部的响应区域

由于滚动条如此多变想提供一个内置的并且美工设计都能认可的滚动条非常困难,相比与内置,能让用户容易写出一个自己需要的滚动条才应该是条正确的道路。

bones当前的版本已经可以通过scroller的接口让用户写出一个滚动条来,在这里就演示下如何实现一个滚动条 并用它来配合scroller滚动标签。

由于手头没有滚动条图片资源 我用了2个色块来替代,你也可以通过bones.shader创建渐变色来让滚动条更好看一点,效果图如下:





滚动条的编写同样使用了扩展标签scrollbar,具体如何使用扩展标签前文已经讲了,这里不再讲解。

先分析下滚动条的结构:

1:滚动条最少应该有一个滑动槽和一个滑块

2:鼠标在滑块上按下并移动时滑块要跟着鼠标滑动

在这里我以能绘制出矩形色块的shape标签来代表滑动槽和滑块,其中滑块是滑动槽的子标签如下:

<!--底色-->
<shape>
<!--滑块区域-->
<shape>
<event name ="onMouseDown" phase ="target" module ="scrollbar" func ="onSliderMouseDown"></event>
<event name ="onMouseUp" phase ="target" module ="scrollbar" func ="onSliderMouseUp"></event>
<event name ="onMouseMove" phase ="target" module ="scrollbar" func ="onSliderMouseMove"></event>
<event name ="onMouseLeave" phase ="target" module ="scrollbar" func ="onSliderMouseLeave"></event>
</shape>
<notify name ="onCreate" module ="scrollbar" func ="onCreate"></notify>
<notify name ="onSizeChanged" module ="scrollbar" func ="onSizeChanged"></notify>
</shape>


通常滚动条有水平和垂直滚动2种 因此提供了setStyle来设置具体类型

--设置水平还是垂直
local function setStyle(self, horiz)
self.horiz_ = horiz
end


知道滚动条类型后,还需要根据滚动范围来计算滑块的大小,看下垂直滚动条如何计算

local function updateSliderV(self)
-- view + min + max = bar.height
local w, h = self:getSize()
local view = self.view_
local min = self.min_
local max = self.max_
local cur = self.cur_
local total = view + min + max
local scale_slider = view / total
local slider_h = view / total * h
local slider_t = (cur - min) / (max - min) * (h - slider_h)
self.slider_:setSize(w, slider_h)
self.slider_:setLoc(0, slider_t)
end


接下来 需要在点击到滑块时, 滑块跟鼠标移动并且通知scroller当前的滚动值

--self是滑块
function mod.onSliderMouseMove(self, e)
if self.click_ then
local x, y = e:getRootLoc()
local ydelta = y - self.last_y_
local xdelta = x - self.last_x_
local parent = self.parent_
local w, h = self:getSize()
local cur = 0
local horiz = parent.horiz_
if horiz then
cur = xdelta / w * (parent.max_ - parent.min_) + parent.cur_
else
cur = ydelta / h * (parent.max_ - parent.min_) + parent.cur_
end
parent.slave_:setScrollPos(cur, horiz)
end

self.last_x_, self.last_y_ = e:getRootLoc()
end


在这里self 指的代表滑块的标签 父则是代表滑动槽,具体的可以看onCreate函数,slave则是scroller标签 这个由外界初始化时调用setSlave时设置的

--关联scroller 和滚动条
local vbar = self:getChildAt(2)
local hbar = self:getChildAt(3)
self.scroller_.vbar_ = vbar
self.scroller_.hbar_ = hbar
vbar:setSlave(self.scroller_)
vbar:setStyle(false)
hbar:setSlave(self.scroller_)
hbar:setStyle(true)

--设置scroller大小 即视口
self.scroller_:setSize(w / 2, h / 2)
self.scroller_:setLoc(w + 10, 10)
--设置滚动条的位置
local bar_const = 12
vbar:setLoc(w + 10 + w / 2, 10)
vbar:setSize(bar_const, h / 2)
--滚动条的位置可以是任意的 垂直滚动条是紧贴 水平滚动条可以离远点
local delta = 20
hbar:setLoc(w + 10, 10 + h /2 + delta )
hbar:setSize(w / 2, bar_const)

--需要滚动显示image标签大小为图片大小
local image = self.scroller_:getChildAt(0)
image:setSize(w, h)
image:setContent(pm_key)
--scroller垂直方向的滚动范围是0-h/2 设置成image的高 scroller会自动计算滚动范围
self.scroller_:setScrollInfo(h, false)
self.scroller_:setScrollInfo(w, true)
--响应滚动要用到image标签 缓存一下
self.scroller_.image_ = self.scroller_:getChildAt(0)


本篇完整代码下载:

/article/8465616.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: