cocos TableView滑动块

 #ifndef _SCROLL__BAR__H_
#define _SCROLL__BAR__H_

#include "cocos2d.h"
#include "ui/UIScale9Sprite.h"

namespace cocos2d {
    namespace extension {

    enum SclBarDirection
    {
   DIR_NODIR = 0,
   DIR_VERTICAL,
   DIR_HORIZENTAL,
    };
    class TableView;
    class ScrollBar : public cocos2d::Layer
    {
    public:
   ScrollBar();
   ~ScrollBar();
   /**
   * 因为九宫图不能缩小到比实际图片要小,所以传入的图片的实际大小要足够小,否则slider的大小会有问题
   */
        static ScrollBar * create(ui::Scale9Sprite * bar_bg, ui::Scale9Sprite * bar_slider, TableView * tableView, SclBarDirection dir);
   static ScrollBar * createWithFile(const char * bar_bgFile,const char * bar_sliderFile,TableView * tableView,SclBarDirection dir);
        bool myInit(ui::Scale9Sprite * bar_bg, ui::Scale9Sprite * bar_slider, TableView * tableView, SclBarDirection dir);

        ui::Scale9Sprite * getSliderBg();
        ui::Scale9Sprite * getSlider();
    protected:
   virtual bool onTouchBegan(Touch* touch, Event* pEvent);
   virtual void onTouchMoved(Touch *pTouch, Event *pEvent);
   virtual void onTouchEnded(Touch *pTouch, Event *pEvent);

   virtual void update(float dt) override;
   /**
   * 动态改变slider的大小
   */
   void updateSlider();

    private:
   TableView * m_pTarget;
        ui::Scale9Sprite * m_pBg;
        ui::Scale9Sprite * m_pSlider;
   SclBarDirection m_direction;
   Size m_preContentSize;
   Size m_viewSize;
   bool m_sliderTouched;
   Vec2 m_firstTouch;
   Vec2 m_sliderCurPos;
   Vec2 m_targetCurPos;
    };

    }
}

#endif



#include "ScrollBar.h"
#include "cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

ScrollBar::ScrollBar()
: m_pTarget(nullptr)
, m_pBg(nullptr)
, m_pSlider(nullptr)
, m_direction(DIR_NODIR)
, m_preContentSize(Size::ZERO)
, m_viewSize(Size::ZERO)
, m_sliderTouched(false)
, m_firstTouch(Vec2::ZERO)
, m_sliderCurPos(Vec2::ZERO)
, m_targetCurPos(Vec2::ZERO)
{

}

ScrollBar::~ScrollBar()
{

}

ScrollBar * ScrollBar::createWithFile(const char * bar_bgFile, const char * bar_sliderFile, TableView * tableView, SclBarDirection dir)
{
Scale9Sprite * pBg = Scale9Sprite::create(bar_bgFile);
Scale9Sprite * pSlider = Scale9Sprite::create(bar_sliderFile);

return create(pBg,pSlider,tableView,dir);
}

ScrollBar * ScrollBar::create(Scale9Sprite * bar_bg,Scale9Sprite * bar_slider,TableView * tableView,SclBarDirection dir)
{
ScrollBar * pRet = new ScrollBar();
if (pRet && pRet->myInit(bar_bg,bar_slider,tableView,dir))
{
pRet->autorelease();
}
else
{
CC_SAFE_DELETE(pRet);
}

return pRet;
}

/**
* 初始化各个数据
*/
bool ScrollBar::myInit(Scale9Sprite * bar_bg,Scale9Sprite * bar_slider,TableView * tableView,SclBarDirection dir)
{
if (!Layer::init())
{
return false;
}
m_pBg = bar_bg;
m_pSlider = bar_slider;
m_pTarget = tableView;
m_direction = dir;
m_preContentSize = m_pTarget->getContainer()->getContentSize();
m_viewSize = m_pTarget->getViewSize();
if (m_direction == DIR_VERTICAL)
{
m_pBg->setContentSize(Size(m_pBg->getContentSize().width,m_viewSize.height));
m_pBg->setPosition(Vec2(m_pBg->getContentSize().width / 2,0));
m_pSlider->setPositionX(m_pBg->getContentSize().width / 2);
else if (m_direction == DIR_HORIZENTAL)
{
m_pBg->setContentSize(Size(m_viewSize.width,m_pBg->getContentSize().height));
m_pBg->setPosition(Vec2(0,-m_pBg->getContentSize().height / 2));
m_pSlider->setPositionY(-m_pBg->getContentSize().height / 2);
}
this->addChild(m_pBg,0);

this->updateSlider();

this->addChild(m_pSlider,1);

this->scheduleUpdate();

auto listenerT = EventListenerTouchOneByOne::create();
listenerT->onTouchBegan = CC_CALLBACK_2(ScrollBar::onTouchBegan,this);
listenerT->onTouchMoved = CC_CALLBACK_2(ScrollBar::onTouchMoved,this);
listenerT->onTouchEnded = CC_CALLBACK_2(ScrollBar::onTouchEnded,this);
listenerT->setSwallowTouches(false);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenerT,this);

return true;
}

void ScrollBar::updateSlider()
{
float ratio = 0.0;
if (m_direction == DIR_VERTICAL)
{
ratio = m_viewSize.height / m_preContentSize.height;
m_pSlider->setContentSize(Size(m_pSlider->getContentSize().width,m_viewSize.height * ratio));
else if (m_direction == DIR_HORIZENTAL)
{
ratio = m_viewSize.width / m_preContentSize.width;
m_pSlider->setContentSize(Size(m_viewSize.width * ratio,m_pSlider->getContentSize().height));
}
//如果要显示的内容的尺寸比视图大小小,则隐藏滑块slider
this->setVisible( !(ratio >= 1) );
}

void ScrollBar::update(float dt)
{
//判断当前内容是否有增减,因为内容的增减会影响ContenSize,从而修改slider的大小
auto curContentSize = m_pTarget->getContainer()->getContentSize();
if ( !(fabsf(curContentSize.height - m_preContentSize.height) <= 0.00001)  || 
!(fabsf(curContentSize.width - m_preContentSize.width) <= 0.00001) )
{
m_preContentSize = curContentSize;
this->updateSlider();
}

//设置slider的位置
if (m_direction == DIR_VERTICAL)
{
//调整滑块的位置
auto curOffset = m_pTarget->getContentOffset() + (m_preContentSize - m_viewSize) / 2;
auto sliderOffset = curOffset.y / (m_viewSize.height - curContentSize.height) * 
(m_viewSize.height - m_pSlider->getContentSize().height);
//判断滑块是否滑出界限
if (fabsf(sliderOffset) > (m_viewSize.height - m_pSlider->getContentSize().height) / 2)
{
return ;
}
m_pSlider->setPositionY(sliderOffset);
}
else if (m_direction == DIR_HORIZENTAL)
{
auto curOffset = m_pTarget->getContentOffset() - (m_preContentSize - m_viewSize) / 2;
auto sliderOffset = -curOffset.x / (m_viewSize.width - curContentSize.width) * 
(m_viewSize.width - m_pSlider->getContentSize().width);
if (fabsf(sliderOffset) > (m_viewSize.width - m_pSlider->getContentSize().width) / 2)
{
return ;
}
m_pSlider->setPositionX(sliderOffset);
}
}

bool ScrollBar::onTouchBegan(Touch* touch, Event* pEvent)
{
m_sliderCurPos = m_pSlider->getPosition();
m_targetCurPos = m_pTarget->getContentOffset();
auto touchPoint = touch->getLocation();
m_firstTouch = touchPoint;
//将触摸点转为在当前子层下的坐标
touchPoint = this->convertToNodeSpace(touchPoint);
//只响应点击了滑块背景的触摸
if (!m_pBg->getBoundingBox().containsPoint(touchPoint))
{
return false;
}
//如果先点击了滑块,则设置标志
if (m_pSlider->getBoundingBox().containsPoint(touchPoint))
{
m_sliderTouched = true;
}
else//如果没有点击滑块,则点击的是滑块背景图
{
if (m_direction == DIR_VERTICAL)
{
//通过调整m_pTarget的偏移,从而调整了滑块slider的位置,因为update函数会一直监听m_pTarget的偏移
auto offset = touchPoint.y - m_sliderCurPos.y;
if (touchPoint.y <= 0)
{
offset += m_pSlider->getContentSize().height / 2;
else
{
offset -= m_pSlider->getContentSize().height / 2;
}
auto newOff = m_targetCurPos.y + offset / (m_pSlider->getContentSize().height - m_viewSize.height) 
* (m_preContentSize.height - m_viewSize.height);
m_pTarget->setContentOffset(Vec2(0,newOff));
}
else if (m_direction == DIR_HORIZENTAL)
{
auto offset = touchPoint.x - m_sliderCurPos.x;
if (touchPoint.x <= 0)
{
offset += m_pSlider->getContentSize().width / 2;
else
{
offset -= m_pSlider->getContentSize().width / 2;
}
auto newOff = m_targetCurPos.x + offset / (m_viewSize.width - m_pSlider->getContentSize().width) 
* (m_preContentSize.width - m_viewSize.width);
m_pTarget->setContentOffset(Vec2(newOff,0));
}
}
return true;
}
void ScrollBar::onTouchMoved(Touch *pTouch, Event *pEvent)
{
//只响应点击了滑块的移动
if (m_sliderTouched)
{
auto offPos = pTouch->getLocation() - m_firstTouch;
if (m_direction == DIR_VERTICAL)
{
//通过调整m_pTarget的偏移,从而调整了滑块slider的位置,因为update函数会一直监听m_pTarget的偏移
auto newOff = m_sliderCurPos.y + offPos.y;
//判断滑块是否滑出界限
if (fabsf(newOff) > (m_viewSize.height - m_pSlider->getContentSize().height) / 2)
{
(newOff < 0 ? (newOff = (m_pSlider->getContentSize().height - m_viewSize.height) / 2) : 
(newOff = (m_viewSize.height - m_pSlider->getContentSize().height) / 2));
}
newOff -= m_sliderCurPos.y;
m_pTarget->setContentOffset(Vec2(0,
m_targetCurPos.y + newOff / (m_pSlider->getContentSize().height - m_viewSize.height) 
* (m_preContentSize.height - m_viewSize.height)));
}
else if (m_direction == DIR_HORIZENTAL)
{
auto newOff = m_sliderCurPos.x + offPos.x;
if (fabsf(newOff) > (m_viewSize.width - m_pSlider->getContentSize().width) / 2)
{
(newOff < 0 ? (newOff = (m_pSlider->getContentSize().width - m_viewSize.width) / 2) : 
(newOff = (m_viewSize.width - m_pSlider->getContentSize().width) / 2));
}
newOff -= m_sliderCurPos.x;
m_pTarget->setContentOffset(Vec2(m_targetCurPos.x + newOff / (m_viewSize.width - m_pSlider->getContentSize().width) 
* (m_preContentSize.width - m_viewSize.width),0));
}
}
}

void ScrollBar::onTouchEnded(Touch *pTouch, Event *pEvent)
{
m_sliderTouched = false;
}

ui::Scale9Sprite * cocos2d::extension::ScrollBar::getSliderBg()
{
    return m_pBg;
}

ui::Scale9Sprite * cocos2d::extension::ScrollBar::getSlider()
{
    return m_pSlider;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值