因为最近一直很忙,国庆都在加班。没时间整理了,先放我项目的代码吧,当然不能把整个项目代码都放上来,东西还是要保护版权的,贴最主要的部分,不能直接使用哦。不过可以参考的,MyTableView不影响滑动部分,主要是我自己用来保持窗口的左右滑动不被元素点击当掉的,代码来啦:
#include "ListViewLayer.h"
#include "SimpleAudioEngine.h"
#include "AppMacros.h"
#include "DownloadJson.h"
#include "Downloader.h"
#include "SendScene.h"
#include "VisibleRect.h"
#include "Element.h"
#include "SharedControlLayer.h"
#include "MyTableView.h"
USING_NS_CC;
USING_NS_CC_EXT;
using namespace CocosDenshion;
bool ListViewLayer::init()
{
bool bRet =
false;
do{
CC_BREAK_IF( !CCLayer::init() );
m_firstLoad =
true;
isSearching =
false;
bRet =
true;
firstLoad =
true;
}
while(0);
return bRet;
}
void ListViewLayer::initWithJsonLink(
const std::
string &jsonLink,
const std::
string & type)
{
m_jsonlink = jsonLink + type;
m_type = type;
this->getNewPageOfIndex(0);
auto writablepath = CCFileUtils::sharedFileUtils()->getWritablePath();
for(auto itr = m_message.elements.begin(); itr != m_message.elements.end(); ++itr){
auto fname = writablepath + itr->sound;
// CCLog("sound name: %s", itr->sound.c_str());
}
createTableView();
}
void ListViewLayer::initWithElements(
const std::vector<Element> &dbElements){
m_message.elements = dbElements;
this->m_tableNum = m_message.elements.size();
createTableView();
}
void ListViewLayer::initWithSearchKeywords(
const std::
string &jsonLink,
const std::
string &keyWords){
m_jsonlink = jsonLink + "search=" + keyWords;
isSearching =
true;
this->getNewPageOfIndex(0);
auto writablepath = CCFileUtils::sharedFileUtils()->getWritablePath();
for(auto itr = m_message.elements.begin(); itr != m_message.elements.end(); ++itr){
auto fname = writablepath + itr->sound;
CCLog("sound name: %s", itr->sound.c_str());
}
createTableView();
}
void ListViewLayer::initWithSearchType(
const std::
string &jsonLink,
const std::
string &type){
m_jsonlink = jsonLink + "lid=" + type;
isSearching =
true;
auto ret =
this->getNewPageOfIndex(0);
auto writablepath = CCFileUtils::sharedFileUtils()->getWritablePath();
createTableView();
}
void ListViewLayer::createTableView(){
static auto height = winSize.height;
m_tableView = (MyTableView*)getChildByTag(200);
if(m_tableView == NULL){
m_tableView = MyTableView::create(
this, CCSizeMake(570, (height == 1136) ? 1020 : 1020 - (1136 - 960)) );
m_tableView->setClippingToBounds(
true);
m_tableView->setDirection(kCCScrollViewDirectionVertical);
m_tableView->setPosition(CCPointZero);
m_tableView->setDelegate(
this);
m_tableView->setVerticalFillOrder(kCCTableViewFillTopDown);
m_tableView->reloadData();
m_tableView->setTouchPriority(TABLE_TOUCH_PRIORITY);
m_tableView->setTag(200);
//在发送场景中使用这个tag获取table以处理触摸事件
this->addChild(m_tableView);
m_tableView->retain();
m_firstLoad =
false;
}
else{
m_tableView->setTouchEnabled(
true);
m_tableView->reloadData();
m_tableView->updateInset();
}
m_oldContentSize = m_tableView->getContentOffset();
}
void ListViewLayer::hide(){
bool value =
false;
m_tableView->setTouchEnabled(value);
m_tableView->setVisible(value);
}
void ListViewLayer::show(){
bool value =
true;
m_tableView->setTouchEnabled(value);
m_tableView->setVisible(value);
}
int ListViewLayer::getNewPageOfIndex(
int index){
CCLog("getNewPageOfIndex-------------------============");
auto cur_page = (1+index)/20;
auto jsonlink = m_jsonlink;
jsonlink = jsonlink + "&page=" + CCString::createWithFormat("%d", cur_page+1)->getCString();
std::
string fname;
if(isSearching){
fname = std::
string("search, page=") + CCString::createWithFormat("%d", cur_page+1)->getCString() + ".json";
}
else{
fname = m_type + "_page=" + CCString::createWithFormat("%d", cur_page+1)->getCString() + ".json";
}
if(firstLoad){
//避免第一次加载没有网络使得屏幕黑屏
firstLoad =
false;
removeFile(fname);
//临时加上的,正式版中要删除
DownloadJson::download(jsonlink, fname.c_str());
}
else{
removeFile(fname);
DownloadJson::download(jsonlink, fname.c_str());
}
auto tmp_message = readJson(fname.c_str());
if(tmp_message.code != 1){
return tmp_message.code;
}
m_message.elements.insert(m_message.elements.end(), tmp_message.elements.begin(), tmp_message.elements.end());
this->m_tableNum = m_message.elements.size();
return 1;
//means OK
}
void ListViewLayer::stopAllMusic(){
const std::
string notPlayImg = "发送=播放.png";
SimpleAudioEngine::sharedEngine()->stopAllEffects();
if(getOldCell() != NULL){
auto item = (CCSprite*)getOldCell()->getChildByTag(CELL_CONTENT)->getChildByTag(PLAY_ITEM);
CCLog("%d", getOldCell()->getIdx());
item->initWithFile(notPlayImg.c_str());
}
}
void ListViewLayer::setOldCell(CCTableViewCell *cell){
m_oldCell = cell;
m_oldCell->retain();
}
CCTableViewCell *ListViewLayer::getOldCell(){
return m_oldCell;
}
void ListViewLayer::tableCellTouched(CCTableView* table, CCTableViewCell* cell)
{
//为了避免在点击一个cell时,多个重叠的list被点击到
if(SharedControlLayer::instance()->is_doingSomething)
if(!SharedControlLayer::instance()->is_searching && !Collection::instance()->isExplorering())
return;
auto idx = cell->getIdx();
CCLog("ListViewLayer(0x%p), type: cell touched at index: %i",
this, idx);
if(cell->getIdx() > m_tableNum){
return ;
}
if(m_tableView->isClickInPlayArea){
playMusic(m_message.elements[idx], cell);
return;
}
if(m_tableView->isClickInCollectArea){
auto star = cell->getChildByTag(CELL_CONTENT)->getChildByTag(COLLECT_TAG);
if(star == NULL){
m_message.elements[idx].isCollected =
true;
star = CCSprite::create("发送=收藏=星星.png");
star->setScale(0.5);
star->setAnchorPoint(CCPointZero);
star->setPosition(ccp(160, 25));
star->setTag(COLLECT_TAG);
cell->getChildByTag(CELL_CONTENT)->addChild(star, 3);
Collection::instance()->insertElement(m_message.elements[idx]);
}
else{
m_message.elements[idx].isCollected =
false;
star->setVisible(
false);
cell->getChildByTag(CELL_CONTENT)->removeChild(star);
Collection::instance()->deleteElement(m_message.elements[idx]);
}
return;
}
//goto the send layer
stopAllMusic();
auto sendContent = SendScene::create();
sendContent->setCellContent(cell, m_message.elements[idx]);
addChild(sendContent, 6);
sendContent->setDelegate(
this);
//delegate for delete or insert cell
m_curIndex = idx;
m_tableView->setTouchEnabled(
false);
SharedControlLayer::instance()->getSharedMainLayer()->mySetTouchEnabled(
false);
}
CCSize ListViewLayer::cellSizeForTable(CCTableView *table)
{
return CCSizeMake(400, 135);
}
void ListViewLayer::removeCell(){
m_tableView->removeCellAtIndex(m_curIndex);
}
void ListViewLayer::insertCell(){
m_tableView->insertCellAtIndex(m_curIndex, 1);
}
static CCSprite *createTagSprite(
const Element &element){
std::
string tagPngFile;
CCSprite * retSprite;
auto color = ccMAGENTA;
auto size = 15;
auto tag = element.tag;
if(tag == "2"){
tagPngFile = "主界面-hot.png";
retSprite = CCSprite::create(tagPngFile.c_str());
}
else if(tag == "1"){
tagPngFile = "主界面-vip.png";
retSprite = CCSprite::create(tagPngFile.c_str());
}
else if(tag == "4"){
//3/4是临时使用
retSprite = CCLabelTTF::create("管理员", "Arial", size);
retSprite->setColor(color);
}
else if(tag == "3"){
retSprite = CCLabelTTF::create(tag.c_str(), "Arial", size);
retSprite->setColor(color);
}
else{
retSprite = CCLabelTTF::create(tag.c_str(), "Arial", size);
retSprite->setColor(color);
}
return retSprite;
}
static CCLabelTTF * createLidSprite(
const std::
string & lid){
std::
string languageID_FileName;
//后者创建一个字符串数组然后根据索引来创建
auto nLid = atoi(lid.c_str());
switch(nLid){
case 1: languageID_FileName = "东北";
break;
case 2: languageID_FileName = "京津";
break;
case 3: languageID_FileName = "上海";
break;
case 4: languageID_FileName = "湖南";
break;
case 5: languageID_FileName = "湖北";
break;
case 6: languageID_FileName = "粤语";
break;
case 7: languageID_FileName = "川渝";
break;
case 8: languageID_FileName = "其它";
break;
default: languageID_FileName = "其它";
break;
break;
}
auto lidSprite =CCLabelTTF::create(languageID_FileName.c_str(), "Arial", 18);
return lidSprite;
}
//滚动到index单元
static void scrollToIndex(CCTableView * m_table,
int index){
auto old_height = m_table->getContentOffset().y;
m_table->setContentOffset(ccp(0,
old_height
+ m_table->getDataSource()->tableCellSizeForIndex(m_table, 0).height
* index));
}
static CCLayer * createCell(
const Element & element ){
auto cellContent = CCLayer::create();
cellContent->setAnchorPoint(CCPointZero);
auto verticalClaritySprite = CCSprite::create("主界面-透明横条.png");
verticalClaritySprite->setAnchorPoint(CCPointZero);
verticalClaritySprite->setPosition(ccp(0, 0));
cellContent->addChild(verticalClaritySprite);
auto horizontalClaritySprite = CCSprite::create("主界面-透明竖条.png");
horizontalClaritySprite->setAnchorPoint(CCPointZero);
horizontalClaritySprite->setPosition(ccp(0, 0));
cellContent->addChild(horizontalClaritySprite);
std::
string normalImage = "发送=播放.png";
std::
string selectedImage = "发送=暂停.png";
auto playSprite = CCSprite::create(normalImage.c_str());
playSprite->setTag(PLAY_ITEM);
playSprite->setPosition(ccp(horizontalClaritySprite->getContentSize().width + playSprite->getContentSize().width/2,
verticalClaritySprite->getContentSize().height + playSprite->getContentSize().height/2));
cellContent->addChild(playSprite);
auto horizontalClaritySprite2 = CCSprite::create("主界面-透明竖条.png");
horizontalClaritySprite2->setAnchorPoint(CCPointZero);
horizontalClaritySprite2->setPosition(ccp(horizontalClaritySprite->getContentSize().width
+ playSprite->getContentSize().width,
0));
if(element.isCollected){
auto star = CCSprite::create("发送=收藏=星星.png");
star->setScale(0.5);
star->setAnchorPoint(CCPointZero);
if(Collection::instance()->isExplorering()){
star->setPosition(ccp(155+3, 25));
}
else{
star->setPosition(ccp(155, 25));
}
star->setTag(COLLECT_TAG);
cellContent->addChild(star, 1);
}
cellContent->addChild(horizontalClaritySprite2);
auto pngName = std::
string("主界面-音频信息板.png");
auto writablepath = CCFileUtils::sharedFileUtils()->getWritablePath();
auto audioInforSprite = CCSprite::create(pngName.c_str());
auto width = playSprite->getContentSize().width + horizontalClaritySprite->getContentSize().width
+ horizontalClaritySprite2->getContentSize().width + audioInforSprite->getContentSize().width/2;
auto height = verticalClaritySprite->getContentSize().height + audioInforSprite->getContentSize().height/2;
audioInforSprite->setPosition(ccp(playSprite->getContentSize().width + horizontalClaritySprite->getContentSize().width
+ horizontalClaritySprite2->getContentSize().width + audioInforSprite->getContentSize().width/2,
verticalClaritySprite->getContentSize().height + audioInforSprite->getContentSize().height/2));
cellContent->addChild(audioInforSprite);
//分类标签,热门,VIP等
auto tag = createTagSprite(element);
tag->setPosition(ccp(551, 103.5));
tag->setTag(CELL_TAG);
cellContent->addChild(tag);
//在控制菜单上显示
auto lid = createLidSprite(element.lid);
lid->setPosition(ccp(width - 100, height - 50));
lid->setColor(ccWHITE);
cellContent->setTag(CELL_LID);
cellContent->addChild(lid);
//文本内容
std::
string textStr;
if(element.text.size() > 30){
textStr = element.text.substr(0, 30) + "
";
}
auto text = CCLabelTTF::create(element.text.c_str(), "Arial", 25.0, CCSizeMake(350, 0), kCCTextAlignmentLeft);
text->setColor(ccBLACK);
text->setPosition(ccp(width - 200, height ));
text->setAnchorPoint(CCPointZero);
text->setTag(CELL_TEXT);
text->setVerticalAlignment(kCCVerticalTextAlignmentCenter);
cellContent->addChild(text);
//大小
std::
string sizecontent = element.ssize + " kb";
auto ssize = CCLabelTTF::create(sizecontent.c_str(), "Arial", 15);
ssize->setColor(ccGREEN);
ssize->setPosition(ccp(width, height - 30 ));
ssize->setAnchorPoint(CCPointZero);
ssize->setTag(CELL_SSIZE);
cellContent->addChild(ssize);
//时间
std::
string stimecontent = element.stime + " s";
auto stime = CCLabelTTF::create(stimecontent.c_str(), "Arial", 15);
stime->setColor(ccGREEN);
stime->setPosition(ccp(width + 150, height - 30 ));
stime->setAnchorPoint(CCPointZero);
stime->setTag(CELL_STIME);
cellContent->addChild(stime);
/*
CCLabelTTF *pLabel = CCLabelTTF::create(element.id.c_str(), "Arial", 25.0);
pLabel->setPosition(CCPointZero);
pLabel->setAnchorPoint(CCPointZero);
pLabel->setTag(CELL_ID);
cellContent->addChild(pLabel);
*/ cellContent->setTag(CELL_CONTENT);
return cellContent;
}
CCTableViewCell* ListViewLayer::tableCellAtIndex(CCTableView *table, unsigned
int idx)
{
CCLog("%s: idx %d", m_type.c_str(), idx);
/*
if(refreshLayer != NULL){
refreshLayer->setVisible(false);
m_tableView->removeChild(refreshLayer);
refreshLayer = NULL;
isRefreshShow = false;
}
*/ //如果是在收藏里面,那就不做动态加载
if( idx >= m_tableNum - 1 && !m_firstLoad && !Collection::instance()->isExplorering()){
auto ret = getNewPageOfIndex(idx);
if(ret != 1){
CCLog("elements all showed %i", m_tableNum);
}
else{
CCLog("m_tableNum %i", m_tableNum);
//滚动的幅度相当于从最低点开始向上加倒数第idx个元素的高度
m_tableView->reloadData();
scrollToIndex(m_tableView, idx-6);
m_tableView->updateInset();
}
}
auto pCell = table->dequeueCell();
auto element = m_message.elements[idx];
auto cellContent = createCell(element);
if (!pCell) {
pCell =
new CCTableViewCell();
pCell->autorelease();
pCell->addChild(cellContent);
}
else{
pCell->removeAllChildren();
pCell->addChild(cellContent);
}
return pCell;
}
static void downloadAndPlay(
const Element & element){
Downloader::download(element.sound_url, element.sound);
Downloader::wait();
SimpleAudioEngine::sharedEngine()->stopAllEffects();
SimpleAudioEngine::sharedEngine()->setEffectsVolume(1.0);
auto volume = SimpleAudioEngine::sharedEngine()->getEffectsVolume();
CCLog("volome = %f", volume);
SimpleAudioEngine::sharedEngine()->playEffect((CCFileUtils::sharedFileUtils()->getWritablePath() + element.sound).c_str());
}
CCSprite *getPlayItem(CCTableViewCell* cell){
return (CCSprite*)cell->getChildByTag(CELL_CONTENT)->getChildByTag(PLAY_ITEM);
}
//这个函数真是,逻辑非常严密
void ListViewLayer::playMusic(
const Element & element, CCTableViewCell* cell){
static const std::
string notPlayImg = "发送=播放.png";
static const std::
string playingImg = "发送=暂停.png";
static std::
string oldStateImg = "";
SimpleAudioEngine::sharedEngine()->stopAllEffects();
if(getOldCell() != NULL){
if(getOldCell()->getIdx() == cell->getIdx()){
//点击的是同一个Cell, 更换原来的图片
//因为oldCell != NULL,所以这里不会是第一次近来的情况,因此始终在点击同一个图标时切换图标状态
if(oldStateImg == ""){
oldStateImg = playingImg;
downloadAndPlay(element);
}
else if(oldStateImg == playingImg){
oldStateImg = notPlayImg;
}
else{
oldStateImg = playingImg;
downloadAndPlay(element);
}
auto item2 = getPlayItem(cell);
item2->initWithFile(oldStateImg.c_str());
}
else{
//点击的不是同一个Cell, 旧的停止,新的开始
//旧的停止
auto item = getPlayItem(getOldCell());
item->initWithFile(notPlayImg.c_str());
//新的开始
auto item2 = getPlayItem(cell);
item2->initWithFile(playingImg.c_str());
downloadAndPlay(element);
oldStateImg = playingImg;
}
}
else{
//first time to click play menu
auto item = getPlayItem(cell);
item->initWithFile(playingImg.c_str());
downloadAndPlay(element);
}
setOldCell( cell);
}
unsigned
int ListViewLayer::numberOfCellsInTableView(CCTableView *table)
{
return m_tableNum;
}
void ListViewLayer::scrollViewDidScroll(CCScrollView *view)
{
auto height = m_tableView->getContentOffset().y;
//CCLog("scrollViewDidScroll, curretn height = %f, scroll height = %f", m_oldContentSize.y, height);
if( fabs(m_oldContentSize.y) < fabs(height) - 150.0){
std::
string filename = "主界面-音频信息板.png";
std::
string refreshStr = "加载中
";
std::
string timeStr = "
";
if(isRefreshShow ==
false){
CCSprite * tmpSprite = CCSprite::create(filename.c_str());
auto rect = CCRectMake(0, 0, tmpSprite->getContentSize().width, tmpSprite->getContentSize().height);
auto frame = CCSpriteFrame::create(filename.c_str(), rect);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFrame(frame, filename.c_str());
refreshLayer = CCLayer::create();
refreshLogoSpr = CCSprite::createWithSpriteFrameName(filename.c_str());
CCSpriteFrame *a = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(filename.c_str());
refreshLogoSpr->setDisplayFrame(a);
refreshInfoLab = CCLabelTTF::create(refreshStr.c_str(), "Thonburi", 24);
timeLab = CCLabelTTF::create(timeStr.c_str(),"Thonburi", 24);
auto bili = 1.0;
refreshLogoSpr->setScale(bili);
refreshLogoSpr->setPosition(ccp(135 + refreshLogoSpr->getContentSize().width/2, 50));
refreshInfoLab->setScale(bili);
refreshInfoLab->setColor(ccc3(0, 0, 0));
refreshInfoLab->setPosition(ccp(winSize.width/2, 75));
timeLab->setScale(bili);
timeLab->setColor(ccc3(0, 0, 0));
timeLab->setPosition(ccp(winSize.width/2-75, 25));
refreshLogoSpr->setTag(9999);
refreshInfoLab->setTag(8888);
timeLab->setTag(7777);
refreshLayer->addChild(refreshLogoSpr);
refreshLayer->addChild(refreshInfoLab);
refreshLayer->addChild(timeLab);
refreshLayer->setTag(555);
m_tableView->addChild(refreshLayer, 11);
//之前的位置;放在最后面:refreshLayer->setPosition(ccp(0, refreshLayer->getContentSize().height));
CCSprite *refreshLogoSpr111= CCSprite::createWithSpriteFrameName(filename.c_str());
refreshLogoSpr111->setTag(888);
isRefreshShow =
true;
}
else {
refreshLogoSpr = (CCSprite*)refreshLayer->getChildByTag(9999);
CCSpriteFrame *a = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(filename.c_str());
refreshLogoSpr->setDisplayFrame(a);
refreshInfoLab =(CCLabelTTF*)refreshLayer->getChildByTag(8888);
timeLab = (CCLabelTTF*)refreshLayer->getChildByTag(7777);
refreshInfoLab->setString(refreshStr.c_str());
timeLab->setString(timeStr.c_str());
//放在最上面
refreshLayer->setPosition(ccp(-50, m_tableView->getContentSize().height + 50));
/*
m_message.elements.clear();
auto ret = getNewPageOfIndex(0);
if(ret != 1){
CCLog("elements all showed %i", m_tableNum);
}else{
CCLog("m_tableNum %i", m_tableNum);
}
*/ }
// auto tmpH2 = m_tableView->getContentOffset().y;
// refreshLayer->setPosition(ccp(0, tmpH2));
}
}
void ListViewLayer::scrollViewDidZoom(CCScrollView *view)
{
CCLog("scrollViewDidZoom");
}
bool ListViewLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){
return m_tableView->ccTouchBegan(pTouch, pEvent);
}
void ListViewLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){
m_tableView->ccTouchEnded(pTouch, pEvent);
}
void ListViewLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){
m_tableView->ccTouchMoved(pTouch, pEvent);
}
void ListViewLayer::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){
m_tableView->ccTouchCancelled(pTouch, pEvent);
}
void ListViewLayer::onEnter(){
CCLayer::onEnter();
m_firstLoad =
false;
}
void ListViewLayer::onExit(){
CCLayer::onExit();
m_firstLoad =
false;
}