最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

默認兩列 

其他案例

  

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

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

2.layoutAttributesForElementsInRect 返回已經制定好之后的每個cell對應的attribute屬性對象進行布局

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

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

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

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

1.基本變量的聲明

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

@interface MKJWaterFallLayout ()

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

@end

2.初始化

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

  // 每次重新刷新的時候清除之前的所有高度值,默認就是UIEdg給定的top
  [self.columnHeightArr removeAllObjects];
  for (NSInteger i = 0; i < [self columnCount]; i++) {
    [self.columnHeightArr addObject:@([self insetMargin].top)];
  }
  // 每次刷新把對應的att屬性清空
  [self.attributeArr removeAllObjects];
  // 初始化一次每個cell對應的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.關鍵計算代碼

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

// 返回對應的indexpath下每個cell的屬性 cell的出現(xiàn)會一直刷新該方法
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
  // 初始化布局屬性---> 對應的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ù),找出最小高度的那一列
  // 先取出第一個默認是最小的
  CGFloat minColumnHeight = [self.columnHeightArr[0] doubleValue];
  // 默認最小的是第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;
  // 當你是一個行排布的時候 默認是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進行frame的計算

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

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

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

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

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

// 計算出滾動區(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.這個小框架已經封裝好了,簡單介紹下用法

// 聲明如下
- (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;
}

// 內部行數(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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

  • Android App中使用ViewPager實現(xiàn)滑動分頁的要點解析

    Android App中使用ViewPager實現(xiàn)滑動分頁的要點解析

    這篇文章主要介紹了Android App中使用ViewPager實現(xiàn)滑動分頁的要點解析,還附帶了一個禁止ViewPager左右滑動的方法,需要的朋友可以參考下
    2016-06-06
  • 淺談Android截屏和指定View生成截圖

    淺談Android截屏和指定View生成截圖

    本文主要介紹了Android如何截屏和指定View生成截圖,感興趣的同學,可以參考下
    2021-06-06
  • android開發(fā)socket編程之udp發(fā)送實例分析

    android開發(fā)socket編程之udp發(fā)送實例分析

    這篇文章主要介紹了android開發(fā)socket編程之udp發(fā)送,實例分析了Android開發(fā)socket網絡編程中udp發(fā)送的相關技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • Android中各種Time API詳細

    Android中各種Time API詳細

    這篇文章要分享的是Android中各種Time API, SystemClock.uptimeMillis()、System.nanoTime(),下面我們就來看看他們到底有什么區(qū)別吧
    2021-10-10
  • android系統(tǒng)在靜音模式下關閉camera拍照聲音的方法

    android系統(tǒng)在靜音模式下關閉camera拍照聲音的方法

    本文為大家詳細介紹下android系統(tǒng)如何在靜音模式下關閉camera拍照聲音,具體的實現(xiàn)方法如下,感興趣的朋友可以參考下哈
    2013-07-07
  • Android 自定義標題欄 顯示網頁加載進度的方法實例

    Android 自定義標題欄 顯示網頁加載進度的方法實例

    Android 自定義標題欄 顯示網頁加載進度的方法實例,需要的朋友可以參考一下
    2013-06-06
  • 利用flutter實現(xiàn)炫酷的list

    利用flutter實現(xiàn)炫酷的list

    這篇文章主要給大家介紹了關于利用flutter實現(xiàn)炫酷的list的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用flutter具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • Android ListView滑動改變標題欄背景漸變效果

    Android ListView滑動改變標題欄背景漸變效果

    這篇文章主要為大家詳細介紹了Android ListView滑動改變標題欄背景漸變效果,透明轉變成不透明,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android實現(xiàn)購物車添加商品特效

    Android實現(xiàn)購物車添加商品特效

    這篇文章主要為大家詳細介紹了Android實現(xiàn)購物車添加商品特效,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 最新評論

    鄂州市| 重庆市| 方城县| 中西区| 通州市| 恩施市| 涡阳县| 民权县| 东台市| 溧水县| 轮台县| 股票| 尉犁县| 新宁县| 溧阳市| 宁夏| 岳普湖县| 新郑市| 夏津县| 凉山| 南充市| 和龙市| 东至县| 西充县| 容城县| 广德县| 阜康市| 禹州市| 大方县| 江源县| 宝丰县| 辰溪县| 尼木县| 霍州市| 东至县| 江陵县| 英德市| 大英县| 达日县| 闻喜县| 安国市|