文档章节

Android内存优化之封装九宫格

拉偶有所依
 拉偶有所依
发布于 2015/06/16 10:38
字数 990
阅读 426
收藏 6

随着市场上越来越多的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(开发日志)信息,一键优化减少加密后原包大小


© 著作权归作者所有

共有 人打赏支持
拉偶有所依
粉丝 28
博文 81
码字总数 138944
作品 0
长沙
私信 提问
加载中

评论(1)

郁林
郁林
安卓??!!
Android 开发人员必须掌握的 10 个开发工具

Android SDK 本身包含很多帮助开发人员设计、开发、测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具。 #1: Eclipse ADT Eclipse ADT 是 Eclipse 平台下用来开发 An...

红薯
2011/04/29
82.8K
21
开发人员必读,安卓开发工具知多少

安卓开发过程中需要用到各种工具,于是作为一名安卓开发人员,那么多工具,各种亚历山大啊,于是今天就给大家汇总了一下安卓开发工具,哪些是安卓开发中必须要用到。 1、Draw 9-Patch 这个九...

flyurt
2015/10/30
306
0
android利用Widget显示系统时间

老师让用imagebutton做一个九宫格,然后随便点击一个按钮,调用系统时间,开始计时,再次随便点击一次,计时结束,在通知栏显示这个时间,相当于一个计时器,我把九宫格做好了,就差这个了 ...

m堕落天使y
2012/05/21
1K
0
有用的HTML5 pattern属性

做手机页面时,遇到数字输入的键盘的问题,之前的做法只是一刀切的使用 type="tel",不过一直觉得九宫格的电话号码键盘上的英文字母太碍事了。于是想要尝试其它的实现方案,最终的结论却令人...

东东笔记
2018/07/27
0
0
android launcher3 修改文件夹为九宫格显示,文件夹里面可以左右滑动并分页显示

android launcher3 修改文件夹为九宫格显示,文件夹里面可以左右滑动并分页显示

seasons3333
2016/09/10
548
1

没有更多内容

加载失败,请刷新页面

加载更多

网络编程

第14天 网络编程 今日内容介绍  网络通信协议  UDP通信  TCP通信 今日学习目标  能够辨别UDP和TCP协议特点  能够说出UDP协议下两个常用类名称  能够说出TCP协议下两个常用类名称...

stars永恒
50分钟前
1
0
二进制相关

二进制 众所周知计算机使用的是二进制,数字的二进制是如何表示的呢? 实际就是逢二进一。比如 2 用二进制就是 10。那么根据此可以推算出 5的二进制等于 10*10+1 即为 101。 在计算机中,负数以...

NotFound403
昨天
3
0
day22:

1、写一个getinterface.sh 脚本可以接受选项[i,I],完成下面任务: 1)使用格式:getinterface.sh [-i interface | -I ip] 2)当用户使用-i选项时,显示指定网卡的IP地址;当用户使用-I选项...

芬野de博客
昨天
2
0
Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注。虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭借阿里中间件团队的背景,还是得到不少...

程序猿DD
昨天
4
0
Java并发编程:深入剖析ThreadLocal

ThreadLocal 的理解 ThreadLocal,很多地方叫线程本地变量,或线程本地存储。ThreadLocal为变量在每个线程中都创建了一个副本,每个线程可以访问自己内部的副本变量。===》解决的问题是线程间...

细节探索者
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部