一步步实现 仿制Android LOL多玩盒子(三) 英雄基础

一、原应用模块简介

1,入口,主界面-英雄。
2,英雄列表模块中包含一个ViewPager的指示器,一个ViewPager。一共三页,免费、收藏、全部。都是每页的内容都包含一个GridView,全部页面包含一个搜索框。点击GridView的某一项后进入英雄详情界面。英雄详情界面包含若干ImageView,一堆TextView,部分组合视图支持展开隐藏;包含一个SeekBar,拖动SeekBar动态更新关联的英雄数据;英雄技能栏与技能描述栏联动,选中的技能图标点亮;点击最佳搭档或最佳克制的英雄的头像跳转到对应的英雄的详细信息界面。
一步步实现 仿制Android LOL多玩盒子(三) 英雄基础_第1张图片         一步步实现 仿制Android LOL多玩盒子(三) 英雄基础_第2张图片

二、功能分析

1,英雄列表

使用ViewPager、FragmentPagerAdapter、ViewPagerIndicator即可实现,ViewPager的每一页作为一个单独的Fragment,三个内容Fragment的结构均一致,由于涉及到其他模块,收藏功能、全部英雄页面的搜索功能暂时不做。由于ViewPager是在android的支持包(如android.support.v4)中的,其中自带的FragmentPagerAdapter也只支持支持包中的Fragment,而我的应用使用到的Activity和Fragment都是android包中的,于是支持包中的FragmentPagerAdapter就没法用,可以把支持包中的FragmentPagerAdapter源代码拷一份出来,把其中的支持包中的Fragment改为android包中的Fragment即可,功能完全一致。
免费英雄界面和全部英雄界面中呈现的内容都是 请求服务器获取 Json 后解析得到英雄简要信息列表,再根据英雄名去请求服务器获取英雄图片。免费英雄界面和全部英雄界面的Json格式大体一致。
请求格式为:http://lolbox.duowan.com/phone/apiHeroes.php?type=free 或 http://lolbox.duowan.com/phone/apiHeroes.php?type=all
请求结果Json格式为
{"free":[{"enName":"Taric","cnName":"\u5854\u91cc\u514b","title":"\u5b9d\u77f3\u9a91\u58eb","tags":"support","rating":"4,8,5,5","location":"\u6253\u91ce,\u8f85\u52a9","price":"3150,1500"},{"enName":"Maokai","cnName":"\u8302\u51ef","title":"\u626d\u66f2\u6811\u7cbe","tags":"tank","rating":"3,8,6,3","location":"\u6253\u91ce","price":"4800,3000"},{"enName":"Udyr","cnName":"\u4e4c\u8fea\u5c14","title":"\u517d\u7075\u884c\u8005","tags":"fighter","rating":"8,7,4,7","location":"\u4e0a\u5355,\u6253\u91ce","price":"3150,2500"},{"enName":"Zyra","cnName":"\u5a55\u62c9","title":"\u8346\u68d8\u4e4b\u5174","tags":"mage","rating":"4,3,8,7","location":"\u4e2d\u5355,\u8f85\u52a9","price":"6300,4500"},{"enName":"XinZhao","cnName":"\u8d75\u4fe1","title":"\u5fb7\u90a6\u603b\u7ba1","tags":"fighter","rating":"8,6,3,2","location":"\u4e0a\u5355,\u6253\u91ce","price":"3150,2500"},{"enName":"Heimerdinger","cnName":"\u9ed1\u9ed8\u4e01\u683c","title":"\u5927\u53d1\u660e\u5bb6","tags":"mage","rating":"2,6,8,8","location":"\u4e0a\u5355,\u4e2d\u5355","price":"3150,2500"},{"enName":"Olaf","cnName":"\u5965\u62c9\u592b","title":"\u72c2\u6218\u58eb","tags":"fighter","rating":"9,5,3,3","location":"\u4e0a\u5355,\u6253\u91ce","price":"3150,1500"},{"enName":"FiddleSticks","cnName":"\u8d39\u5fb7\u63d0\u514b","title":"\u672b\u65e5\u4f7f\u8005","tags":"mage","rating":"2,3,9,9","location":"\u4e2d\u5355,\u6253\u91ce,\u8f85\u52a9","price":"1350,2000"},{"enName":"Tristana","cnName":"\u5d14\u4e1d\u5854\u5a1c","title":"\u9ea6\u6797\u70ae\u624b","tags":"marksman","rating":"9,3,5,4","location":"\u4e2d\u5355,ADC","price":"1350,1000"},{"enName":"Quinn","cnName":"\u594e\u56e0","title":"\u5fb7\u739b\u897f\u4e9a\u4e4b\u7ffc","tags":"marksman","rating":"9,4,2,5","location":"ADC","price":"6300,4500"},{"enName":"Ashe","cnName":"\u827e\u5e0c","title":"\u5bd2\u51b0\u5c04\u624b","tags":"marksman,female ","rating":"7,3,2,4","location":"ADC","price":"450,1000"},{"enName":"Garen","cnName":"\u76d6\u4f26","title":"\u5fb7\u739b\u897f\u4e9a\u4e4b\u529b","tags":"fighter","rating":"7,7,1,5","location":"\u4e0a\u5355","price":"3150,1000"},{"enName":"Ryze","cnName":"\u745e\u5179","title":"\u6d41\u6d6a\u6cd5\u5e08","tags":"mage","rating":"2,2,10,7","location":"\u4e0a\u5355,\u4e2d\u5355","price":"450,1000"}],"desc":"*\u6bcf\u5468\u4e94\u66f4\u65b0\u5468\u514d"}
我们解析到free节点下的英雄列表后,再去根据英雄的英文名称去请求 英雄图片,请求格式为 http://img.lolbox.duowan.com/champions/Taric_120x120.jpg  ,其中最后一段下划线前的部分是英雄英文名称,下划线后的部分是图片的分辨率。

2,英雄详情

由英雄英文名请求英雄详情的格式为  http://lolbox.duowan.com/phone/apiHeroDetail.php?heroName=Taric  ,请求得到的Json格式为
{"id":"44","name":"Taric","displayName":"\u5b9d\u77f3\u9a91\u58eb","title":"\u5854\u91cc\u514b","iconPath":"Taric_Square_0.png","portraitPath":"Taric_0.jpg","splashPath":"Taric_Splash_0.jpg","danceVideoPath":"0044_dance.mp4","tags":"\u8f85\u52a9","description":"\u5728\u7b26\u6587\u4e4b\u5730\uff0c\u6709\u4e00\u79cd\u9c9c\u4e3a\u4eba\u77e5\u7684\u9b54\u6cd5\uff0c\u5c3d\u7ba1\u6709\u5c11\u6570\u4eba\u610f\u8bc6\u5230\u5b83\u7684\u5b58\u5728\uff0c\u5374\u5bf9\u5176\u6df1\u8868\u6000\u7591\u3002\u8fd9\u79cd\u9b54\u6cd5\u662f\u5927\u5730\u9b54\u6cd5\uff0c\u4ece\u6c34\u6676\u4e0e\u5b9d\u77f3\u7684\u5171\u632f\u4e2d\u6c72\u53d6\u529b\u91cf\u3002\u5b9d\u77f3\u9a91\u58eb\u5854\u91cc\u514b\u4fbf\u662f\u7b26\u6587\u4e4b\u5730\u552f\u4e00\u4fee\u4e60\u6b64\u9b54\u6cd5\u7684\u4eba\uff0c\u4ed6\u4f1a\u88ab\u4e0d\u5b9a\u671f\u5730\u4ece\u9065\u8fdc\u7684\u4e16\u754c\u53ec\u5524\u5230\u7b26\u6587\u4e4b\u5730\u3002\n\n\u4ed6\u7684\u7236\u4eb2\u662f\u5bb6\u4e61\u8d6b\u8d6b\u6709\u540d\u7684\u533b\u7597\u5e08\u3002\u5854\u91cc\u514b\u81ea\u5c0f\u5c31\u4e00\u76f4\u70ed\u8877\u4e8e\u7236\u4eb2\u7684\u8ffd\u6c42\u3002\u4ed6\u5f88\u5feb\u4fbf\u7cbe\u901a\u5404\u79cd\u8349\u836f\u3001\u690d\u7269\u4ee5\u53ca\u52a8\u7269\u836f\u6750\u3002\u968f\u7740\u5e74\u9f84\u7684\u589e\u957f\uff0c\u6700\u4ee4\u4ed6\u75f4\u8ff7\u7684\u83ab\u8fc7\u4e8e\u5b9d\u77f3\u7684\u529b\u91cf\u4e86\u3002\u6ca1\u8fc7\u591a\u4e45\uff0c\u5854\u91cc\u514b\u4fbf\u770b\u5b8c\u4e86\u7236\u4eb2\u56fe\u4e66\u9986\u7684\u85cf\u4e66\uff0c\u5f00\u59cb\u8e0f\u4e0a\u81ea\u5df1\u7684\u5f81\u7a0b\u3002\u4ed6\u5e0c\u671b\u80fd\u5e2e\u52a9\u4e16\u4eba\uff0c\u4e0d\u4ec5\u4ec5\u662f\u4e3a\u5176\u7597\u4f24\uff0c\u8fd8\u60f3\u6cbb\u7597\u6240\u6709\u7684\u654c\u4eba\u3002\u4ed6\u5e76\u975e\u8981\u6210\u4e3a\u4e00\u4f4d\u533b\u7597\u5e08\uff0c\u800c\u662f\u4e00\u540d\u5b88\u62a4\u8005\u2014\u2014\u4e00\u540d\u4f7f\u7528\u5927\u5730\u4e4b\u529b\u7684\u4fdd\u62a4\u8005\u3002\n\n\u5854\u91cc\u514b\u6210\u4e86\u4e00\u540d\u6d6a\u8ff9\u56db\u65b9\u7684\u9a91\u58eb\u3002\u5728\u4ed6\u7684\u6545\u571f\uff0c\u4ed6\u662f\u4e3e\u56fd\u95fb\u540d\u7684\u6b63\u4e49\u5b88\u62a4\u8005\u3002\u76f4\u5230\u6709\u4e00\u5929\uff0c\u4e00\u79cd\u53ec\u5524\u7684\u9b54\u6cd5\u5c06\u5176\u5e26\u79bb\u4e86\u5bb6\u4e61\uff0c\u6765\u5230\u7b26\u6587\u4e4b\u5730\u3002\u4e00\u5f00\u59cb\uff0c\u5854\u91cc\u514b\u6709\u70b9\u60ca\u614c\u5931\u63aa\uff0c\u8ff7\u60d1\u4e0d\u89e3\uff0c\u4f46\u73b0\u5728\u4ed6\u89c9\u5f97\u74e6\u6d1b\u5170\u5927\u9646\u9700\u8981\u50cf\u4ed6\u8fd9\u6837\u7684\u4eba\u3002\u5c3d\u7ba1\u601d\u4e61\u60c5\u5207\uff0c\u4ed6\u8fd8\u662f\u4e50\u4e8e\u5728\u8054\u76df\u6218\u6597\uff0c\u6551\u4eba\u4e8e\u5371\u96be\u4e4b\u9645\u3002\u4ed6\u90a3\u4fca\u79c0\u5229\u843d\u7684\u5916\u8868\uff0c\u518d\u52a0\u4e0a\u4ed6\u90a3\u95ea\u70c1\u7740\u73e0\u5149\u5b9d\u6c14\u7684\u76d4\u7532\u4e0e\u6b66\u5668\uff0c\u8ba9\u4ed6\u8fc5\u901f\u6210\u4e3a\u82f1\u96c4\u8054\u76df\u7684\u540d\u4eba\u3002\u74e6\u6d1b\u5170\u7684\u5a92\u4f53\uff0c\u51fa\u4e8e\u67d0\u79cd\u539f\u56e0\uff0c\u5bf9\u4ed6\u7684\u4e2a\u4eba\u751f\u6d3b\u5f88\u611f\u5174\u8da3\u3002\u867d\u7136\u5854\u91cc\u514b\u4e00\u76f4\u5766\u88ce\u4ed6\u4f5c\u4e3a\u82f1\u96c4\u7684\u751f\u6d3b\uff0c\u5bf9\u4e00\u5207\u4e8b\u7269\u4e5f\u90fd\u5bbd\u5bb9\u5927\u65b9\uff0c\u4f46\u5bf9\u4e8e\u81ea\u5df1\u8054\u76df\u4ee5\u5916\u7684\u751f\u6d3b\u5374\u4e00\u76f4\u5b88\u53e3\u5982\u74f6\uff0c\u4fdd\u62a4\u7740\u81ea\u5df1\u7684\u9690\u79c1\u3002\n\n\u5854\u91cc\u514b\u7684\u7236\u4eb2\u66fe\u6559\u5bfc\u4ed6\uff0c\u6bcf\u5757\u77f3\u5934\u7686\u6709\u5176\u610f\u4e49\u6240\u5728\u3002\u5bf9\u4e8e\u5854\u91cc\u514b\u7684\u654c\u4eba\u6765\u8bf4\uff0c\u77f3\u5934\u7684\u610f\u4e49\u4fbf\u662f\u62db\u6765\u9ebb\u70e6\u3002","quote":"","quoteAuthor":"","range":"125.0","moveSpeed":"340.0","armorBase":"25.876","armorLevel":"3.2","manaBase":"349.08","manaLevel":"56.0","criticalChanceBase":"0.0","criticalChanceLevel":"0.0","manaRegenBase":"1.2","manaRegenLevel":"0.16","healthRegenBase":"1.588","healthRegenLevel":"0.1","magicResistBase":"32.1","magicResistLevel":"1.25","healthBase":"619.2","healthLevel":"90.0","attackBase":"57.88","attackLevel":"3.5","ratingDefense":"8","ratingMagic":"5","ratingDifficulty":"5","ratingAttack":"4","tips":"-- \u5982\u679c\u5854\u91cc\u514b\u5bf9\u81ea\u5df1\u4f7f\u7528\u795e\u5723\u6d17\u793c\uff0c\u4ed6\u5c06\u4f1a\u83b7\u5f97\u66f4\u591a\u7684\u6cbb\u7597\u6548\u679c\uff0c\u56e0\u6b64\u4ed6\u5f88\u64c5\u957f\u627f\u53d7\u9632\u5fa1\u5854\u7684\u653b\u51fb\u3002\n-- \u6709\u65f6\u4e0d\u6253\u788e\u5b9d\u77f3\u62a4\u76fe\u3001\u4fdd\u7559\u5149\u73af\u6548\u679c\u66f4\u597d\u3002","opponentTips":"-- \u5854\u91cc\u514b\u7684\u5b9d\u77f3\u62a4\u76fe\u6280\u80fd\u8ba9\u4ed6\u62e5\u6709\u5f88\u5f3a\u7684\u62a4\u7532\u3002\u56e0\u6b64\u6cd5\u7cfb\u82f1\u96c4\u6bd4\u7269\u7406\u7cfb\u82f1\u96c4\u8981\u66f4\u5bb9\u6613\u4f24\u5bb3\u5230\u4ed6\u3002\n-- \u4e86\u89e3\u5854\u91cc\u514b\u7684\u53ec\u5524\u5e08\u6280\u80fd\u3002\u5982\u679c\u4ed6\u4f7f\u7528\u6e05\u6670\u672f\uff0c\u90a3\u4e48\u8fc7\u65e9\u4f7f\u7528\u6280\u80fd\u5bf9\u5176\u8fdb\u884c\u9a9a\u6270\u7684\u6548\u679c\u4e0d\u5927\u3002","selectSoundPath":"zh_CN\/Taric.mp3","Taric_B":{"id":"451","name":"\u5b9d\u77f3\u72c2\u70ed","cost":"","cooldown":"","description":"\u5728\u65bd\u653e\u4e00\u6b21\u6280\u80fd\u540e\uff0c\u5854\u91cc\u514b\u7684\u4e0b\u4e00\u6b21\u666e\u653b\u5c06\u9020\u6210\u4ed620%\u62a4\u7532\u503c\u7684\u989d\u5916\u9b54\u6cd5\u4f24\u5bb3\uff0c\u5e76\u51cf\u5c11\u5854\u91cc\u514b\u6240\u6709\u6280\u80fd2\u79d2\u7684\u51b7\u5374\u65f6\u95f4\u3002","range":"","effect":""},"Taric_Q":{"id":"452","name":"\u795e\u5723\u6d17\u793c","cost":"60\/80\/100\/120\/140 \u6cd5\u529b","cooldown":"18\/17\/16\/15\/14","description":"\u5854\u91cc\u514b\u53ec\u5524\u5927\u5730\u80fd\u91cf\u6765\u540c\u65f6\u6cbb\u7597\u4e00\u540d\u53cb\u519b\u548c\u81ea\u5df1\u3002\u82e5\u5854\u91cc\u514b\u53ea\u6cbb\u7597\u81ea\u5df1\uff0c\u5219\u6548\u679c\u4f1a\u66f4\u663e\u8457\u3002","range":"","effect":"\u4e3b\u52a8\u6548\u679c\uff1a \u5854\u91cc\u514b\u53ec\u5524\u5927\u5730\u80fd\u91cf\u540c\u65f6\u6cbb\u7597\u53cb\u519b\u548c\u81ea\u5df1 60\/100\/140\/180\/220(+0.3AP)\uff08+0.05\u5854\u91cc\u514b\u989d\u5916\u751f\u547d\u503c\uff09\u70b9\u751f\u547d\u503c\u3002\u82e5\u53ea\u6709\u5854\u91cc\u514b\u81ea\u5df1\u53d7\u5230\u6cbb\u7597\uff0c\u5219\u6548\u679c\u63d0\u9ad8 40%\uff0c\u56de\u590d 84\/140\/196\/252\/308(+0.84AP)\uff08+0.07\u5854\u91cc\u514b\u989d\u5916\u751f\u547d\u503c\uff09\u70b9\u751f\u547d\u503c\u3002"},"Taric_W":{"id":"453","name":"\u5b9d\u77f3\u62a4\u76fe","cost":"50\/50\/50\/50\/50 \u6cd5\u529b","cooldown":"10\/10\/10\/10\/10","description":"\u5854\u91cc\u514b\u53d7\u5230\u5b9d\u77f3\u62a4\u7532\u5149\u73af\u6240\u4fdd\u62a4\uff0c\u4ece\u800c\u589e\u52a0\u81ea\u5df1\u548c\u5468\u56f4\u53cb\u519b\u7684\u62a4\u7532\u3002\u5854\u91cc\u514b\u53ef\u4ee5\u4e3b\u52a8\u6253\u788e\u62a4\u7532\uff0c\u5bf9\u5468\u56f4\u654c\u519b\u9020\u6210\u4f24\u5bb3\uff0c\u6682\u65f6\u964d\u4f4e\u5468\u56f4\u654c\u519b\u7684\u62a4\u7532\uff0c\u5e76\u4e14\u81ea\u5df1\u7684\u62a4\u7532\u4e5f\u5f97\u5230\u63d0\u5347\u3002","range":"400","effect":"\u88ab\u52a8\u6548\u679c\uff1a\u5854\u91cc\u514b\u7684\u5b9d\u77f3\u4f1a\u589e\u52a0\u81ea\u5df110\/15\/20\/25\/30\u62a4\u7532\u3002\u6b64\u5916\uff0c\u5468\u56f4\u7684\u53cb\u519b\u82f1\u96c4\u4f1a\u83b7\u5f97\u62a4\u7532\uff08\u76f8\u5f53\u4e8e\u5854\u91cc\u514b12\/12\/12\/12\/12%\u7684\u62a4\u7532\uff09\u3002\n\n\u4e3b\u52a8\u6548\u679c\uff1a\u5854\u91cc\u514b\u9707\u788e\u4ed6\u7684\u62a4\u7532\uff0c\u5bf9\u5468\u56f4\u654c\u65b9\u9020\u621040\/80\/120\/160\/200(+\u5854\u91cc\u514b20%\u7684\u62a4\u7532)\u9b54\u6cd5\u4f24\u5bb3\uff0c\u5e76\u51cf\u5c11\u4ed6\u4eec5\/10\/15\/20\/25(\u5854\u91cc\u514b10%\u603b\u62a4\u7532\u503c\u7684\u52a0\u6210)\u62a4\u7532\uff0c\u6301\u7eed4\/4\/4\/4\/4\u79d2\u3002\u5728\u8be5\u6280\u80fd\u7684\u51b7\u5374\u671f\u95f4\uff0c\u5854\u91cc\u514b\u4f1a\u635f\u59315\/10\/15\/20\/25\u62a4\u7532\u3002"},"Taric_E":{"id":"454","name":"\u70ab\u5149","cost":"75\/75\/75\/75\/75 \u6cd5\u529b","cooldown":"18\/17\/16\/15\/14","description":"\u5854\u91cc\u514b\u4ece\u5b9d\u77f3\u76fe\u724c\u653e\u5c04\u51fa\u70ab\u76ee\u4e4b\u5149\uff0c\u6655\u7729\u5e76\u4f24\u5bb3\u654c\u4eba\u3002","range":"625","effect":"\u5854\u91cc\u514b\u5411\u76ee\u6807\u654c\u519b\u653e\u5c04\u51fa\u4e00\u56e2\u70ab\u76ee\u7684\u5149\u7403\uff0c\u5bf9\u5176\u9020\u62101.2\/1.3\/1.4\/1.5\/1.6\u79d2\u7684\u6655\u7729\u6548\u679c\uff0c\u4ee5\u53ca40\/70\/100\/130\/160(+0.2AP)\u70b9\u523080\/140\/200\/260\/320(+0.4AP)\u70b9\u4e4b\u95f4\u7684\u9b54\u6cd5\u4f24\u5bb3\u3002\u5854\u91cc\u514b\u79bb\u76ee\u6807\u8d8a\u8fd1\uff0c\u7729\u5149\u7684\u4f24\u5bb3\u5c31\u4f1a\u8d8a\u9ad8\u3002"},"Taric_R":{"id":"455","name":"\u8f89\u8000","cost":"100\/100\/100 \u6cd5\u529b","cooldown":"75\/75\/75","description":"\u5854\u91cc\u514b\u5c06\u4ed6\u7684\u9524\u5b50\u7838\u8fdb\u5730\u9762\uff0c\u6765\u5bf9\u9644\u8fd1\u7684\u654c\u4eba\u9020\u6210\u4f24\u5bb3\u3002\u5728\u968f\u540e\u7684\u4e00\u6bb5\u65f6\u95f4\u91cc\uff0c\u4ed6\u7684\u5b9d\u77f3\u4f1a\u6563\u53d1\u51fa\u80fd\u91cf\uff0c\u4e3a\u5854\u91cc\u514b\u548c\u4ed6\u7684\u53cb\u519b\u63d0\u4f9b\u989d\u5916\u7684\u653b\u51fb\u529b\u548c\u6cd5\u672f\u5f3a\u5ea6\u3002","range":"400","effect":"\u5854\u91cc\u514b\u5c06\u4ed6\u7684\u9524\u5b50\u7838\u8fdb\u5730\u9762\uff0c\u6765\u5bf9\u9644\u8fd1\u7684\u654c\u4eba\u9020\u6210150\/250\/350(+0.5AP)\u70b9\u7684\u9b54\u6cd5\u4f24\u5bb3\u3002\n\n\u5728\u968f\u540e\u768410\/10\/10\u79d2\u91cc\uff0c\u4ed6\u7684\u5b9d\u77f3\u4f1a\u6563\u53d1\u51fa\u80fd\u91cf\uff0c\u4e3a\u5854\u91cc\u514b\u63d0\u4f9b\u989d\u5916\u768430\/50\/70\u70b9\u653b\u51fb\u529b\u548c\u6cd5\u672f\u5f3a\u5ea6\uff0c\u5e76\u4e14\u4ed6\u5468\u56f4\u7684\u53cb\u519b\u4eab\u53d7\u6b64\u6548\u679c\u7684\u4e00\u534a\u3002"},"price":"3150,1500","like":[{"partner":"Ezreal","des":"\u540c\u6837\u7684\uff0cEZ\u7684\u8f93\u51fa\u4e5f\u662f\u975e\u5e38\u5f3a\u5927\u7684\uff0c\u4ed6\u53ef\u4ee5\u5728\u5b9d\u77f3\u6655\u4f4f\u76ee\u6807\u4ee5\u540e\uff0c\u6253\u51fa\u5f88\u9ad8\u7684\u8f93\u51fa\uff0c\u88ab\u63a7\u5236\u4f4f\u7684\u76ee\u6807\uff0c\u8ba9\u4f60\u653e\u7684\u5927\u62db\u66f4\u52a0\u7684\u51c6\u786e\uff0c\u589e\u52a0\u4f60\u5927\u62db\u7684\u547d\u4e2d\u7387\u3002"},{"partner":"Vayne","des":"\u5b9d\u77f3\u6709\u7740\u5f88\u7a33\u5b9a\u7684\u63a7\u5236\u6280\u80fd\uff0c\u5b9d\u77f3\u7684E\u6280\u80fd\u53ef\u4ee5\u8ba9\u76ee\u6807\u6655\u7729\uff0c\u5e2e\u52a9VN\u66f4\u597d\u7684\u8f93\u51fa\uff0c\u7528Q\u6280\u80fd\u6253\u51fa\u4f24\u5bb3\uff0cW\u6280\u80fd\u53ef\u4ee5\u7ed9\u81ea\u5df1\u52a0\u62a4\u7532\u6216\u8005\u964d\u4f4e\u76ee\u6807\u62a4\u7532\uff0cQ\u6280\u80fd\u4e5f\u6709\u6062\u590d\u6548\u679c\uff0c\u53ef\u4ee5\u6062\u590d\u751f\u547d\u503c\u3002"}],"hate":[{"partner":"Zyra","des":"\u5c3d\u7ba1\u5a55\u62c9\u5f88\u8106\u76ae\uff0c\u4e5f\u6ca1\u6709\u4f4d\u79fb\uff0c\u4f46\u662f\u5a55\u62c9\u7684\u63a7\u5236\u80fd\u529b\u5f88\u5f3a\u5927\uff0c\u8f85\u52a9\u4f4d\u7684\u5a55\u62c9\u4f24\u5bb3\u548c\u4f5c\u7528\u4e00\u6837\u4e1d\u6beb\u4e0d\u6bd4\u5b9d\u77f3\u5dee\uff0c\u5927\u62db\u7684\u56e2\u4f53\u63a7\u5236\u5f80\u5f80\u80fd\u8d77\u5230\u975e\u5e38\u5173\u952e\u7684\u6548\u679c\u3002"},{"partner":"Lulu","des":"\u7490\u7490\u7684\u6280\u80fd\u5c04\u7a0b\u975e\u5e38\u8fdc\uff0c\u624b\u5f88\u957f\uff0c\u6240\u4ee5\u4f60\u5f88\u96be\u9760\u8fd1\u7490\u7490\uff0c\u6c89\u9ed8\u901a\u5e38\u4f1a\u5728\u5173\u952e\u7684\u65f6\u5019\u8981\u4e86\u4f60\u7684\u5c0f\u547d\uff0c\u6216\u8005\u662f\u4f60\u961f\u53cb\u7684\u5c0f\u547d\uff0c\u5927\u62db\u53ef\u4ee5\u51fb\u98de\u51cf\u901f\u4fdd\u62a4\u81ea\u5df1\u6216\u8005\u81ea\u5df1\u65b9\u76ee\u6807\u3002"}]}
这里面包含了英雄详情界面所需的所有信息了,有个地方需要注意,英雄技能节点,字段名格式为   Taric_Q  ,由于不同英雄的名称不同,所以获得到的英雄详情Json 的字段名并不是完全一致的。可以使用解析前矫正的方式解决这一问题,即把获取到的Json字符串先将其中的  Taric_Q 等字符串替换为 q 格式的字符串,然后再解析,便可成功解析出来了。这里也暴露了把Json解析为JavaBean的一个弊端,解析为 HashMap 格式便不会出现这样的问题,但是考虑到JavaBean比较直观,且大多数情况下Json中的字段名都是固定的,所以这里还是使用了JavaBean。
英雄详情界面比较复杂,标题栏中的那些功能留待日后再做。
该界面中有多个支持展开或收缩的视图,比较简单的实现方式是直接设置受影响的视图的 layout_height  或 visibility。
英雄的各项与等级关联的数据在Json中都是提供了一个基准值和一个每一级的浮动值,所以根据SeekBar的滑动来更新对应等级的英雄属性也比较简单。
搭档和克制英雄分别在 like 和hate字段中,包含每个英雄的英文名和 相关描述,根据该英文名可获取其头像。
英雄技能图标的请求格式为 http://img.lolbox.duowan.com/abilities/Taric_Q_64x64.png ,最后一段分别是 英雄英文名,技能位置,图片分辨率。

三、实现

1,由于标题栏几乎每个页面都会有,为避免代码重复,做了各自定义控件,封装标题栏的一些基本功能。尚未完善。
2,由于GridView大量出现,且基本都是内容区就一个GridView,封装了一个只包含GridView的Fragment。
3,可伸缩的组合视图可以考虑也封装成一个自定义控件,英雄技能选择器也可以封装成自定义控件,但是目前暂时未做。
/**
 * ViewPager 指示器,源自大神博客 http://blog.csdn.net/lmj623565791/article/details/42160391
 * @author zhy
 */
public class ViewPagerIndicator extends LinearLayout {

	/**
	 * 绘制三角形的画笔
	 */
	private Paint mPaint;
	/**
	 * path构成一个三角形
	 */
	private Path mPath;
	/**
	 * 三角形的宽度
	 */
	private int mTriangleWidth;
	/**
	 * 三角形的高度
	 */
	private int mTriangleHeight;

	/**
	 * 三角形的宽度为单个Tab的1/6
	 */
	private static final float RADIO_TRIANGEL = 1.0f / 6;
	/**
	 * 三角形的最大宽度
	 */
	private final int DIMENSION_TRIANGEL_WIDTH = (int) (getScreenWidth() / 3 * RADIO_TRIANGEL);

	/**
	 * 初始时,三角形指示器的偏移量
	 */
	private int mInitTranslationX;
	/**
	 * 手指滑动时的偏移量
	 */
	private float mTranslationX;

	/**
	 * 默认的Tab数量
	 */
	private static final int COUNT_DEFAULT_TAB = 4;
	/**
	 * tab数量
	 */
	private int mTabVisibleCount = COUNT_DEFAULT_TAB;

	/**
	 * tab上的内容
	 */
	private List mTabTitles;
	/**
	 * 与之绑定的ViewPager
	 */
	public ViewPager mViewPager;

	private static final int COLOR_TEXT_NORMAL = 0x77FFFFFF;
	private static final int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;
	/**
	 * 标题正常时的颜色
	 */
	private int mColorHighlight;
	/**
	 * 标题选中时的颜色
	 */
	private int mColorNormal;
	

	public ViewPagerIndicator(Context context) {
		this(context, null);
	}

	public ViewPagerIndicator(Context context, AttributeSet attrs) {
		
		super(context, attrs);

		// 获得自定义属性,tab的数量
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
		mTabVisibleCount = a.getInt(R.styleable.ViewPagerIndicator_item_count, COUNT_DEFAULT_TAB);
		if (mTabVisibleCount < 0) {
			mTabVisibleCount = COUNT_DEFAULT_TAB;
		}
		mColorHighlight = a.getColor(R.styleable.ViewPagerIndicator_item_color_select, COLOR_TEXT_HIGHLIGHTCOLOR);
		mColorNormal = a.getColor(R.styleable.ViewPagerIndicator_item_color, COLOR_TEXT_NORMAL);
		
		a.recycle();

		// 初始化画笔
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setColor(Color.parseColor("#ffffffff"));
		mPaint.setStyle(Style.FILL);
		mPaint.setPathEffect(new CornerPathEffect(3));
	}

	/**
	 * 绘制指示器
	 */
	@Override
	protected void dispatchDraw(Canvas canvas) {
		canvas.save();
		// 画笔平移到正确的位置
		canvas.translate(mInitTranslationX + mTranslationX, getHeight() + 1);
		canvas.drawPath(mPath, mPaint);
		canvas.restore();

		super.dispatchDraw(canvas);
	}

	/**
	 * 初始化三角形的宽度
	 */
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		mTriangleWidth = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// 1/6 of
																		// width
		mTriangleWidth = Math.min(DIMENSION_TRIANGEL_WIDTH, mTriangleWidth);

		// 初始化三角形
		initTriangle();

		// 初始时的偏移量
		mInitTranslationX = getWidth() / mTabVisibleCount / 2 - mTriangleWidth / 2;
	}

	/**
	 * 设置可见的tab的数量
	 * @param count
	 */
	public void setVisibleTabCount(int count) {
		this.mTabVisibleCount = count;
	}

	/**
	 * 设置tab的标题内容 可选,可以自己在布局文件中写死
	 * @param datas
	 */
	public void setTabItemTitles(List datas) {
		// 如果传入的list有值,则移除布局文件中设置的view
		if (datas != null && datas.size() > 0) {
			this.removeAllViews();
			this.mTabTitles = datas;

			for (String title : mTabTitles) {
				// 添加view
				addView(generateTextView(title));
			}
			// 设置item的click事件
			setItemClickEvent();
		}

	}

	/**
	 * 对外的ViewPager的回调接口
	 * @author zhy
	 */
	public interface PageChangeListener {
		public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

		public void onPageSelected(int position);

		public void onPageScrollStateChanged(int state);
	}

	// 对外的ViewPager的回调接口
	private PageChangeListener onPageChangeListener;

	// 对外的ViewPager的回调接口的设置
	public void setOnPageChangeListener(PageChangeListener pageChangeListener) {
		this.onPageChangeListener = pageChangeListener;
	}

	// 设置关联的ViewPager
	public void setViewPager(ViewPager mViewPager, int pos) {
		this.mViewPager = mViewPager;

		mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
				// 设置字体颜色高亮
				resetTextViewColor();
				highLightTextView(position);

				// 回调
				if (onPageChangeListener != null) {
					onPageChangeListener.onPageSelected(position);
				}
			}

			@Override
			public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
				// 滚动
				scroll(position, positionOffset);

				// 回调
				if (onPageChangeListener != null) {
					onPageChangeListener.onPageScrolled(position, positionOffset,
								positionOffsetPixels);
				}

			}

			@Override
			public void onPageScrollStateChanged(int state) {
				// 回调
				if (onPageChangeListener != null) {
					onPageChangeListener.onPageScrollStateChanged(state);
				}

			}
		});
		// 设置当前页
		mViewPager.setCurrentItem(pos);
		// 高亮
		highLightTextView(pos);
	}

	/**
	 * 高亮文本
	 * @param position
	 */
	protected void highLightTextView(int position) {
		View view = getChildAt(position);
		if (view instanceof TextView) {
			((TextView) view).setTextColor(mColorHighlight);
		}

	}

	/**
	 * 重置文本颜色
	 */
	private void resetTextViewColor() {
		for (int i = 0; i < getChildCount(); i++) {
			View view = getChildAt(i);
			if (view instanceof TextView) {
				((TextView) view).setTextColor(mColorNormal);
			}
		}
	}

	/**
	 * 设置点击事件
	 */
	public void setItemClickEvent() {
		int cCount = getChildCount();
		for (int i = 0; i < cCount; i++) {
			final int j = i;
			View view = getChildAt(i);
			view.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mViewPager.setCurrentItem(j);
				}
			});
		}
	}

	/**
	 * 根据标题生成我们的TextView
	 * @param text
	 * @return
	 */
	private TextView generateTextView(String text) {
		TextView tv = new TextView(getContext());
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
					LayoutParams.MATCH_PARENT);
		lp.width = getScreenWidth() / mTabVisibleCount;
		tv.setGravity(Gravity.CENTER);
		tv.setTextColor(mColorNormal);
		tv.setText(text);
		tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
		tv.setLayoutParams(lp);
		return tv;
	}

	/**
	 * 初始化三角形指示器
	 */
	private void initTriangle() {
		mPath = new Path();

		mTriangleHeight = (int) (mTriangleWidth / 2 / Math.sqrt(2));
		mPath.moveTo(0, 0);
		mPath.lineTo(mTriangleWidth, 0);
		mPath.lineTo(mTriangleWidth / 2, -mTriangleHeight);
		mPath.close();
	}

	/**
	 * 指示器跟随手指滚动,以及容器滚动
	 * @param position
	 * @param offset
	 */
	public void scroll(int position, float offset) {
		/**
		 * 
		 *  0-1:position=0 ;1-0:postion=0;
		 * 
*/ // 不断改变偏移量,invalidate mTranslationX = getWidth() / mTabVisibleCount * (position + offset); int tabWidth = getScreenWidth() / mTabVisibleCount; // 容器滚动,当移动到倒数最后一个的时候,开始滚动 if (offset > 0 && position >= (mTabVisibleCount - 2) && getChildCount() > mTabVisibleCount) { if (mTabVisibleCount != 1) { this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth + (int) (tabWidth * offset), 0); } else // 为count为1时 的特殊处理 { this.scrollTo(position * tabWidth + (int) (tabWidth * offset), 0); } } invalidate(); } /** * 设置布局中view的一些必要属性;如果设置了setTabTitles,布局中view则无效 */ @Override protected void onFinishInflate() { Log.e("TAG", "onFinishInflate"); super.onFinishInflate(); int cCount = getChildCount(); if (cCount == 0) { return; } for (int i = 0; i < cCount; i++) { View view = getChildAt(i); LinearLayout.LayoutParams lp = (LayoutParams) view.getLayoutParams(); lp.weight = 0; lp.width = getScreenWidth() / mTabVisibleCount; view.setLayoutParams(lp); } // 设置点击事件 setItemClickEvent(); } /** * 获得屏幕的宽度 * @return */ public int getScreenWidth() { WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.widthPixels; } }
/**
 * 标题栏
 * @author warren
 * @date 2015年1月1日
 */
public class TitleBar extends RelativeLayout {

	private ImageView mImgLeft;
	private ImageView mImgRight;
	private TextView mTvTitle;
	
	private View.OnClickListener mLeftClickListener;
	private View.OnClickListener mRightClickListener;

	public TitleBar(Context context) {
		super(context);
	}

	public TitleBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);
	}
	
	public TitleBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs);
	}

	private void init(AttributeSet attrs) {

		// 这里添加控件也可以使用布局文件的形式。
		// 使用布局文件的方式为   
		// LayoutInflater.from(getContext()).inflate(layoutResId, this, true);
		// ImageView img = findViewById(imgResId);
		
		
		TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TitleBar);

		mImgLeft = new ImageView(getContext());
		RelativeLayout.LayoutParams mImgLeftParam = new RelativeLayout.LayoutParams(
					RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.MATCH_PARENT);
		mImgLeftParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		mImgLeftParam.addRule(RelativeLayout.CENTER_VERTICAL);
		mImgLeft.setLayoutParams(mImgLeftParam);
		mImgLeft.setPadding(DeviceUtil.dp2Px(getContext(), 10), 0, DeviceUtil.dp2Px(getContext(), 10), 0);
		mImgLeft.setImageDrawable(a.getDrawable(R.styleable.TitleBar_left_img));
		if(a.getDrawable(R.styleable.TitleBar_left_imgbackground) != null){
			mImgLeft.setBackgroundDrawable(a.getDrawable(R.styleable.TitleBar_left_imgbackground));
		}
		
		mImgRight = new ImageView(getContext());
		RelativeLayout.LayoutParams mImgRightParam = new RelativeLayout.LayoutParams(
					RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.MATCH_PARENT);
		mImgRightParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		mImgRightParam.addRule(RelativeLayout.CENTER_VERTICAL);
		mImgRight.setLayoutParams(mImgRightParam);
		mImgRight.setPadding(DeviceUtil.dp2Px(getContext(), 10), 0, DeviceUtil.dp2Px(getContext(), 10), 0);
		mImgRight.setImageDrawable(a.getDrawable(R.styleable.TitleBar_left_img));
		if(a.getDrawable(R.styleable.TitleBar_right_imgbackground) != null){
			mImgRight.setBackgroundDrawable(a.getDrawable(R.styleable.TitleBar_right_imgbackground));
		}
		
		mTvTitle = new TextView(getContext());
		RelativeLayout.LayoutParams mTvTitleParam = new RelativeLayout.LayoutParams(
					RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.WRAP_CONTENT);
		mTvTitleParam.addRule(RelativeLayout.CENTER_HORIZONTAL);
		mTvTitleParam.addRule(RelativeLayout.CENTER_VERTICAL);
		mTvTitle.setLayoutParams(mTvTitleParam);
		mTvTitle.setText(a.getString(R.styleable.TitleBar_title));
		mTvTitle.setTextColor(a.getColor(R.styleable.TitleBar_titleColor, R.color.greenblue));
		mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, a.getDimension(R.styleable.TitleBar_titleSize, 18));
		addView(mImgLeft);
		addView(mImgRight);
		addView(mTvTitle);
		
		a.recycle();
	}
	
	/**
	 * 设置左边ImageView的可见性
	 * @param visibility
	 */
	public void setLeftVisibility(int visibility){
		this.mImgLeft.setVisibility(visibility);
	}
	
	/**
	 * 设置右边ImageView的可见性
	 * @param visibility
	 */
	public void setRightVisibility(int visibility){
		this.mImgRight.setVisibility(visibility);
	}
	
	/**
	 * 设置左边ImageView的点击事件
	 * @param listener
	 */
	public void setLeftClick(View.OnClickListener listener){
		this.mLeftClickListener = listener;
		this.mImgLeft.setOnClickListener(mLeftClickListener);
	}
	
	/**
	 * 设置右边ImageView的点击事件
	 * @param listener
	 */
	public void setRightClick(View.OnClickListener listener){
		this.mRightClickListener = listener;
		this.mImgRight.setOnClickListener(mRightClickListener);
	}
	
	/**
	 * 标题栏文字
	 * @param strText
	 */
	public void setText(String strText){
		this.mTvTitle.setText(strText);
	}
	
	/**
	 * 标题栏文字
	 * @param strResId
	 */
	public void setText(int strResId){
		this.mTvTitle.setText(strResId);
	}

}

/**
 * 功能与 support.v4 包中的同名类完全一致,抄过来是为了支持  android.app.Fragment
 * @author warren
 * @date 2015年1月1日
 */
public abstract class FragmentPagerAdapter extends PagerAdapter {

	private static final String TAG = "FragmentPagerAdapter";
	private static final boolean DEBUG = false;

	private final FragmentManager mFragmentManager;
	private FragmentTransaction mCurTransaction = null;
	private Fragment mCurrentPrimaryItem = null;

	public FragmentPagerAdapter(FragmentManager fm) {
		mFragmentManager = fm;
	}

	/**
	 * Return the Fragment associated with a specified position.
	 */
	public abstract Fragment getItem(int position);

	@Override
	public void startUpdate(ViewGroup container) {
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		if (mCurTransaction == null) {
			mCurTransaction = mFragmentManager.beginTransaction();
		}

		final long itemId = getItemId(position);

		// Do we already have this fragment?
		String name = makeFragmentName(container.getId(), itemId);
		Fragment fragment = mFragmentManager.findFragmentByTag(name);
		if (fragment != null) {
			if (DEBUG) {
				Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
			}
			mCurTransaction.attach(fragment);
		} else {
			fragment = getItem(position);
			if (DEBUG) {
				Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
			}
			mCurTransaction.add(container.getId(), fragment,
						makeFragmentName(container.getId(), itemId));
		}
		if (fragment != mCurrentPrimaryItem) {
			fragment.setMenuVisibility(false);
			fragment.setUserVisibleHint(false);
		}

		return fragment;
	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		if (mCurTransaction == null) {
			mCurTransaction = mFragmentManager.beginTransaction();
		}
		if (DEBUG) {
			Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v="
						+ ((Fragment) object).getView());
		}
		mCurTransaction.detach((Fragment) object);
	}

	@Override
	public void setPrimaryItem(ViewGroup container, int position, Object object) {
		Fragment fragment = (Fragment) object;
		if (fragment != mCurrentPrimaryItem) {
			if (mCurrentPrimaryItem != null) {
				mCurrentPrimaryItem.setMenuVisibility(false);
				mCurrentPrimaryItem.setUserVisibleHint(false);
			}
			if (fragment != null) {
				fragment.setMenuVisibility(true);
				fragment.setUserVisibleHint(true);
			}
			mCurrentPrimaryItem = fragment;
		}
	}

	@Override
	public void finishUpdate(ViewGroup container) {
		if (mCurTransaction != null) {
			mCurTransaction.commitAllowingStateLoss();
			mCurTransaction = null;
			mFragmentManager.executePendingTransactions();
		}
	}

	@Override
	public boolean isViewFromObject(View view, Object object) {
		return ((Fragment) object).getView() == view;
	}

	@Override
	public Parcelable saveState() {
		return null;
	}

	@Override
	public void restoreState(Parcelable state, ClassLoader loader) {
	}

	/**
	 * Return a unique identifier for the item at the given position.
	 * 

* The default implementation returns the given position. Subclasses should * override this method if the positions of items can change. *

* @param position Position within this adapter * @return Unique identifier for the item at position */ public long getItemId(int position) { return position; } private static String makeFragmentName(int viewId, long id) { return "android:switcher:" + viewId + ":" + id; } }

/**
 * 英雄列表
 * @author warren
 * @date 2015年1月1日
 */
public class HeroListActivity extends Activity {

	private TitleBar mTb;
	private ViewPagerIndicator mVpIndicator;
	private ViewPager mVp;
	private FragmentPagerAdapter mAdapter;
	
	private List mLstHeroFree;
	private List mLstHeroLike;
	private List mLstHeroAll;
	
	private boolean[] mArrFinish = new boolean[3];
	
	private List mLstTitles = Arrays.asList("免费", "收藏", "全部");

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_herolist);
		
		initCtrl();
	}

	private void initCtrl() {
		
		mTb = (TitleBar) findViewById(R.id.titlebar);
		mVpIndicator = (ViewPagerIndicator) findViewById(R.id.vpindicator);
		mVp = (ViewPager) findViewById(R.id.vp);
		
		AppNetManager anm = AppContext.getApp().getNetManager();
		anm.get(URLUtil.getURL_HeroList("free"), new IListener() {
			
			@Override
			public void onCall(String strJson) {
				AppContext.getApp().getJsonManager().parse(strJson, FreeHeroList.class, new IListener() {

					@Override
					public void onCall(FreeHeroList t) {
						
						mArrFinish[0] = true;
						if (t == null) {
							return;
						}
						mLstHeroFree = t.getFree();
						checkStartInitFrags();
					}
				});
			}
		});
		
		mArrFinish[1] = true;
		
//		anm.get(URLUtil.getURL_HeroList("like"), new IListener() {
//			
//			@Override
//			public void onCall(String strJson) {
//				AppContext.getApp().getJsonManager().parse(strJson, FreeHeroList.class, new IListener() {
//
//					@Override
//					public void onCall(FreeHeroList t) {
//						
//						mArrFinish[1] = true;
//						
//						if (t == null) {
//							return;
//						}
//						mLstHeroLike = t.getFree();
//						checkStartInitFrags();
//					}
//				});
//			}
//		});
		
		anm.get(URLUtil.getURL_HeroList("all"), new IListener() {
			
			@Override
			public void onCall(String strJson) {
				AppContext.getApp().getJsonManager().parse(strJson, AllHeroList.class, new IListener() {

					@Override
					public void onCall(AllHeroList t) {
						
						mArrFinish[2] = true;
						if (t == null) {
							return;
						}
						mLstHeroAll = t.getAll();
						checkStartInitFrags();
					}
				});
			}
		});
		
		mTb.setLeftClick(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
	}
	
	/**
	 * 检查三个List都获取完毕后,更新页面,加载Fragment
	 */
	private void checkStartInitFrags(){
		
		if(mArrFinish[0] && mArrFinish[1] && mArrFinish[2]){
			
			if(mLstHeroFree == null){
				mLstHeroFree = new ArrayList();
			}
			if(mLstHeroLike == null){
				mLstHeroLike = new ArrayList();
			}
			if(mLstHeroAll == null){
				mLstHeroAll = new ArrayList();
			}
			
			final BaseGridFragment[] frags = new BaseGridFragment[3];
			frags[0] = new BaseGridFragment();
			frags[0].setLstHero(mLstHeroFree);
			frags[1] = new BaseGridFragment();
			frags[1].setLstHero(mLstHeroLike);
			frags[2] = new BaseGridFragment();
			frags[2].setLstHero(mLstHeroAll);
			
			
			mAdapter = new FragmentPagerAdapter(getFragmentManager()) {
				
				@Override
				public int getCount() {
					return 3;
				}
				
				@Override
				public Fragment getItem(int position) {
					return frags[position];
				}
			};
			mVp.setAdapter(mAdapter);
			mVpIndicator.setViewPager(mVp, 0);
			mVpIndicator.setTabItemTitles(mLstTitles);
			
		}
	}
	
}


/**
 * 基本的GridView Fragment
 * @author warren
 * @date 2015年1月1日
 */
public class BaseGridFragment extends BaseContentFragment {

	public static final String FRAGMENTNAME = "BaseGridFragment";
	public static final String EXTRA_JSON = "EXTRA_JSON";
	public static final String EXTRA_TYPE = "EXTRA_TYPE";
	public static final int DATATYPE_HERO = 1;
	public static final int DATATYPE_MATERIAL = 2;

	private View mVRoot;

	private GridView mGv;
	private BaseGridAdapter mAdapter;

	private List mLstHero;
	private List mLstMaterial;
	/**
	 * 0/1 : 英雄/物品
	 */
	private int mType;
	
	private List mLstSnt = new ArrayList();

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

		mVRoot = inflater.inflate(R.layout.fragment_gridonly, container, false);

		initCtrl();

		return mVRoot;
	}
	
	@Override
	public void onResume() {
		super.onResume();
		mAdapter.notifyDataSetChanged();
	}

	private void initCtrl() {

		mGv = (GridView) mVRoot.findViewById(R.id.gv);
		
		mGv.setNumColumns(4);
		
		mAdapter = new BaseGridAdapter(LayoutInflater.from(mVRoot.getContext()));
		mGv.setAdapter(mAdapter);

		mAdapter.setLstNetTools(mLstSnt, AppContext.getApp().getImgLoader(), null);
		mAdapter.setNumColumn(4);
		mAdapter.notifyDataSetChanged();
		
		
		mGv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView parent, View view, int position, long id) {
				
				if(mType == 0){
					openHeroDetailActivity(mLstHero.get(position).getEnName());
				} else {
					openMaterialDetail("" + mLstMaterial.get(position).getId());
				}
			}
		});
	}

	public void setLstHero(List lstHero) {
		this.mLstHero = lstHero;
		this.mType = 0;

		mLstSnt.clear();
		for (HeroSimple hero : this.mLstHero) {
			SimpleNetTool snt = new SimpleNetTool(URLUtil.getURL_HeroImg(hero.getEnName(),
						EnumDPI.DPI120x120), hero.getCnName());
			mLstSnt.add(snt);
		}
		
	}

	public void setLstMaterial(List lstMaterial) {
		
		this.mLstMaterial = lstMaterial;
		this.mType = 1;
		mLstSnt.clear();
		for (MaterialSimple material : this.mLstMaterial) {
			SimpleNetTool snt = new SimpleNetTool(URLUtil.getURL_ZBImg(material.getId(), EnumDPI.DPI64x64), material.getText());
			mLstSnt.add(snt);
		}
	}
	
	/**
	 * 打开英雄详情界面
	 * @param strHeroEnName
	 */
	private void openHeroDetailActivity(String strHeroEnName){
		
		Intent it = new Intent(getActivity(), HeroDetailActivity.class);
		it.putExtra(HeroDetailActivity.EXTRA_HEROENNAME, strHeroEnName);
		startActivity(it);
		getActivity().overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
	}
	
	/**
	 * 打开物品详情界面
	 * @param materialId
	 */
	private void openMaterialDetail(String materialId) {

		Intent it = new Intent(getActivity(), MaterialDetailActivity.class);
		it.putExtra(MaterialDetailActivity.EXTRA_MATERIALID, materialId);
		startActivity(it);
		getActivity().overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
	}
	

	@Override
	public String getName() {
		return FRAGMENTNAME;
	}

}



/**
 * 英雄详情
 * @author warren
 * @date 2015年1月2日
 */
public class HeroDetailActivity extends Activity {

	public static final String EXTRA_HEROENNAME = "EXTRA_HEROENNAME";

	private TitleBar mTb;
	private ImageView mImgHero;
	private TextView mTvHeroName;
	private TextView mTvTag;
	private TextView mTvPrice;
	private TextView mTvAtt;
	private TextView mTvAbilityDescription;

	private FrameLayout[] mArrFlAbility = new FrameLayout[5];
	private ImageView[] mArrImgAbility = new ImageView[5];
	private View[] mArrVAbility = new View[5];

	private LinearLayout mLlPartner;
	private ImageView mImgPartner1;
	private TextView mTvPartner1;
	private ImageView mImgPartner2;
	private TextView mTvPartner2;
	private RelativeLayout mRlPartnerViewMore;
	private TextView mTvExpandPartner;
	private boolean mIsExpandPartner = false;

	private LinearLayout mLlEnemy;
	private ImageView mImgEnemy1;
	private TextView mTvEnemy1;
	private ImageView mImgEnemy2;
	private TextView mTvEnemy2;
	private RelativeLayout mRlEnemyViewMore;
	private TextView mTvExpandEnemy;
	private boolean mIsExpandEnemy = false;

	private TextView mTvUse;
	private TextView mTvAnswerfor;

	private LinearLayout mLlData;
	private RelativeLayout mRlDataViewMore;
	private TextView mTvExpandData;
	private boolean mIsExpandDataView = false;

	private TextView mTvRank;
	private TextView mTvAttackDistance;
	private TextView mTvMovement;
	private TextView mTvBaseAttack;
	private TextView mTvBaseDefense;
	private TextView mTvBaseMona;
	private TextView mTvBaseHealth;
	private TextView mTvBaseBaoji;
	private TextView mTvMonaRegen;
	private TextView mTvHealthRegen;
	private TextView mTvMagicDefense;
	private SeekBar mSeekRank;

	private TextView mTvStory;
	private RelativeLayout mRlStoryViewMore;
	private TextView mTvExpandStory;
	private boolean mIsExpandStory = false;

	private String mStrHeroEnName;

	private Hero mHero;

	private String[] mArrAbilitysDes = new String[5];

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_herodetail);

		mStrHeroEnName = getIntent().getStringExtra(EXTRA_HEROENNAME);

		initCtrl();

		requestData();
	}

	private void initCtrl() {

		mTb = (TitleBar) findViewById(R.id.titlebar);
		mTb.setRightVisibility(View.GONE);

		mImgHero = (ImageView) findViewById(R.id.img_hero);
		mTvHeroName = (TextView) findViewById(R.id.tv_heroname);
		mTvTag = (TextView) findViewById(R.id.tv_tag);
		mTvPrice = (TextView) findViewById(R.id.tv_price);
		mTvAtt = (TextView) findViewById(R.id.tv_att);

		mArrFlAbility[0] = (FrameLayout) findViewById(R.id.fl_ability_1);
		mArrImgAbility[0] = (ImageView) findViewById(R.id.img_ability_1);
		mArrVAbility[0] = findViewById(R.id.v_ability_1);
		mArrFlAbility[1] = (FrameLayout) findViewById(R.id.fl_ability_2);
		mArrImgAbility[1] = (ImageView) findViewById(R.id.img_ability_2);
		mArrVAbility[1] = findViewById(R.id.v_ability_2);
		mArrFlAbility[2] = (FrameLayout) findViewById(R.id.fl_ability_3);
		mArrImgAbility[2] = (ImageView) findViewById(R.id.img_ability_3);
		mArrVAbility[2] = findViewById(R.id.v_ability_3);
		mArrFlAbility[3] = (FrameLayout) findViewById(R.id.fl_ability_4);
		mArrImgAbility[3] = (ImageView) findViewById(R.id.img_ability_4);
		mArrVAbility[3] = findViewById(R.id.v_ability_4);
		mArrFlAbility[4] = (FrameLayout) findViewById(R.id.fl_ability_5);
		mArrImgAbility[4] = (ImageView) findViewById(R.id.img_ability_5);
		mArrVAbility[4] = findViewById(R.id.v_ability_5);

		mTvAbilityDescription = (TextView) findViewById(R.id.tv_ability_description);

		mLlPartner = (LinearLayout) findViewById(R.id.ll_partner_content);
		mImgPartner1 = (ImageView) findViewById(R.id.img_partner_1);
		mTvPartner1 = (TextView) findViewById(R.id.tv_partner_1);
		mImgPartner2 = (ImageView) findViewById(R.id.img_partner_2);
		mTvPartner2 = (TextView) findViewById(R.id.tv_partner_2);
		mRlPartnerViewMore = (RelativeLayout) findViewById(R.id.rl_viewmorepartner);
		mTvExpandPartner = (TextView) findViewById(R.id.tv_viewmorepartner);

		mLlEnemy = (LinearLayout) findViewById(R.id.ll_enemy_content);
		mImgEnemy1 = (ImageView) findViewById(R.id.img_enemy_1);
		mTvEnemy1 = (TextView) findViewById(R.id.tv_enemy_1);
		mImgEnemy2 = (ImageView) findViewById(R.id.img_enemy_2);
		mTvEnemy2 = (TextView) findViewById(R.id.tv_enemy_2);
		mRlEnemyViewMore = (RelativeLayout) findViewById(R.id.rl_viewmoreenemy);
		mTvExpandEnemy = (TextView) findViewById(R.id.tv_viewmoreenemy);

		mTvUse = (TextView) findViewById(R.id.tv_use);
		mTvAnswerfor = (TextView) findViewById(R.id.tv_answerfor);

		mLlData = (LinearLayout) findViewById(R.id.ll_data);
		// mTvData = findViewById(R.id.tv_)
		mRlDataViewMore = (RelativeLayout) findViewById(R.id.rl_viewmoredata);
		mTvExpandData = (TextView) findViewById(R.id.tv_viewmoredata);

		mTvRank = (TextView) findViewById(R.id.tv_rank);
		mTvAttackDistance = (TextView) findViewById(R.id.tv_attackdistance);
		mTvMovement = (TextView) findViewById(R.id.tv_movement);
		mTvBaseAttack = (TextView) findViewById(R.id.tv_baseattack);
		mTvBaseDefense = (TextView) findViewById(R.id.tv_basedefense);
		mTvBaseMona = (TextView) findViewById(R.id.tv_basemona);
		mTvBaseHealth = (TextView) findViewById(R.id.tv_basehealth);
		mTvBaseBaoji = (TextView) findViewById(R.id.tv_baojirate);
		mTvMonaRegen = (TextView) findViewById(R.id.tv_monaregen);
		mTvHealthRegen = (TextView) findViewById(R.id.tv_healthregen);
		mTvMagicDefense = (TextView) findViewById(R.id.tv_magicdefense);
		mSeekRank = (SeekBar) findViewById(R.id.seekRank);

		mTvStory = (TextView) findViewById(R.id.tv_story);
		mRlStoryViewMore = (RelativeLayout) findViewById(R.id.rl_viewmorestory);
		mTvExpandStory = (TextView) findViewById(R.id.tv_viewmorestory);

		mTb.setLeftClick(new OnClickListener() {

			@Override
			public void onClick(View v) {
				finish();
			}
		});

		
	}

	/**
	 * 选择技能
	 * @param index
	 */
	private void selectAbitlity(int index) {

		mTvAbilityDescription.setText(mArrAbilitysDes[index] == null ? "" : mArrAbilitysDes[index]);
		for (int i = 0; i < 5; i++) {

			if (i == index) {
				mArrVAbility[i].setVisibility(View.GONE);
			} else {
				mArrVAbility[i].setVisibility(View.VISIBLE);
			}

		}
	}

	/**
	 * 请求数据
	 */
	private void requestData() {

		AppContext.getApp().getNetManager()
					.get(URLUtil.getURL_HeroDetail(mStrHeroEnName), new IListener() {

						@Override
						public void onCall(String t) {

							if (t == null || t.length() == 0) {
								Toast.makeText(HeroDetailActivity.this, "没有请求到数据",
											Toast.LENGTH_SHORT).show();
								return;
							}

							t = checkData(t);

							AppContext.getApp().getJsonManager()
										.parse(t, Hero.class, new IListener() {

											@Override
											public void onCall(Hero t) {
												mHero = t;
												setView();
											}
										});

						}
					});
	}

	/**
	 * 请求到的英雄详情Json中技能的字段名格式是 Taric_Q ,不便于转换为固定格式的bean,这里处理矫正一下
	 * @param strJsonHero
	 * @return
	 */
	private String checkData(String strJsonHero) {

		strJsonHero = strJsonHero.replace(mStrHeroEnName + "_B", "b");
		strJsonHero = strJsonHero.replace(mStrHeroEnName + "_Q", "q");
		strJsonHero = strJsonHero.replace(mStrHeroEnName + "_W", "w");
		strJsonHero = strJsonHero.replace(mStrHeroEnName + "_E", "e");
		strJsonHero = strJsonHero.replace(mStrHeroEnName + "_R", "r");
		return strJsonHero;
	}

	/**
	 * 根据请求得到的数据设置视图
	 */
	private void setView() {

		ImageLoader imgLoader = AppContext.getApp().getImgLoader();

		imgLoader.displayImage(URLUtil.getURL_HeroImg(mStrHeroEnName, EnumDPI.DPI120x120), mImgHero);

		imgLoader.displayImage(
					URLUtil.getURL_HeroAbilityImg(mStrHeroEnName, EnumAbility.B, EnumDPI.DPI64x64),
					mArrImgAbility[0]);
		imgLoader.displayImage(
					URLUtil.getURL_HeroAbilityImg(mStrHeroEnName, EnumAbility.Q, EnumDPI.DPI64x64),
					mArrImgAbility[1]);
		imgLoader.displayImage(
					URLUtil.getURL_HeroAbilityImg(mStrHeroEnName, EnumAbility.W, EnumDPI.DPI64x64),
					mArrImgAbility[2]);
		imgLoader.displayImage(
					URLUtil.getURL_HeroAbilityImg(mStrHeroEnName, EnumAbility.E, EnumDPI.DPI64x64),
					mArrImgAbility[3]);
		imgLoader.displayImage(
					URLUtil.getURL_HeroAbilityImg(mStrHeroEnName, EnumAbility.R, EnumDPI.DPI64x64),
					mArrImgAbility[4]);
		imgLoader.displayImage(URLUtil.getURL_HeroImg(mHero.getLike().get(0).get("partner"),
					EnumDPI.DPI120x120), mImgPartner1);
		imgLoader.displayImage(URLUtil.getURL_HeroImg(mHero.getLike().get(1).get("partner"),
					EnumDPI.DPI120x120), mImgPartner2);
		imgLoader.displayImage(URLUtil.getURL_HeroImg(mHero.getHate().get(0).get("partner"),
					EnumDPI.DPI120x120), mImgEnemy1);
		imgLoader.displayImage(URLUtil.getURL_HeroImg(mHero.getHate().get(1).get("partner"),
					EnumDPI.DPI120x120), mImgEnemy2);

		String strPrice = "金" + mHero.getPrice().split(",")[0] + "券"
					+ mHero.getPrice().split(",")[1];
		String strAbility = "攻" + mHero.getRatingAttack() + " 法" + mHero.getRatingMagic() + " 防"
					+ mHero.getRatingDefense() + " 难" + mHero.getRatingDifficulty();

		mTvHeroName.setText(mHero.getTitle());
		mTvTag.setText(mHero.getTags());
		mTvPrice.setText(strPrice);
		mTvAtt.setText(strAbility);

		mTvPartner1.setText(mHero.getLike().get(0).get("des"));
		mTvPartner2.setText(mHero.getLike().get(1).get("des"));
		mTvEnemy1.setText(mHero.getHate().get(0).get("des"));
		mTvEnemy2.setText(mHero.getHate().get(1).get("des"));

		mTvUse.setText(mHero.getTips());
		mTvAnswerfor.setText(mHero.getOpponentTips());

		mTvStory.setText(mHero.getDescription());

		mArrAbilitysDes[0] = generateAbilityDescription(mHero.getB());
		mArrAbilitysDes[1] = generateAbilityDescription(mHero.getQ());
		mArrAbilitysDes[2] = generateAbilityDescription(mHero.getW());
		mArrAbilitysDes[3] = generateAbilityDescription(mHero.getE());
		mArrAbilitysDes[4] = generateAbilityDescription(mHero.getR());

		selectAbitlity(0);

		for (int i = 0; i < 5; i++) {
			final int iIn = i;
			mArrFlAbility[i].setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					selectAbitlity(iIn);
				}
			});
		}
		
		mImgPartner1.setOnClickListener(new OnHeroClickListener());
		mImgPartner2.setOnClickListener(new OnHeroClickListener());
		mImgEnemy1.setOnClickListener(new OnHeroClickListener());
		mImgEnemy2.setOnClickListener(new OnHeroClickListener());
		
		
		mRlPartnerViewMore.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mIsExpandPartner) {
					mIsExpandPartner = false;
					mLlPartner.setLayoutParams(new LinearLayout.LayoutParams(
								LinearLayout.LayoutParams.MATCH_PARENT, DeviceUtil.dp2Px(
											HeroDetailActivity.this, 60)));
					mTvExpandPartner.setText("点击查看更多");
				} else {
					mIsExpandPartner = true;
					mLlPartner.setLayoutParams(new LinearLayout.LayoutParams(
								LinearLayout.LayoutParams.MATCH_PARENT,
								LinearLayout.LayoutParams.WRAP_CONTENT));
					mTvExpandPartner.setText("点击隐藏");
				}
			}
		});

		mRlEnemyViewMore.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mIsExpandEnemy) {
					mIsExpandEnemy = false;
					mLlEnemy.setLayoutParams(new LinearLayout.LayoutParams(
								LinearLayout.LayoutParams.MATCH_PARENT, DeviceUtil.dp2Px(
											HeroDetailActivity.this, 60)));
					mTvExpandEnemy.setText("点击查看更多");
				} else {
					mIsExpandEnemy = true;
					mLlEnemy.setLayoutParams(new LinearLayout.LayoutParams(
								LinearLayout.LayoutParams.MATCH_PARENT,
								LinearLayout.LayoutParams.WRAP_CONTENT));
					mTvExpandEnemy.setText("点击隐藏");
				}
			}
		});

		mRlStoryViewMore.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mIsExpandStory) {
					mIsExpandStory = false;
					mTvStory.setVisibility(View.GONE);
					mTvExpandStory.setText("点击查看更多");
				} else {
					mIsExpandStory = true;
					mTvStory.setVisibility(View.VISIBLE);
					mTvExpandStory.setText("点击隐藏");
				}
			}
		});

		mRlDataViewMore.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mIsExpandDataView) {
					mIsExpandDataView = false;
					mLlData.setVisibility(View.GONE);
					mTvExpandData.setText("点击查看更多");
				} else {
					mIsExpandDataView = true;
					mLlData.setVisibility(View.VISIBLE);
					mTvExpandData.setText("点击隐藏");
				}
			}
		});

		
		mTvRank.setText("1");
		mTvAttackDistance.setText(mHero.getRange());
		mTvBaseAttack.setText(mHero.getAttackBase());
		mTvMovement.setText(mHero.getMoveSpeed());
		mTvBaseDefense.setText(mHero.getArmorBase());
		mTvBaseMona.setText(mHero.getManaBase());
		mTvBaseHealth.setText(mHero.getHealthBase());
		mTvBaseBaoji.setText(mHero.getCriticalChanceBase());
		mTvMonaRegen.setText(mHero.getManaRegenBase());
		mTvHealthRegen.setText(mHero.getHealthRegenBase());
		mTvMagicDefense.setText(mHero.getMagicResistBase());

		mSeekRank.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

				mTvRank.setText("" + progress);
				mTvAttackDistance.setText(mHero.getRange());
				mTvBaseAttack.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getAttackBase())
										+ Double.parseDouble(mHero.getAttackLevel()) * progress, 1));
				mTvMovement.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getMoveSpeed()), 1));
				mTvBaseDefense.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getArmorBase())
										+ Double.parseDouble(mHero.getArmorLevel()) * progress, 1));
				mTvBaseMona.setText(StringUtils.keepDecimal(Double.parseDouble(mHero.getManaBase())
							+ Double.parseDouble(mHero.getManaLevel()) * progress, 1));
				mTvBaseHealth.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getHealthBase())
										+ Double.parseDouble(mHero.getHealthLevel()) * progress, 1));
				mTvBaseBaoji.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getCriticalChanceBase())
										+ Double.parseDouble(mHero.getCriticalChanceLevel())
										* progress, 1));
				mTvMonaRegen.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getManaRegenBase())
										+ Double.parseDouble(mHero.getManaRegenLevel()) * progress,
							1));
				mTvHealthRegen.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getHealthRegenBase())
										+ Double.parseDouble(mHero.getHealthRegenLevel())
										* progress, 1));
				mTvMagicDefense.setText(StringUtils.keepDecimal(
							Double.parseDouble(mHero.getMagicResistBase())
										+ Double.parseDouble(mHero.getMagicResistLevel())
										* progress, 1));
			}
		});

		mSeekRank.setProgress(1);
	}

	/**
	 * 构造英雄技能的描述
	 * @param ability
	 * @return
	 */
	private String generateAbilityDescription(HeroAbility ability) {

		StringBuilder sbDescription = new StringBuilder();
		sbDescription.append(ability.getName() + "\n");
		sbDescription.append("消耗:" + ability.getCost() + "\n");
		sbDescription.append("冷却:" + ability.getCooldown() + "\n");
		sbDescription.append("范围:" + ability.getRange() + "\n");
		sbDescription.append("效果:" + ability.getDescription());

		return sbDescription.toString();
	}
	
	/**
	 * 搭档或克制 英雄头像点击事件
	 * @author warren
	 * @date 2015年1月2日
	 */
	class OnHeroClickListener implements View.OnClickListener{

		@Override
		public void onClick(View v) {
			
			String strHeroName = "";
			
			switch (v.getId()) {
			case R.id.img_partner_1:
				strHeroName = mHero.getLike().get(0).get("partner");
				break;
			case R.id.img_partner_2:
				strHeroName = mHero.getLike().get(1).get("partner");
				break;
			case R.id.img_enemy_1:
				strHeroName = mHero.getHate().get(0).get("partner");
				break;
			case R.id.img_enemy_2:
				strHeroName = mHero.getHate().get(1).get("partner");
				break;
			default:
				break;
			}
			
			if(StringUtils.isNullOrZero(strHeroName)){
				Toast.makeText(HeroDetailActivity.this, "所请求的英雄不存在", Toast.LENGTH_SHORT).show();
				return;
			}
			
			Intent it = new Intent(HeroDetailActivity.this, HeroDetailActivity.class);
			it.putExtra(HeroDetailActivity.EXTRA_HEROENNAME, strHeroName);
			HeroDetailActivity.this.startActivity(it);
			overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
			
		}
		
	}

}

/**
 * 英雄详细信息Bean
 * @author warren
 * @date 2015年1月1日
 */
public class Hero {

	private String armorBase;
	private String armorLevel;
	private String attackBase;
	private String attackLevel;
	private String criticalChanceBase;
	private String criticalChanceLevel;
	private String danceVideoPath;
	private String description;
	private String displayName;
	private List> hate;
	private String healthBase;
	private String healthLevel;
	private String healthRegenBase;
	private String healthRegenLevel;
	private String iconPath;
	private String id;
	private List> like;
	private String magicResistBase;
	private String magicResistLevel;
	private String manaBase;
	private String manaLevel;
	private String manaRegenBase;
	private String manaRegenLevel;
	private String moveSpeed;
	private String name;
	private String opponentTips;
	private String portraitPath;
	private String price;
	private String quote;
	private String quoteAuthor;
	private String range;
	private String ratingAttack;
	private String ratingDefense;
	private String ratingDifficulty;
	private String ratingMagic;
	private String selectSoundPath;
	private String splashPath;
	private String tags;
	private HeroAbility b;
	private HeroAbility q;
	private HeroAbility w;
	private HeroAbility e;
	private HeroAbility r;
	private String tips;
	private String title;

	public Hero() {
	}

	/**
	 * @return the armorBase
	 */
	public String getArmorBase() {
		return armorBase;
	}

	/**
	 * @param armorBase the armorBase to set
	 */
	public void setArmorBase(String armorBase) {
		this.armorBase = armorBase;
	}

	/**
	 * @return the armorLevel
	 */
	public String getArmorLevel() {
		return armorLevel;
	}

	/**
	 * @param armorLevel the armorLevel to set
	 */
	public void setArmorLevel(String armorLevel) {
		this.armorLevel = armorLevel;
	}

	/**
	 * @return the attackBase
	 */
	public String getAttackBase() {
		return attackBase;
	}

	/**
	 * @param attackBase the attackBase to set
	 */
	public void setAttackBase(String attackBase) {
		this.attackBase = attackBase;
	}

	/**
	 * @return the attackLevel
	 */
	public String getAttackLevel() {
		return attackLevel;
	}

	/**
	 * @param attackLevel the attackLevel to set
	 */
	public void setAttackLevel(String attackLevel) {
		this.attackLevel = attackLevel;
	}

	/**
	 * @return the criticalChanceBase
	 */
	public String getCriticalChanceBase() {
		return criticalChanceBase;
	}

	/**
	 * @param criticalChanceBase the criticalChanceBase to set
	 */
	public void setCriticalChanceBase(String criticalChanceBase) {
		this.criticalChanceBase = criticalChanceBase;
	}

	/**
	 * @return the criticalChanceLevel
	 */
	public String getCriticalChanceLevel() {
		return criticalChanceLevel;
	}

	/**
	 * @param criticalChanceLevel the criticalChanceLevel to set
	 */
	public void setCriticalChanceLevel(String criticalChanceLevel) {
		this.criticalChanceLevel = criticalChanceLevel;
	}

	/**
	 * @return the danceVideoPath
	 */
	public String getDanceVideoPath() {
		return danceVideoPath;
	}

	/**
	 * @param danceVideoPath the danceVideoPath to set
	 */
	public void setDanceVideoPath(String danceVideoPath) {
		this.danceVideoPath = danceVideoPath;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the displayName
	 */
	public String getDisplayName() {
		return displayName;
	}

	/**
	 * @param displayName the displayName to set
	 */
	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	/**
	 * @return the hate
	 */
	public List> getHate() {
		return hate;
	}

	/**
	 * @param hate the hate to set
	 */
	public void setHate(List> hate) {
		this.hate = hate;
	}

	/**
	 * @return the healthBase
	 */
	public String getHealthBase() {
		return healthBase;
	}

	/**
	 * @param healthBase the healthBase to set
	 */
	public void setHealthBase(String healthBase) {
		this.healthBase = healthBase;
	}

	/**
	 * @return the healthLevel
	 */
	public String getHealthLevel() {
		return healthLevel;
	}

	/**
	 * @param healthLevel the healthLevel to set
	 */
	public void setHealthLevel(String healthLevel) {
		this.healthLevel = healthLevel;
	}

	/**
	 * @return the healthRegenBase
	 */
	public String getHealthRegenBase() {
		return healthRegenBase;
	}

	/**
	 * @param healthRegenBase the healthRegenBase to set
	 */
	public void setHealthRegenBase(String healthRegenBase) {
		this.healthRegenBase = healthRegenBase;
	}

	/**
	 * @return the healthRegenLevel
	 */
	public String getHealthRegenLevel() {
		return healthRegenLevel;
	}

	/**
	 * @param healthRegenLevel the healthRegenLevel to set
	 */
	public void setHealthRegenLevel(String healthRegenLevel) {
		this.healthRegenLevel = healthRegenLevel;
	}

	/**
	 * @return the iconPath
	 */
	public String getIconPath() {
		return iconPath;
	}

	/**
	 * @param iconPath the iconPath to set
	 */
	public void setIconPath(String iconPath) {
		this.iconPath = iconPath;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the like
	 */
	public List> getLike() {
		return like;
	}

	/**
	 * @param like the like to set
	 */
	public void setLike(List> like) {
		this.like = like;
	}

	/**
	 * @return the magicResistBase
	 */
	public String getMagicResistBase() {
		return magicResistBase;
	}

	/**
	 * @param magicResistBase the magicResistBase to set
	 */
	public void setMagicResistBase(String magicResistBase) {
		this.magicResistBase = magicResistBase;
	}

	/**
	 * @return the magicResistLevel
	 */
	public String getMagicResistLevel() {
		return magicResistLevel;
	}

	/**
	 * @param magicResistLevel the magicResistLevel to set
	 */
	public void setMagicResistLevel(String magicResistLevel) {
		this.magicResistLevel = magicResistLevel;
	}

	/**
	 * @return the manaBase
	 */
	public String getManaBase() {
		return manaBase;
	}

	/**
	 * @param manaBase the manaBase to set
	 */
	public void setManaBase(String manaBase) {
		this.manaBase = manaBase;
	}

	/**
	 * @return the manaLevel
	 */
	public String getManaLevel() {
		return manaLevel;
	}

	/**
	 * @param manaLevel the manaLevel to set
	 */
	public void setManaLevel(String manaLevel) {
		this.manaLevel = manaLevel;
	}

	/**
	 * @return the manaRegenBase
	 */
	public String getManaRegenBase() {
		return manaRegenBase;
	}

	/**
	 * @param manaRegenBase the manaRegenBase to set
	 */
	public void setManaRegenBase(String manaRegenBase) {
		this.manaRegenBase = manaRegenBase;
	}

	/**
	 * @return the manaRegenLevel
	 */
	public String getManaRegenLevel() {
		return manaRegenLevel;
	}

	/**
	 * @param manaRegenLevel the manaRegenLevel to set
	 */
	public void setManaRegenLevel(String manaRegenLevel) {
		this.manaRegenLevel = manaRegenLevel;
	}

	/**
	 * @return the moveSpeed
	 */
	public String getMoveSpeed() {
		return moveSpeed;
	}

	/**
	 * @param moveSpeed the moveSpeed to set
	 */
	public void setMoveSpeed(String moveSpeed) {
		this.moveSpeed = moveSpeed;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the opponentTips
	 */
	public String getOpponentTips() {
		return opponentTips;
	}

	/**
	 * @param opponentTips the opponentTips to set
	 */
	public void setOpponentTips(String opponentTips) {
		this.opponentTips = opponentTips;
	}

	/**
	 * @return the portraitPath
	 */
	public String getPortraitPath() {
		return portraitPath;
	}

	/**
	 * @param portraitPath the portraitPath to set
	 */
	public void setPortraitPath(String portraitPath) {
		this.portraitPath = portraitPath;
	}

	/**
	 * @return the price
	 */
	public String getPrice() {
		return price;
	}

	/**
	 * @param price the price to set
	 */
	public void setPrice(String price) {
		this.price = price;
	}

	/**
	 * @return the quote
	 */
	public String getQuote() {
		return quote;
	}

	/**
	 * @param quote the quote to set
	 */
	public void setQuote(String quote) {
		this.quote = quote;
	}

	/**
	 * @return the quoteAuthor
	 */
	public String getQuoteAuthor() {
		return quoteAuthor;
	}

	/**
	 * @param quoteAuthor the quoteAuthor to set
	 */
	public void setQuoteAuthor(String quoteAuthor) {
		this.quoteAuthor = quoteAuthor;
	}

	/**
	 * @return the range
	 */
	public String getRange() {
		return range;
	}

	/**
	 * @param range the range to set
	 */
	public void setRange(String range) {
		this.range = range;
	}

	/**
	 * @return the ratingAttack
	 */
	public String getRatingAttack() {
		return ratingAttack;
	}

	/**
	 * @param ratingAttack the ratingAttack to set
	 */
	public void setRatingAttack(String ratingAttack) {
		this.ratingAttack = ratingAttack;
	}

	/**
	 * @return the ratingDefense
	 */
	public String getRatingDefense() {
		return ratingDefense;
	}

	/**
	 * @param ratingDefense the ratingDefense to set
	 */
	public void setRatingDefense(String ratingDefense) {
		this.ratingDefense = ratingDefense;
	}

	/**
	 * @return the ratingDifficulty
	 */
	public String getRatingDifficulty() {
		return ratingDifficulty;
	}

	/**
	 * @param ratingDifficulty the ratingDifficulty to set
	 */
	public void setRatingDifficulty(String ratingDifficulty) {
		this.ratingDifficulty = ratingDifficulty;
	}

	/**
	 * @return the ratingMagic
	 */
	public String getRatingMagic() {
		return ratingMagic;
	}

	/**
	 * @param ratingMagic the ratingMagic to set
	 */
	public void setRatingMagic(String ratingMagic) {
		this.ratingMagic = ratingMagic;
	}

	/**
	 * @return the selectSoundPath
	 */
	public String getSelectSoundPath() {
		return selectSoundPath;
	}

	/**
	 * @param selectSoundPath the selectSoundPath to set
	 */
	public void setSelectSoundPath(String selectSoundPath) {
		this.selectSoundPath = selectSoundPath;
	}

	/**
	 * @return the splashPath
	 */
	public String getSplashPath() {
		return splashPath;
	}

	/**
	 * @param splashPath the splashPath to set
	 */
	public void setSplashPath(String splashPath) {
		this.splashPath = splashPath;
	}

	/**
	 * @return the tags
	 */
	public String getTags() {
		return tags;
	}

	/**
	 * @param tags the tags to set
	 */
	public void setTags(String tags) {
		this.tags = tags;
	}


	/**
	 * @return the b
	 */
	public HeroAbility getB() {
		return b;
	}

	/**
	 * @param b the b to set
	 */
	public void setB(HeroAbility b) {
		this.b = b;
	}

	/**
	 * @return the q
	 */
	public HeroAbility getQ() {
		return q;
	}

	/**
	 * @param q the q to set
	 */
	public void setQ(HeroAbility q) {
		this.q = q;
	}

	/**
	 * @return the w
	 */
	public HeroAbility getW() {
		return w;
	}

	/**
	 * @param w the w to set
	 */
	public void setW(HeroAbility w) {
		this.w = w;
	}

	/**
	 * @return the e
	 */
	public HeroAbility getE() {
		return e;
	}

	/**
	 * @param e the e to set
	 */
	public void setE(HeroAbility e) {
		this.e = e;
	}

	/**
	 * @return the r
	 */
	public HeroAbility getR() {
		return r;
	}

	/**
	 * @param r the r to set
	 */
	public void setR(HeroAbility r) {
		this.r = r;
	}

	/**
	 * @return the tips
	 */
	public String getTips() {
		return tips;
	}

	/**
	 * @param tips the tips to set
	 */
	public void setTips(String tips) {
		this.tips = tips;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Hero [armorBase=" + armorBase + ", armorLevel=" + armorLevel + ", attackBase="
					+ attackBase + ", attackLevel=" + attackLevel + ", criticalChanceBase="
					+ criticalChanceBase + ", criticalChanceLevel=" + criticalChanceLevel
					+ ", danceVideoPath=" + danceVideoPath + ", description=" + description
					+ ", displayName=" + displayName + ", hate=" + hate + ", healthBase="
					+ healthBase + ", healthLevel=" + healthLevel + ", healthRegenBase="
					+ healthRegenBase + ", healthRegenLevel=" + healthRegenLevel + ", iconPath="
					+ iconPath + ", id=" + id + ", like=" + like + ", magicResistBase="
					+ magicResistBase + ", magicResistLevel=" + magicResistLevel + ", manaBase="
					+ manaBase + ", manaLevel=" + manaLevel + ", manaRegenBase=" + manaRegenBase
					+ ", manaRegenLevel=" + manaRegenLevel + ", moveSpeed=" + moveSpeed + ", name="
					+ name + ", opponentTips=" + opponentTips + ", portraitPath=" + portraitPath
					+ ", price=" + price + ", quote=" + quote + ", quoteAuthor=" + quoteAuthor
					+ ", range=" + range + ", ratingAttack=" + ratingAttack + ", ratingDefense="
					+ ratingDefense + ", ratingDifficulty=" + ratingDifficulty + ", ratingMagic="
					+ ratingMagic + ", selectSoundPath=" + selectSoundPath + ", splashPath="
					+ splashPath + ", tags=" + tags + ", B=" + b + ", Q=" + q + ", W=" + w + ", E="
					+ e + ", R=" + r + ", tips=" + tips + ", title=" + title + "]";
	}
}


/**
 * 英雄技能Bean
 * @author warren
 * @date 2015年1月1日
 */
public class HeroAbility {
	private String cooldown;
	private String cost;
	private String description;
	private String effect;
	private String id;
	private String name;
	private String range;
	
	public HeroAbility() {
	}


	/**
	 * @return the cooldown
	 */
	public String getCooldown() {
		return cooldown;
	}

	/**
	 * @param cooldown the cooldown to set
	 */
	public void setCooldown(String cooldown) {
		this.cooldown = cooldown;
	}

	/**
	 * @return the cost
	 */
	public String getCost() {
		return cost;
	}

	/**
	 * @param cost the cost to set
	 */
	public void setCost(String cost) {
		this.cost = cost;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the effect
	 */
	public String getEffect() {
		return effect;
	}

	/**
	 * @param effect the effect to set
	 */
	public void setEffect(String effect) {
		this.effect = effect;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the range
	 */
	public String getRange() {
		return range;
	}

	/**
	 * @param range the range to set
	 */
	public void setRange(String range) {
		this.range = range;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "HeroAbility [cooldown=" + cooldown + ", cost=" + cost + ", description="
					+ description + ", effect=" + effect + ", id=" + id + ", name=" + name
					+ ", range=" + range + "]";
	}
}

package com.warren.lolbox.model.bean;


/**
 * 英雄简要信息Bean
 * @author warren
 * @date 2015年1月1日
 */
public class HeroSimple implements ISimple{

	private String cnName;
	private String enName;
	private String location;
	private String price;
	private String rating;
	private String tags;
	private String title;

	public HeroSimple() {
	}

	/**
	 * @return the cnName
	 */
	public String getCnName() {
		return cnName;
	}

	/**
	 * @param cnName the cnName to set
	 */
	public void setCnName(String cnName) {
		this.cnName = cnName;
	}

	/**
	 * @return the enName
	 */
	public String getEnName() {
		return enName;
	}

	/**
	 * @param enName the enName to set
	 */
	public void setEnName(String enName) {
		this.enName = enName;
	}

	/**
	 * @return the location
	 */
	public String getLocation() {
		return location;
	}

	/**
	 * @param location the location to set
	 */
	public void setLocation(String location) {
		this.location = location;
	}

	/**
	 * @return the price
	 */
	public String getPrice() {
		return price;
	}

	/**
	 * @param price the price to set
	 */
	public void setPrice(String price) {
		this.price = price;
	}

	/**
	 * @return the rating
	 */
	public String getRating() {
		return rating;
	}

	/**
	 * @param rating the rating to set
	 */
	public void setRating(String rating) {
		this.rating = rating;
	}

	/**
	 * @return the tags
	 */
	public String getTags() {
		return tags;
	}

	/**
	 * @param tags the tags to set
	 */
	public void setTags(String tags) {
		this.tags = tags;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "HeroSimple [cnName=" + cnName + ", enName=" + enName + ", location=" + location
					+ ", price=" + price + ", rating=" + rating + ", tags=" + tags + ", title="
					+ title + "]";
	}

}


/**
 * 英雄简要信息Bean
 * @author warren
 * @date 2015年1月1日
 */
public class HeroSimple implements ISimple{

	private String cnName;
	private String enName;
	private String location;
	private String price;
	private String rating;
	private String tags;
	private String title;

	public HeroSimple() {
	}

	/**
	 * @return the cnName
	 */
	public String getCnName() {
		return cnName;
	}

	/**
	 * @param cnName the cnName to set
	 */
	public void setCnName(String cnName) {
		this.cnName = cnName;
	}

	/**
	 * @return the enName
	 */
	public String getEnName() {
		return enName;
	}

	/**
	 * @param enName the enName to set
	 */
	public void setEnName(String enName) {
		this.enName = enName;
	}

	/**
	 * @return the location
	 */
	public String getLocation() {
		return location;
	}

	/**
	 * @param location the location to set
	 */
	public void setLocation(String location) {
		this.location = location;
	}

	/**
	 * @return the price
	 */
	public String getPrice() {
		return price;
	}

	/**
	 * @param price the price to set
	 */
	public void setPrice(String price) {
		this.price = price;
	}

	/**
	 * @return the rating
	 */
	public String getRating() {
		return rating;
	}

	/**
	 * @param rating the rating to set
	 */
	public void setRating(String rating) {
		this.rating = rating;
	}

	/**
	 * @return the tags
	 */
	public String getTags() {
		return tags;
	}

	/**
	 * @param tags the tags to set
	 */
	public void setTags(String tags) {
		this.tags = tags;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "HeroSimple [cnName=" + cnName + ", enName=" + enName + ", location=" + location
					+ ", price=" + price + ", rating=" + rating + ", tags=" + tags + ", title="
					+ title + "]";
	}

}

package com.warren.lolbox.model.bean;

import java.util.List;

/**
 * 所有英雄列表
 * @author warren
 * @date 2015年1月1日
 */
public class AllHeroList {
	
	private List all;
	
	public AllHeroList() {
		super();
	}

	/**
	 * @return the all
	 */
	public List getAll() {
		return all;
	}

	/**
	 * @param all the all to set
	 */
	public void setAll(List all) {
		this.all = all;
	}

	
}

package com.warren.lolbox.model.bean;

import java.util.List;

/**
 * 免费英雄列表
 * @author warren
 * @date 2015年1月1日
 */
public class FreeHeroList {
	
	private String desc;
	private List free;

	public FreeHeroList() {
		super();
	}

	/**
	 * @return the desc
	 */
	public String getDesc() {
		return desc;
	}

	/**
	 * @param desc the desc to set
	 */
	public void setDesc(String desc) {
		this.desc = desc;
	}

	/**
	 * @return the free
	 */
	public List getFree() {
		return free;
	}

	/**
	 * @param free the free to set
	 */
	public void setFree(List free) {
		this.free = free;
	}

}

英雄详情界面比较复杂,这里也先贴出来,这个界面不完善以后还得改。




    

    

        

            

                

                

                

                

                
            

            

            

                

                    

                    
                

                

                    

                    
                

                

                    

                    
                

                

                    

                    
                

                

                    

                    
                
            

            

            

            

                

                    

                        

                        
                    

                    

                    

                        

                        
                    
                

                

                

                    
                
            

            

            

                

                    

                        

                        
                    

                    

                    

                        

                        
                    
                

                

                

                    
                
            

            

            

            

            

            

            

                

                    

                        

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    

                    

                        

                        
                    
                

                

                

                    
                
            

            

            

                

                

                

                    
                
            
        
    


四、实现效果

一步步实现 仿制Android LOL多玩盒子(三) 英雄基础_第3张图片      一步步实现 仿制Android LOL多玩盒子(三) 英雄基础_第4张图片

你可能感兴趣的:(android,LOL盒子)