公告類型:可變的滾動視圖,文字長度根據制定長度進行換行

最近由於功能的需求,寫了一個容器可變的滾動視圖,文字長度也是從網上找的,

這個Demo的效果是這樣的:

在一個指定大小的背景圖上邊,點擊按鈕,出現一條信息,(每次的信息長度不固定),這條信息出現在背景圖的ScrollView上,當信息沒有佔滿ScrollView的大小時,它是不可以滾動的,然後再點擊按鈕,再往這條信息的下方出現一條信息,最後當信息佔滿ScrollView時,會自動向上滾動,ScrollView的大小也會自動根據信息的長度而改變。

下面貼一下源碼:

struct tagNoticeInfo

{

    CCLabelTTF* labelNotice;

    float fWidth;

};

.h文件

void loadScrollView();

    void showNotice(std::string noticeStr);

    CCLabelTTF* HorizontalSpacingANDVerticalSpacing(std::string _string, const char *fontName, float fontSize, float horizontalSpacing, float verticalSpacing, float lineWidth);


//CCScrollView

    CCLayer* m_layerScrollContain;

    CCScrollView* m_scrollViewNotice;

    std::vector<tagNoticeInfo> m_vctPriseInfo;


.cpp文件


void CBonusLayer::loadScrollView()

{

    m_scrollViewNotice = CCScrollView::create();

    m_layerScrollContain = CCLayer::create();//創建一個層,作爲滾動的內容

    m_layerScrollContain->setPosition(ccp(0,0));

    m_layerScrollContain->setAnchorPoint(ccp(0, 0));

    m_layerScrollContain->setContentSize(CCSizeMake(360, 500));

    m_scrollViewNotice->setPosition(ccp(10, 25));

    m_scrollViewNotice->setAnchorPoint(ccp(0, 0));

    m_scrollViewNotice->setContentOffset(ccp(0,500-250));

    m_scrollViewNotice->setViewSize(CCSizeMake(360, 500));//設置view的大小

    m_scrollViewNotice->setContentSize(CCSizeMake(360, 500));

    m_scrollViewNotice->setContainer(m_layerScrollContain);

    m_scrollViewNotice->setBounceable(false);

    m_scrollViewNotice->setDelegate(this);

    m_scrollViewNotice->setTouchPriority(-200);

    m_scrollViewNotice->setDirection(kCCScrollViewDirectionVertical);

    m_spPriseList -> addChild(m_scrollViewNotice);

}


void CBonusLayer::showNotice(std::string noticeStr)

{

    //計算公告的位置

    int count = m_vctPriseInfo.size();

    float height = 0;

    for(unsigned int i = 0; i < count; i++)

    {

        tagNoticeInfo NoticeInfo = (tagNoticeInfo)m_vctPriseInfo[i];

        float width = NoticeInfo.fWidth;

        height = height + width/340.0*40+40;//每一個公告的高度

    }

    tagNoticeInfo NoticeInfo;

    NoticeInfo.labelNotice= CCLabelTTF::create(noticeStr.c_str(), "Arial", 32);

    NoticeInfo.fWidth = NoticeInfo.labelNotice->getContentSize().width;

    NoticeInfo.labelNotice = HorizontalSpacingANDVerticalSpacing(NoticeInfo.labelNotice->getString(), "Arial", 32, 1.5, 1, 340);

    

    float fY = height + NoticeInfo.fWidth/340.0*40+80;

    printf("fY is %f\n", fY);

    //計算面板是否可以滾動,而且滾動的範圍也要加以限制

    if(fY < 500)

    {

        m_scrollViewNotice->setTouchEnabled(false);

        NoticeInfo.labelNotice -> setPosition(ccp(10,500-40 - height));

    }

    else

    {

        m_scrollViewNotice->setTouchEnabled(true);

        m_layerScrollContain->setContentSize(CCSizeMake(360, fY));

        m_layerScrollContain->setPosition(ccp(0,0));

        m_scrollViewNotice->setContentSize(CCSizeMake(360, fY));

        NoticeInfo.labelNotice -> setPosition(ccp(10,(NoticeInfo.fWidth/340.0*40+40)));

        float width = 0;

        for(unsigned int i = 0; i < m_vctPriseInfo.size(); i++)

        {

            tagNoticeInfo NoticeInfo = (tagNoticeInfo)m_vctPriseInfo[i];

            width = width + NoticeInfo.fWidth/340.0*40+40;

            NoticeInfo.labelNotice -> setPosition(ccp(10,fY-width+NoticeInfo.fWidth/340.0*40));

        }

    }

    NoticeInfo.labelNotice -> setAnchorPoint(ccp(0,0.5f));

    

    m_layerScrollContain -> addChild(NoticeInfo.labelNotice);

    m_vctPriseInfo.push_back(NoticeInfo);

}


CCLabelTTF* CBonusLayer::HorizontalSpacingANDVerticalSpacing(std::string _string, const char *fontName, float fontSize, float horizontalSpacing, float verticalSpacing, float lineWidth)

{

    CCArray* labelTTF_arr = CCArray::create();

    int index = 0;

    int index_max = strlen(_string.c_str());

    bool is_end = true;

    while (is_end) {

        if (_string[index] >= 0 && _string[index] <= 127) {

            std::string englishStr = _string.substr(index,1).c_str();

            const char* englishChar = englishStr.c_str();

            labelTTF_arr->addObject(CCLabelTTF::create(englishChar, fontName, fontSize));

            index+= 1;

        }

        else{

            std::string chineseStr = _string.substr(index,3).c_str();

            const char* chineseChar =  chineseStr.c_str();

            labelTTF_arr->addObject(CCLabelTTF::create(chineseChar, fontName, fontSize));

            index+= 3;

        }

        if (index>=index_max) {

            is_end=false;

        }

    }

    //以上步驟是根據ASCII碼找出中英文字符,並創建成一個CCLabelTTF對象存入labelTTF_arr數組中。

    //下面創建的原理是在CCLabelTTF對象上添加子對象CCLabelTTF,以此組合成一句話,以左上角第一個字爲錨點。。

    CCLabelTTF* returnTTF = (CCLabelTTF*)labelTTF_arr->objectAtIndex(0);

    returnTTF->setColor(ccc3(116, 0, 0));

    float nowWidth = returnTTF->getContentSize().width;

    CCLabelTTF* dangqiangTTF = returnTTF;

    CCLabelTTF* lineBeginTTF = returnTTF;

    

    int arr_count = labelTTF_arr->count();

    for (int i=1; i < arr_count; i++) {

        CCLabelTTF* beforeTTF = (CCLabelTTF*)labelTTF_arr->objectAtIndex(i);

        beforeTTF->setColor(ccc3(116, 0, 0));

        beforeTTF->setAnchorPoint(ccp(0, 0.5));

        nowWidth+=beforeTTF->getContentSize().width;

        if (nowWidth >= lineWidth) {

            nowWidth = returnTTF->getContentSize().width;

            dangqiangTTF = lineBeginTTF;

            beforeTTF->setPosition(ccp(0, -dangqiangTTF->getContentSize().height*0.5-verticalSpacing));

            lineBeginTTF = beforeTTF;

        }else{

            beforeTTF->setPosition(ccp(dangqiangTTF->getContentSize().width+horizontalSpacing, dangqiangTTF->getContentSize().height*0.5));

        }

        dangqiangTTF->addChild(beforeTTF);

        dangqiangTTF = beforeTTF;

    }

    

    return returnTTF;

}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章