Android内存优化之封装九宫格
随着市场上越来越多的APP上线,好多软件对手机的内存要求也是很大,所以我们在开发的时候一定要掌握如何去优化内存,将自己的APP尽可能优化。今天我们就一起看一下九宫格的优化。下面是软件的截图

1、为了达到更好的效果我们不用UITableView,首先我们要通过XIB自定义一个图片和文字如图:

2、自定义主视图JRMainScrollView,通过协议代理来实现功能,做法和UITableView类似,大家可以参考一下UITableView
首先:我们要定义数据源协议
<span style="font-family:Arial;font-size:14px;">//数据源协议
@protocol JRMainScrollDataSource <NSObject>
//获取总的数量
- (NSInteger) numberOfItems; //获取列的数量
- (NSInteger) numberOfColumsOfRow;
//获取item
- (UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger) index;
@end</span>
其次:我们要定义属性协议
<span style="font-family:Arial;font-size:14px;">//属性协议
@protocol JRMainScrollDelegate <NSObject>
@optional
//获取高度
- (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView; //获取宽度
- (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView; //获取间距
- (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type;
@end</span>
注意获取间距包括到左右的间距和上下的间距通过定义一个枚举实现
<span style="font-family:Arial;font-size:14px;">typedef enum{
kJRMainScrollItemLeftSpace,
kJRMainScrollItemTopSpace
} kJRMainScrollItemSpace;</span>
3、内部布局实现,计算出当前所有的frame,并且放入数组在此期间,用的的属性参数都需要从代理来获取,代码如下
<span style="font-family:Arial;font-size:14px;">//加载子视图
- (void)_loadSubViews{
//获取总个数和列数
NSInteger totalItems=[self.jrDataSource numberOfItems];
NSInteger colum=[self.jrDataSource numberOfColumsOfRow]; //获取宽度和高度
CGFloat itemWidth=[self.jrDelegate widthForItemAtView:self];
CGFloat itemHeigt=[self.jrDelegate heightForItemAtView:self]; //获取上下间距
CGFloat leftSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemLeftSpace];
CGFloat topSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemTopSpace]; CGFloat space=(kWidth-2*leftSpace-colum*itemWidth)/(colum-1)+itemWidth; for (int i=0;i<totalItems;i++) {
int clo=i%colum;
int row=i/colum;
CGRect frame=CGRectMake(leftSpace+clo*space, 20+row*(itemHeigt+topSpace), itemWidth, itemHeigt);
[self.array addObject:[NSValue valueWithCGRect:frame]];
}
self.contentSize=CGSizeMake(0, CGRectGetMaxY([[self.array lastObject] CGRectValue]));
self.showsVerticalScrollIndicator=NO; }</span>
4、判断当前的frame是不是在当前的屏幕可视范围之内,如果要是在的进行视图的渲染,如果不在不予理睬。
<span style="font-family:Arial;font-size:14px;">-(void)layoutSubviews{
[super layoutSubviews];
//循环便利获取在屏幕中的frame
for (int i=0;i<self.array.count;i++) {
UIView * tempView=(UIView *)self.current[@(i)];
CGRect rect=[self.array[i] CGRectValue];
if ([self isInScreenWith:rect]) {
if(!tempView){//字典里没有的才需要重重新加载
UIView *view=[self.jrDataSource mainScrollView:self itemAtIndex:i];
view.frame=rect;
[self.current setObject:view forKey:@(i)];
[self addSubview:view];
}
}else if(tempView){//如果存在字典而且不在视线内部的则移除
[self.current removeObjectForKey:@(i)];
[tempView removeFromSuperview];
[self.pool addObject:tempView];
}
}
//判断是不是在视野内部,其中有两种情况,Y值在屏幕内部,或者MAXY值在屏幕内部
- (BOOL) isInScreenWith:(CGRect) frame{
CGFloat setMiny=self.contentOffset.y;
CGFloat setMaxy=self.contentOffset.y+kHeight;
BOOL condition1=frame.origin.y>=setMiny&&frame.origin.y<=setMaxy;
BOOL condition2=CGRectGetMaxY(frame)>=setMiny&&CGRectGetMaxY(frame)<=setMaxy;
if(condition1||condition2){
return YES;
}
return NO;
}</span>
5、操作缓冲池重复利用对象
<span style="font-family:Arial;font-size:14px;">/** 存放frame*/
@property(nonatomic,strong) NSMutableArray * array;
/** 存放当前显示的对象*/
@property(nonatomic,strong) NSMutableDictionary * current;
/** 存放缓冲池对象*/
@property(nonatomic,strong) NSMutableSet * pool;
/**
* 获取重复利用的对象
*
* @param identy <#identy description#>
*
* @return <#return value description#>
*/
- (JRRectView *) dequeueReusedItemWithIdenty:(NSString *) identy{
JRRectView * view=[self.pool anyObject];
if (view!=nil) {
[self.pool removeObject:view];
}
return view;
}</span>
6、在主控制器加载视图并实现代理方法即可
<span style="font-family:Arial;font-size:14px;"> //加载所有数据
- (void) _loadSubviews{ //1 增加滚动视图
JRMainScrollView * mainScroll=[[JRMainScrollView alloc] initWithFrame:self.view.bounds];
mainScroll.jrDataSource=self;
mainScroll.jrDelegate=self;
[mainScroll reloadViews];
[self.view addSubview:mainScroll]; }
#pragma mark - 数据源方法
-(NSInteger)numberOfItems{
return 132;
} -(NSInteger) numberOfColumsOfRow{
return 3;
} -(UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger)index{ JRRectView *cell=[mainScrollView dequeueReusedItemWithIdenty:@"test"];
if (cell==nil) {
cell=[[[NSBundle mainBundle] loadNibNamed:@"rect" owner:nil options:nil] lastObject];
} cell.titleLabel.text=[NSString stringWithFormat:@"下载"];
NSString * imageName=[NSString stringWithFormat:@"%d",arc4random_uniform(20)+256];
UIImage *image=[UIImage imageNamed:imageName];
cell.image.image=image; return cell;
} #pragma mark - 代理方法 //获取高度
- (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView{
return 100;
} //获取宽度
- (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView{
return 90;
} //获取间距
- (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type{ if (type==kJRMainScrollItemLeftSpace) {
return 20;
}else if (type==kJRMainScrollItemTopSpace){
return 20;
}
return 20; }</span>
7、内存优化,除了上面6点,还要懂得源码的优化,一键清除Log(开发日志)信息,一键优化减少加密后原包大小
Android内存优化之封装九宫格的更多相关文章
- ANDROID内存优化——大汇总(转)
原文作者博客:转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! ANDROID内存优化(大汇总——上) 写在最前: 本文的思路主要借鉴了20 ...
- Android内存优化之——static使用篇(使用MAT工具进行分析)
这篇文章主要配套与Android内存优化之——static使用篇向大家介绍MAT工具的使用,我们分析的内存泄漏程序是上一篇文章中static的使用内存泄漏的比较不容易发现泄漏的第二情况和第三种情况—— ...
- ANDROID内存优化(大汇总——中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- Android内存优化大全(中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- 大礼包!ANDROID内存优化(大汇总)
写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上把网上搜集的各种内存零散知识点进行汇总.挑选.简化后整理而成. 所以我将本文定义为一个工具类的文章,如果你在A ...
- 【腾讯Bugly干货分享】Android内存优化总结&实践
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...
- Android内存优化(三)详解内存分析工具MAT
前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...
- Android内存优化1 了解java内存分配 1
开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...
- Android内存优化(二)DVM和ART的GC日志分析
相关文章 Android内存优化系列 Java虚拟机系列 前言 在Java虚拟机(三)垃圾标记算法与Java对象的生命周期这篇文章中,提到了Java虚拟机的GC日志.DVM和ART的GC日志与Java ...
随机推荐
- HDU 4350
最近这些天,确实很烦恼.因为发现自己好像无论怎么样努力,也赶不上那些强校的学生.不得不承认,我们是传统弱校了.停了有一周了,什么也不想写,不停的反思,到底自己在哪里比不上人.D说,那是因为自始至终你只 ...
- 串口通讯 ADC0804 数码管
#include<reg52.h> #include<stdio.h> #include<intrins.h> #define uchar unsigned cha ...
- Web Service学习-CXF开发Web Service实例demo(一)
Web Service是什么? Web Service不是框架.更甚至不是一种技术. 而是一种跨平台,跨语言的规范 Web Service解决什么问题: 为了解决不同平台,不同语言所编写的应用之间怎样 ...
- 运行shell命令
首先将shell命令命名为.sh文件 将上面的代码保存为test.sh.并 cd 到对应文件夹: chmod +x ./test.sh #使脚本具有运行权限 ./test.sh #运行脚本 假设报错/ ...
- cocos2d-x之浅析Hello World
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- tflearn中一些CNN RNN的例子
lstm.py # -*- coding: utf-8 -*- """ Simple example using LSTM recurrent neural networ ...
- 使用sed -i对文本字符串进行增删改查
sed是一个很好的文件处理工具,本身是一个管道命令,主要以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作.1. sed命令行格式sed [选项] [命令] 1.1 选项-n,使用安 ...
- 前端将图片二进制流显示在html端
工作中碰到的问题,在处理接口返回的验证码图片时,由于返回的是encode编码代码,在js端获取到数据之后,通过函数encodeURI()来进行解码,之后可以通过在src中设置来实现图片显示:
- js通过经纬度计算两点之间的距离
最近这几天在做地图的时候,获取到目的地经纬度和当前所在位置的经纬度,通过这几个参数,用js代码就能获取到这两点之间的直线距离: function (lat1, lng1, lat2, lng2) { ...
- 使用JS&jQuery改善用户体验
第一章 JavaScript基本语法 一.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&= ...