欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android中UIColletionView瀑布流布局實(shí)現(xiàn)思路以及封裝的實(shí)現(xiàn)

 更新時間:2024年04月09日 16:39:44   作者:Deft_MKJing宓珂璟  
本篇文章主要介紹了android中UIColletionView瀑布流布局實(shí)現(xiàn)思路以及封裝的實(shí)現(xiàn),具有一定的參考價值,有興趣的可以了解一下。<BR>

瀑布流實(shí)現(xiàn)思路

  • 第一種就是用ScrollView來進(jìn)行實(shí)現(xiàn),由于它不具備復(fù)用的功能,因此我們需要自己寫一套類似復(fù)用的模塊來進(jìn)行優(yōu)化
  • 第二種就是利用apple做好的復(fù)用模塊,自定義UIColletionLayout來實(shí)現(xiàn)瀑布流,想想也是第二種實(shí)現(xiàn)起來更快更優(yōu),OK,封裝一個小小的框架來試試

默認(rèn)兩列 

其他案例

  

上面的動畫切換布局也是自定義UICollectionLayout來進(jìn)行布局的,簡單的靜態(tài)圖片布局展示其實(shí)就重寫幾個方法就可以了

1.prepareLayout 每次重新刷新collectionView的時候會調(diào)用一次,做一些初始化的工作

2.layoutAttributesForElementsInRect 返回已經(jīng)制定好之后的每個cell對應(yīng)的attribute屬性對象進(jìn)行布局

3.layoutAttributesForItemAtIndexPath 該方法會一直調(diào)用,每次cell出來就會根據(jù)對應(yīng)的indexpath來進(jìn)行方法調(diào)用,因此關(guān)鍵布局代碼就可以放置在這里進(jìn)行重新計算

4.collectionViewContentSize 計算整體的大小,實(shí)現(xiàn)滾動

上面插入樣式實(shí)現(xiàn)的傳送門

瀑布流實(shí)現(xiàn)分析

1.基本變量的聲明

// 每一列的間距
static const CGFloat MKJDefaultColumnMargin = 10;
// 每一行間距
static const CGFloat MKJDefaultRowMargin = 10;
// 整體的上間距,左間距,下間距,右間距
static const UIEdgeInsets MKJDefaultEdgeInsets = {10,10,10,10};
// 默認(rèn)是多少列
static const NSUInteger MKJDefaultColumnCounts = 2;

@interface MKJWaterFallLayout ()

@property (nonatomic,strong) NSMutableArray *attributeArr; // cell屬性的數(shù)組
@property (nonatomic,strong) NSMutableArray *columnHeightArr; // 每列的高度數(shù)組

@end

2.初始化

// 每次刷新會調(diào)用一次
- (void)prepareLayout
{
  [super prepareLayout];

  // 每次重新刷新的時候清除之前的所有高度值,默認(rèn)就是UIEdg給定的top
  [self.columnHeightArr removeAllObjects];
  for (NSInteger i = 0; i < [self columnCount]; i++) {
    [self.columnHeightArr addObject:@([self insetMargin].top)];
  }
  // 每次刷新把對應(yīng)的att屬性清空
  [self.attributeArr removeAllObjects];
  // 初始化一次每個cell對應(yīng)的attribute屬性
  NSInteger count = [self.collectionView numberOfItemsInSection:0];
  for (NSInteger i = 0; i < count; i++) {
    NSIndexPath *indexpath = [NSIndexPath indexPathForItem:i inSection:0];
    UICollectionViewLayoutAttributes *attribute = [self layoutAttributesForItemAtIndexPath:indexpath];
    [self.attributeArr addObject:attribute];
  }
}

3.關(guān)鍵計算代碼

// 返回attribute屬性數(shù)組決定最后的排布
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
  return self.attributeArr;
}

// 返回對應(yīng)的indexpath下每個cell的屬性 cell的出現(xiàn)會一直刷新該方法
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
  // 初始化布局屬性---> 對應(yīng)的indexpath
  UICollectionViewLayoutAttributes *att = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

  CGFloat collectionW = self.collectionView.frame.size.width;

  // 寬度是根據(jù)列數(shù)和間距固定算出來的
  CGFloat width = (collectionW - [self insetMargin].left - [self insetMargin].right - ([self columnCount] - 1) * [self columnMargin]) / [self columnCount];

  // 高度是根據(jù)代理的數(shù)據(jù)源返回比例計算的
  CGFloat height = [self.delegate MKJWaterFallLayout:self heightForItemAtIndexPath:indexPath] * width;
  // X 和 Y值都是在找出最小column之后才能確定,核心就是根據(jù)列數(shù),找出最小高度的那一列
  // 先取出第一個默認(rèn)是最小的
  CGFloat minColumnHeight = [self.columnHeightArr[0] doubleValue];
  // 默認(rèn)最小的是第0列
  NSUInteger finalCol = 0;
  for (NSInteger i = 1 ; i < [self columnCount]; i++) {
    CGFloat currentColHeight = [self.columnHeightArr[i] doubleValue];
    if (minColumnHeight > currentColHeight) {
      minColumnHeight = currentColHeight;
      finalCol = i;
    }
  }

  // x,y值是根據(jù)最小高度列算出來的
  CGFloat x = [self insetMargin].left + (width + [self columnMargin]) * finalCol;
  CGFloat y = minColumnHeight;
  // 當(dāng)你是一個行排布的時候 默認(rèn)是top值,不需要加間距
  NSInteger count = indexPath.item;
  if ((count / ([self columnCount])) >= 1) {
    y += [self rowMargin];
  }
  att.frame = CGRectMake(x, y, width, height);
  self.columnHeightArr[finalCol] = @(CGRectGetMaxY(att.frame));
  return att;

}

這里的計算簡概括為就是對每個cell進(jìn)行frame的計算

1.寬度的計算是根據(jù)列間距和整體左右間距以及行數(shù)進(jìn)行限制,這些參數(shù)可以是固定值,也可以是代理傳進(jìn)去的

2.高度的計算必定是根據(jù)外部代理進(jìn)行計算的

3.X值的計算是根據(jù)這個框架內(nèi)部的每一列的高度數(shù)組進(jìn)行之前的緩存高度,進(jìn)行最小值計算,然后拿出最小值對應(yīng)的列數(shù),根據(jù)上面算出來的高度進(jìn)行X值的計算

4.Y值的計算和X值一樣,根據(jù)給定的數(shù)組,比出最小高度列的列數(shù),根據(jù)數(shù)組的高度,計算出對應(yīng)的Y值,最終再進(jìn)行數(shù)組對應(yīng)列數(shù)的高度更新

4.獲取實(shí)際能容大小,讓其可以滾動

// 計算出滾動區(qū)域的大小
- (CGSize)collectionViewContentSize
{
  CGFloat maxColumHeight = [self.columnHeightArr[0] doubleValue];
  for (NSInteger i = 1; i < [self columnCount]; i++) {
    CGFloat currentColHeight = [self.columnHeightArr[i] doubleValue];
    if (maxColumHeight < currentColHeight) {
      maxColumHeight = currentColHeight;
    }
  }
  return CGSizeMake(0, maxColumHeight + [self insetMargin].bottom);

}

5.這個小框架已經(jīng)封裝好了,簡單介紹下用法

// 聲明如下
- (UICollectionView *)colletionView
{
  if (_colletionView == nil) {
    MKJWaterFallLayout *layout = [[MKJWaterFallLayout alloc] init];
    layout.delegate = self;
    UICollectionView *collectionV = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:layout];
    collectionV.backgroundColor = [UIColor redColor];
    [collectionV registerNib:[UINib nibWithNibName:productID bundle:nil] forCellWithReuseIdentifier:productID];
    collectionV.delegate = self;
    collectionV.dataSource = self;
    _colletionView = collectionV;

  }
  return _colletionView;
}

// 內(nèi)部行數(shù),間距的控制
#pragma mark - waterfallLayoutDelegate
- (CGFloat)MKJWaterFallLayout:(MKJWaterFallLayout *)layout heightForItemAtIndexPath:(NSIndexPath *)indexPath
{
  // 返回寬度和高度比例
  MKJProductModel *product = self.dataSource[indexPath.item];
  return product.h / product.w;
}

// 控制列間距
- (CGFloat)columnMarginForWaterFallLayout:(MKJWaterFallLayout *)collectionViewLayout
{
  return 10;
}
// 控制行間距
- (CGFloat)rowMarginForWaterFallLayout:(MKJWaterFallLayout *)collectionViewLayout
{
  return 30;
}
// 控制列數(shù)
- (NSUInteger)columnCountForWaterFallLayout:(MKJWaterFallLayout *)collectionViewLayout
{
//  if (self.dataSource.count > 50) {
//    return 3;
//  }
  return 3;
}
// 控制整體上左下右間距
- (UIEdgeInsets)insetForWaterFallLayout:(MKJWaterFallLayout *)collectionViewLayout
{
  return UIEdgeInsetsMake(10, 10, 10, 10);
}

Demo地址: http://xiazai.jb51.net/201702/yuanma/MKJWaterFallLayout_jb51.rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android的文本和輸入之創(chuàng)建輸入法教程

    Android的文本和輸入之創(chuàng)建輸入法教程

    輸入法編輯器(IME)是讓用戶輸入文本的控件,Android提供了一個可擴(kuò)展的的輸入法的框架,它允許應(yīng)用程序給用戶提供另外的輸入法,如軟鍵盤或語音輸入,需要的朋友可以了解下
    2012-12-12
  • Android Webview使用小結(jié)

    Android Webview使用小結(jié)

    這篇文章主要針對Android Webview的使用方法為大家進(jìn)行了詳細(xì)的總結(jié),感興趣的小伙伴們可以參考一下
    2016-06-06
  • Android中BroadcastReceiver案例講解

    Android中BroadcastReceiver案例講解

    今天小編就為大家分享一篇關(guān)于Android中BroadcastReceiver案例講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Android編程實(shí)現(xiàn)Gallery中每次滑動只顯示一頁的方法

    Android編程實(shí)現(xiàn)Gallery中每次滑動只顯示一頁的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)Gallery中每次滑動只顯示一頁的方法,涉及Android擴(kuò)展Gallery控件實(shí)現(xiàn)翻頁效果控制的功能,涉及Android事件響應(yīng)及屬性控制的相關(guān)技巧,需要的朋友可以參考下
    2015-11-11
  • Android中LinearLayout布局的常用屬性總結(jié)

    Android中LinearLayout布局的常用屬性總結(jié)

    這篇文章主要介紹了Android中LinearLayout布局的常用屬性總結(jié),包括居中、重心、比例等線性布局中的基本設(shè)置,需要的朋友可以參考下
    2016-04-04
  • Android使用自定義View實(shí)現(xiàn)餅狀圖的實(shí)例代碼

    Android使用自定義View實(shí)現(xiàn)餅狀圖的實(shí)例代碼

    這篇文章主要介紹了Android使用自定義View實(shí)現(xiàn)餅狀圖的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Flutter WillPopScope攔截返回事件原理示例詳解

    Flutter WillPopScope攔截返回事件原理示例詳解

    這篇文章主要為大家介紹了Flutter WillPopScope攔截返回事件原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Android編程實(shí)現(xiàn)大圖滾動顯示的方法

    Android編程實(shí)現(xiàn)大圖滾動顯示的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)大圖滾動顯示的方法,涉及Android使用imageView配合onTouch事件操作圖片顯示的相關(guān)技巧,需要的朋友可以參考下
    2016-10-10
  • Android 8.0中一些坑以及對應(yīng)的解決方法

    Android 8.0中一些坑以及對應(yīng)的解決方法

    這篇文章主要給大家介紹了關(guān)于Android 8.0中一些坑以及對應(yīng)的解決方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Flutter中漸變色的使用案例分享

    Flutter中漸變色的使用案例分享

    在日常的開發(fā)中,UI為了讓界面更加吸引人往往會在界面上用到大量的漸變色,本文將通過幾個案例更好的去了解Flutter中漸變色的使用,需要的可以參考一下
    2023-06-06

最新評論