最新用空闲时间高仿了一下喜马拉雅FM这款APP,目前主要完成了发现栏目中的推荐页面。

效果演示

分析

+发现tab中有五个小分类,分别对应五个页面,所有在“发现”的控制器中使用了UIPageViewController来控制五个子控制器。

+从Charles抓出来的接口来看,“推荐”页面一共调用了三个接口,分别请求了推荐、热门、直播的内容,所以在这里选择了Reactivecocoa来实现接口的并发访问- (void)refreshDataSource {

@weakify(self);

RACSignal *signalRecommend = [RACSignal createSignal:^RACDisposable *(id subscriber) {

@strongify(self);

[self requestRecommendList:^{

[subscriber sendNext:nil];

}];

return nil;

}];

RACSignal *signalHotAndGuess = [RACSignal createSignal:^RACDisposable *(id subscriber) {

@strongify(self);

[self requestHotAndGuessList:^{

[subscriber sendNext:nil];

}];

return nil;

}];

RACSignal *signalLiving = [RACSignal createSignal:^RACDisposable *(id subscriber) {

@strongify(self);

[self requestLiving:^{

[subscriber sendNext:nil];

}];

return nil;

}];

[[RACSignal combineLatest:@[signalRecommend,signalHotAndGuess,signalLiving]] subscribeNext:^(id x) {

@strongify(self);

[(RACSubject *)self.updateContentSignal sendNext:nil];

}];

}

文章转自 耐心_朱迪的简书

+在“推荐”页面中有几个轮播图,仔细观察会发现它的轮播图一直想左转换,所以这里的轮播图片需要做一下特殊处理。以实现无限轮播的效果- (void)setModel:(XMLYFindFocusImagesModel *)model  {

_model = model;

[self.adverScrollView removeAllSubViews];

self.adverScrollView.contentSize = CGSizeMake(kScreenWidth * _model.list.count, 150);

//1.向scrollView中增加UIImageView的时候,需要在最后一张图片后面将第一张图片添加上去

for(NSInteger index = 0; index <= _model.list.count; index++)   {

//2.如果是最后一张图片,则放置第一张图片

XMLYFindFocusImageDetailModel \*detail = index == _model.list.count ? _model.list.firstObject : [_model.list objectAtIndex:index];

UIImageView \*imageView = [[UIImageView alloc] init];

imageView.frame = CGRectMake(kScreenWidth \* index, 0, kScreenWidth, 150);

[imageView yy_setImageWithURL:[NSURL URLWithString:detail.pic] options:YYWebImageOptionSetImageWithFadeAnimation];

[self.adverScrollView addSubview:imageView];

}

}

在轮播图滚动动画结束后需要做一下判断,如果当前滚动到了最后一张图片,则立即将scrollView的偏移调整到初始位置,这样一个无限轮播就完成了。- (void)scrollViewDidScroll:(UIScrollView \*)scrollView {

NSInteger curPage = self.adverScrollView.contentOffset.x / kScreenWidth;

if(curPage == self.model.list.count) {

[self.adverScrollView setContentOffset:CGPointMake(0, 0) animated:NO];

}

}

在有轮播图的地方肯定少不了定时器,如果将定时器直接放在cell中,就会因为cell的复用导致定时器出现问题,所有一般是将定时器放在控制器中。但是这样的话也带来一个问题,就是由于定时器的存在,如果要求定时器的生命周期和控制器相同(也就是在控制器dealloc的时候才取消定时器).这样的控制器是无法调用dealloc的,会造成控制器虽然已经退出但是定时器依然在正常工作。所以这里专门为控制器设计了一个定时器的单例帮助类,这样的话就可以在dealloc中去销毁所有的定时器。@interface XMLYFindRecommendHelper : NSObject

#pragma mark - Common

//生成帮助类单例

+ (instancetype)helper;

//销毁所有的定时器

- (void)destoryAllTimer;

#pragma mark - Live

//  开启为直播设置的定时器

- (void)startLiveTimer;

//销毁直播的定时器

- (void)destoryLiveTimer;

#pragma mark - Header

//开启头部的定时器

- (void)startHeadTimer;

//销毁头部的定时器

- (void)destoryHeaderTimer;

@end

在广播页面中,有一个根据当前时间显示不同的问候语的小功能。比如现在是早上6点钟,应该显示“早安*北京”。这里就需要用到NSDateFormatter,但是NSDateFormatter的比较消耗性能,所以我专门写了一个XMLYTimeHelper类来管理所有的时间转换操作。在这个类中对NSDateFormatter做了缓存处理,并使用dispatch_semaphore_t保证了线程安全。//根据字符串生成相应的NSDateFormatter,比如"yyyy-MM-dd HH:mm:ss"

static force_inline NSDateFormatter *XMLYDataCreateFormatter(NSString *string) {

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

formatter.dateFormat = string;

return formatter;

}

//用户直接调用此方法,传入"yyyy-MM-dd HH:mm:ss"这样的字符串生成NSDateFormatter

static force_inline NSDateFormatter *XMLYDateFormatter(NSString *string) {

//1.检查输入的合法性

if(!string || ![string isKindOfClass:[NSString class]] || string.length == 0) return nil;

//2.初始化单例参数

static CFMutableDictionaryRef cache;

static dispatch_semaphore_t lock;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

cache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

lock = dispatch_semaphore_create(1);

});

//3.加锁

dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);

//4.查询当前字符串是否已经存在相应的NSDateformatter

NSDateFormatter *formatter = CFDictionaryGetValue(cache, (__bridge const void *)(string));

//5.解锁

dispatch_semaphore_signal(lock);

//6.如果缓存中没有,则需要重新生成

if(!formatter) {

formatter = XMLYDataCreateFormatter(string);

//7.重新生成成功,存入缓存

if(formatter) {

dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);

CFDictionarySetValue(cache, (__bridge const void *)(string), (__bridge const void *)(formatter));

dispatch_semaphore_signal(lock);

}

}

return formatter;

}

android仿喜马拉雅APP状态栏,源码分享:高仿喜马拉雅FM相关推荐

  1. [Android源码]Android源码之高仿飞鸽传书WIFI热点搜索与创建(一)

    (本文详情来源:android源码 http://www.eoeandroid.com/thread-296427-1-1.html   转载请注明出处!)  [Android源码分享]飞鸽传书的An ...

  2. 企业级旅行App源码、高仿爱鲜蜂源码、iOS Arkit测距源码等

    iOS精选源码 用户发布信息的控件,发布评论,发布图片,发布视频 类似YouTube和脸谱网自定义视频效果 使用ARKit创建的贪吃蛇游戏 iOS ARkit 测量距离 源码 Swift高仿爱鲜蜂 一 ...

  3. Android源码之高仿爱奇艺

    Android源码之高仿爱奇艺  支持平台:Android   运行环境:Eclipse   开发语言:Java 下载地址:http://www.devstore.cn/code/info/306.h ...

  4. 急急急~!求一款源码~!背背恋Android约会交友APP完整源码(客户端+服务端)~!

    急急急!求一款源码!背背恋Android约会交友APP完整源码(客户端+服务端)~!

  5. github,源码,高仿 直播

    仿花田:相亲网站 意中人 已在GitHub上开源 从头开始写一款开源app上线,相互学习 SlideMenuControllerSwift swift实现双侧边栏菜单 StepView github ...

  6. 今日上新推荐源码,高仿微信社交,高仿拼多多商城

    Flutter社交App源码 介绍:利用 Flutter 来高仿微信(WeChat) 7.0.0+ App,代码规范惊为天人.注释详解令人发指.细节处理精益求精.核心功能配备文档.接近98%还原度的原 ...

  7. 【源码】H5+JS混合实现《Just Do 8》app游戏源码分享

    时间:15年6月 地点:上海 起因:台风被困家里24小时,实在无聊,写了这个小游戏 类型:混合开发入门 [github源码] https://github.com/zwwill/justdo8 [代码 ...

  8. 源码分享,仿英雄联盟对战游戏!

    源码介绍 这是一款类似英雄联盟的 5V5 实时对战游戏,同时支持 Linux 和  Windows 系统部署. 我们先来看下这个游戏的内容吧,这是在我机器上编译后运行的效果图: 登录界面 进入后台配置 ...

  9. flappy bird java源码_android高仿flappy bird源码

    [实例简介]android高仿flappy bird源码,可以在任何机型上完美运行,难度可以自己调整,适合新手,当做一个小项目练练手. [实例截图] [核心代码] package liqiang.fl ...

最新文章

  1. java c 序列化_Java 序列化
  2. JForum 的 SSO集成
  3. windoes server 关闭服务端口方法、漏洞补丁解决
  4. 这家获得谷歌投资的企业想把亚马逊挑下神坛
  5. EasyUI中菜单Menu的简单使用
  6. C++强制类型转换操作符 dynamic_cast
  7. 【Java数据库】使用JDBC操作MySQL数据库、Batch批处理 、事务的概念
  8. sqoop mysql 安装_Sqoop安装及验证_MySQL
  9. 160 - 28 CoSH.2
  10. 关于Paralle.For和Paralle.ForEach
  11. 辞旧迎新:2018年的分区你们建了吗?
  12. 项目实训第二周(车道线检测)
  13. 《深入浅出WPF》学习笔记之一
  14. Unity WebGL Input输入中文
  15. Altium Designer中PCB画多层板(4、6、8...层)
  16. 免费HTTP代理商如何
  17. EOS Wallet 操作
  18. Java视频教程(浙江大学翁恺)
  19. Postgresql通过docker进行高可用部署 pgpool-II
  20. Ajax实现跨域请求

热门文章

  1. 表格对角线两边打字_表格对角线两边打字_表格斜线一分为二怎么打字(excel斜杠分割表格打字)...
  2. 为什么专业领域里外行领导能让墙倒屋塌?
  3. 【Mysql】Mysql事务隔离界别及其实现原理
  4. K线类型识别—单K线之阳线
  5. mysql被自动关闭
  6. 2020年AR(增强现实)最新发展趋势
  7. 日期选择器(包含上、下午选择及年月日连选)
  8. 这家国产FPGA换道超车!强攻5G和AI市场!
  9. 关于PyTorch Geometric的安装及问题解决记录
  10. U-BOOT分析(二)之顶层Makefile文件(1)