餅圖模塊, 詳細模塊控制項封裝 詳解

来源:http://www.cnblogs.com/Dog-Ping/archive/2017/04/04/6666166.html
-Advertisement-
Play Games

餅圖模塊, 詳細模塊控制項封裝 餅圖封裝分為三個控制項. 餅圖控制項 描述控制項 餅圖控制項(左)描述控制項(右)整合 圖為將兩個控制項包裝好了以後的樣子稱為BigBackgroundView控制項 BigBackgroundView控制項: BigBackground控制項中提供的方法 從方法可以看出只要傳入pieV ...


餅圖模塊, 詳細模塊控制項封裝

  • 餅圖封裝分為三個控制項.
    • 餅圖控制項
    • 描述控制項
    • 餅圖控制項(左)描述控制項(右)整合

    圖為將兩個控制項包裝好了以後的樣子稱為BigBackgroundView控制項

Snip20170404_1

BigBackgroundView控制項:

BigBackground控制項中提供的方法

 /**
   *  傳入控制項的內邊距 創建整體控制項
   *
   *  @param pieViewInset      餅圖的內邊距(相對於最近控制項)
   *  @param describeViewInset 描述控制項的內邊距(相對於最近控制項)
   *
   *  @return self 創建是不需要設置frame, 如設置 寬高傳入(0, 0)即可
   */
 - (instancetype)bigViewWithPieViewEdgeInset:(UIEdgeInsets)pieViewInset DescribeViewEdgeInset:(UIEdgeInsets)describeViewInset;
  • 從方法可以看出只要傳入pieView的內邊距和傳入描述控制項內邊距即可創建
    • BigBackgroundView控制項不需要初始化frame,因為整體寬高是由內部的兩個控制項共同決定的
    • 如果pieView的高度大於描述控制項的高度, 描述控制項居中.反之PieView居中
  • 如果覺得BigBackgroundView控制項的左右佈局不夠你的開發需求,我們可以將兩個控制項拆分開來逐個排布

BigBackground中提供的屬性

PieView 和 DescribeView 的屬性彙總 下麵介紹這兩個控制項


PieView控制項

PieView中的屬性

Snip20170404_3

/** 傳入百分比數組 */
@property(nonatomic, strong) NSArray *scaleArr;

/** 顏色數組 */
@property(nonatomic, strong) NSArray *colorArr;

/** 線寬 預設 20          當線寬等於餅圖半徑時候 空心變成實心   */
@property(nonatomic, assign) CGFloat lineWidth;

/** 餅圖半徑  預設35       當線寬等於餅圖半徑時候 空心變成實心   */
@property(nonatomic, assign) CGFloat pieViewRadius;

屬性 百分比數組
屬性 顏色數組(可以多傳顏色)
屬性 線寬(餅圖, 空心餅圖)
屬性 半徑(和線寬配合使用)

PieView中的方法

/**
 *  一 傳入的百分比數組, 返迴轉換為餅圖使用的數組
 *
 *  @param scaleArr 百分比數組
 *
 *  @return pieView可用數組
 */
- (NSArray *)changeScaleArrayToPieViewArray:(NSArray *)scaleArr;
  • 第一步: 需要將伺服器傳進來的百分比數組進行加工, 需要適應PieView中使用的百分比數組
    • 解析: 餅圖的繪製, 第一個百分比繪製結束的地方, 就是第二個繪製的開始, 以此類推..
/**
 *  二 創建餅圖方法
 *
 *  @return self 不必設置frame
 */
- (instancetype)PieViewMaker;
  • 第二步: 餅圖製造者, 直接調用此方法就可以繪製出餅圖.不必設置frame, 只需要給出x, y 即可, 寬高 (0, 0)即可.
  • 如果不主動設置餅圖的半徑和線寬屬性, 則會初始化預設的餅圖.屬性中將預設數值已經列出
  • 如果不傳入數組, 傳入數組數量不匹配, 控制器將不顯示控制項

DescribeView控制項

DescribeView中屬性

Snip20170404_4

typedef NS_ENUM(NSInteger, DesPositionType) {
    kPositionTypeHorizontal = 0, //橫向排列
    kPositionTypeVertical //豎向排列
};
@interface DescribeView : UIView

/** 橫豎向排列 預設豎向排列*/
@property(nonatomic, assign) DesPositionType positionStyle;

/** 按鈕和label 字體大小 預設大小9 */
@property(nonatomic, assign) int labelFont  ;

/** 控制項內部按鈕 和 label 空隙 預設5 */
@property(nonatomic, assign) CGFloat desButtonAndLabelMargin;

/** 控制項之間的行高 預設5 */
@property(nonatomic, assign) CGFloat rowMargin;

/** 折行 預設3 */
@property(nonatomic, assign) int breakLineNumber;

/** label最大寬度 預設有多寬顯示多寬*/
@property(nonatomic, assign) CGFloat maxLabelWidth;

/** view視圖之間的間隔 預設5*/
@property(nonatomic, assign) CGFloat colMargin;

屬性 橫向排布, 還是豎向排布
屬性 字體的大小
屬性 左邊方塊和文字之間的空隙
屬性 行間距
屬性 到第幾行折返到下一行(行, 列公用屬性)
屬性 文字最大顯示多寬(預設有多寬顯示多寬, 伺服器應該計算好寬度)
屬性 列間距

DescribeView中方法

/**
 *  創建描述控制項
 *
 *  @param describeArr 描述信息
 *  @param colorArr    顏色
 *  @param scaleArr    百分比
 *
 *  @return self 創建不必設置frame
 */
- (instancetype)describeInPieView:(NSArray *)describeArr withColorArr:(NSArray *)colorArr withScaleArr:(NSArray *)scaleArr;
  • 傳入描述信息數組, 顏色數組, 百分比數組, 將創建好一個描述控制項
  • 如果不設置描述控制項屬性則顯示預設屬性, 以上屬性有列出
  • 如果傳入數組為空, 輸入數組數量不一致, 控制器將不顯示描述控制項

控制項解析

PieView解析

應用drawRect:方法繪製

  • 進入PieView首先先應用drawRect:方法先繪製第一個圓
    • 因為如果伺服器由於精度問題, 傳入的百分比數組相加不為1, 有可能少, 有可能多. 我先繪製一個完整圓, 剩下的繼續繪製, 到最後會空出一個位置, 正好最下麵的整個員從空出的位置顯示出來, 將位置補充完成, 解決伺服器返回數據不准確問題
#pragma mark - 直接繪製 drawRect
- (void)drawRect:(CGRect)rect {
    if (self.colorArr.count < self.scaleArr.count) {
        return;
    }
    // 如果傳入數組數量為零 則直接返回
    if (self.scaleArr.count == 0) {
        return;
    } else {
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path addArcWithCenter:self.center radius:_pieRadius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
        [self adjust:path];
        [path stroke];
    }
    
}
  • 裡面有兩個容錯
    • 一個是數組為零時候
    • 一個是顏色少於百分比數組的時候

百分比數組轉換成餅圖使用數組

  • 由於伺服器返回數組為@[@0.1, @0.2, @0.3, @0.4];
  • 而餅圖需要的是第一個元素為起點, 第二個元素為終點; 第二個元素為起點, 第三個元素為終點...依次類推直到結束, 這樣的數組
#pragma mark - 將百分比穿換成pieView使用的百分比數組
- (NSArray *)changeScaleArrayToPieViewArray:(NSArray *)scaleArr
{
    CGFloat total = 0.0f;
    CGFloat start = 0.0f;
    CGFloat end = 0.0f;
    NSMutableArray *mScaleArr = [NSMutableArray array];
    for (int i = 0; i < scaleArr.count; i ++) {
        total += [scaleArr[i] floatValue];
        end = M_PI * 2 * [scaleArr[i] floatValue] + start;
        start = end;
        [mScaleArr addObject:[NSNumber numberWithFloat:end]];
    }
    return [mScaleArr copy];
}
  • 轉換完成後返回一個餅圖可用的數組

最後調用餅圖製造者方法

  • 裡面使用到了UIBezierPath, CAShapeLayer這兩個類
  • 先繪製path, 然後添加到shapLayer上面
#pragma mark - 餅圖製造者
- (instancetype)PieViewMaker
{
    
    if (self.colorArr.count < self.scaleArr.count) {
        return nil;
    }
    
    //當線寬大於等於半徑時候, 將為實心圓
    if (self.lineWidth >= self.pieViewRadius) {
        self.lineWidth = self.pieViewRadius;
    }
    
    CGRect pieViewFrame = self.frame;
    pieViewFrame.size.width = self.pieViewRadius * 2;
    pieViewFrame.size.height = self.pieViewRadius * 2;
    
    self.frame = pieViewFrame;
    
    //裡面空心圓半徑
    _pieRadius = (self.frame.size.width - self.lineWidth) / 2;
    
    // 如果傳入數組數量為零 則直接返回
    if (self.scaleArr.count == 0) {
        return nil;
    }
    //如果傳入數組數量為1, 則繪製整個圓
    if (self.scaleArr.count == 1) {
        return nil;
    } else {
        //否則正常繪製
        for (int i = 0; i <= self.scaleArr.count - 2; i++) {
            UIBezierPath *path = [UIBezierPath bezierPath];
            
            [path addArcWithCenter:self.center radius:_pieRadius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
            [self adjust:path];
            [path stroke];
            
            _bezierPath = [UIBezierPath bezierPath];
            [_bezierPath addArcWithCenter:self.center radius:_pieRadius startAngle:[self.scaleArr[i] floatValue] endAngle:[self.scaleArr[i + 1] floatValue]  clockwise:YES];
            
            _shapeLayer = [CAShapeLayer layer];
            _shapeLayer.frame = self.bounds;
            _shapeLayer.path = _bezierPath.CGPath;
            [self adjustPathAndShapeLayer:_bezierPath shapeLayer:_shapeLayer color:((UIColor *)self.colorArr[i + 1])];
            [self.layer addSublayer:_shapeLayer];
        }
        
    }
    return self;
}
  • 返回self, 在裡面反推寬高
  • 裡面做了容錯處理

DescribeView解析

  • 根據描述數組中最大的字元串先計算出寬度, 使用KVC中的@"@max.intValue"方法
#pragma mark - 返回數組中最大值
- (float)returnMaxWidth:(NSArray *)numberArr
{
    NSMutableArray *mTextArr = [NSMutableArray array];
    for (int i = 0; i < numberArr.count; i++) {
        
        CGRect frame = [numberArr[i] boundingRectWithSize:CGSizeMake(1000, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:_labelFont]} context:nil];
        double width = frame.size.width;
        [mTextArr addObject:[NSNumber numberWithFloat:width]];
    }
    return [[mTextArr valueForKeyPath:@"@max.intValue"] floatValue] + 1;
}
  • 控制項整體使用frame計算寬高
  • 返回self, 在空間內部計算寬高
  • 根據行列, 根據行折行數量, 計算孔家顯示排布
#pragma mark - 創建描述控制項
- (instancetype)describeInPieView:(NSArray<NSString *> *)describeArr withColorArr:(NSArray *)colorArr withScaleArr:(NSArray<NSNumber *> *)scaleArr
{
    //容錯: 數組元素顯示不匹配將 直接return
    if (colorArr.count < scaleArr.count || colorArr.count < describeArr.count || describeArr.count < scaleArr.count || scaleArr.count < describeArr.count) {
        return nil;
    }
    
    //返回數組中最大字元串長度
    CGFloat maxLabelWidth;
    if (self.maxLabelWidth < 0.001) {
        maxLabelWidth = [self returnMaxWidth:describeArr];
    } else {
        maxLabelWidth = self.maxLabelWidth;
    }
    
    
    for (int i = 0; i < describeArr.count; i++) {
        [self setUpButtonWithDesArr:scaleArr colorArr:colorArr index:i];
    }
    
    
    if (describeArr.count == scaleArr.count) {
        
        switch (self.positionStyle) {
            case kPositionTypeVertical: // 豎向排列
            {
                
                for (int i = 0; i < describeArr.count; i++) {
                    
                    //避免重賦值_viewHeight 和 _viewWidth
                    if (_viewHeight == 0.0) {
                        //顯示View的高度
                        _viewHeight = _buttonHeight;
                        
                        //顯示View寬度
                        _viewWidth = _maxButtonWidth + maxLabelWidth + _desButtonAndLabelMargin;
                        
                        
                        //豎向排布frame計算
                        if (scaleArr.count <= _breakLineNumber) {
                            CGRect showViewWidth = self.frame;
                            showViewWidth.size.width = _viewWidth;
                            showViewWidth.size.height = (scaleArr.count - 1) * _rowMargin + scaleArr.count * _viewHeight;
                            self.frame = showViewWidth;
                            
                        } else {
                            if (scaleArr.count % _breakLineNumber == 0) {
                                CGRect showViewWidth = self.frame;
                                showViewWidth.size.height = (scaleArr.count / _breakLineNumber) * _viewHeight + ((scaleArr.count / _breakLineNumber) - 1) * _rowMargin;
                                showViewWidth.size.width = (_colMargin * _breakLineNumber - 1)  + _breakLineNumber * _viewWidth;
                                self.frame = showViewWidth;
                            } else {
                                CGRect showViewWidth = self.frame;
                                showViewWidth.size.width = ((scaleArr.count / _breakLineNumber) + 1) * _viewWidth + ((scaleArr.count / _breakLineNumber)) * _colMargin;
                                showViewWidth.size.height = (_colMargin * (_breakLineNumber - 1)) + _breakLineNumber * _viewHeight;
                                self.frame = showViewWidth;
                                
                            }
                        }
                    }
                    
                    //View 的x值
                    NSUInteger col = i / _breakLineNumber;
                    CGFloat viewX = col * (_viewWidth + _colMargin);
                    
                    //View 的y值
                    NSUInteger row = i % _breakLineNumber;
                    CGFloat viewY = row * (_viewHeight + _rowMargin);
                    //創建按鈕顯示
                    UIButton * vScaleBtn =  [self setUpButtonWithDesArr:scaleArr colorArr:colorArr index:i];
                    
                    //創建文本詳細顯示
                    UILabel *vDesLabel = [self setUpLabelWithDescribeArr:describeArr index:i maxWidth:maxLabelWidth];
                    
                    //創建底層View
                    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(viewX, viewY, _viewWidth, _viewHeight)];
                    //                    showView.backgroundColor = [UIColor redColor];
                    [showView addSubview:vDesLabel];
                    [showView addSubview:vScaleBtn];
                    [self addSubview:showView];
                }
                
                
            }
                break;
                //橫向排布
            case kPositionTypeHorizontal:
            {
                
                for (int i = 0; i < describeArr.count; i++) {
                    
                    //避免重賦值_viewHeight
                    if (_viewHeight == 0.0) {
                        //顯示View的高度
                        _viewHeight = _buttonHeight;
                        
                        //顯示View寬度
                        _viewWidth = _maxButtonWidth + maxLabelWidth + _desButtonAndLabelMargin;
                        
                        //橫向排布佈局
                        if (scaleArr.count <= _breakLineNumber) {
                            CGRect showViewWidth = self.frame;
                            showViewWidth.size.width = _colMargin * (scaleArr.count - 1) + scaleArr.count * _viewWidth;
                            showViewWidth.size.height = _viewHeight;
                            self.frame = showViewWidth;
                            
                        } else {
                            if (scaleArr.count % _breakLineNumber == 0) {
                                CGRect showViewWidth = self.frame;
                                showViewWidth.size.height = (scaleArr.count / _breakLineNumber) * _viewHeight + ((scaleArr.count / _breakLineNumber) - 1) * _rowMargin;
                                showViewWidth.size.width = (_colMargin * _breakLineNumber - 1)  + _breakLineNumber * _viewWidth;
                                self.frame = showViewWidth;
                            } else {
                                CGRect showViewWidth = self.frame;
                                showViewWidth.size.height = ((scaleArr.count / _breakLineNumber) + 1) * _viewHeight + ((scaleArr.count / _breakLineNumber)) * _rowMargin;
                                showViewWidth.size.width = (_colMargin * (_breakLineNumber - 1)) + _breakLineNumber * _viewWidth;
                                self.frame = showViewWidth;
                            }
                        }
                    }
                    
                    //View 的x值
                    NSUInteger col = i % _breakLineNumber;
                    CGFloat viewX = col * (_viewWidth + _colMargin);
                    
                    //View 的y值
                    NSUInteger row = i / _breakLineNumber;
                    CGFloat viewY = row * (_viewHeight + _rowMargin);
                    
                    //創建按鈕顯示
                    UIButton *hScaleBtn = [self setUpButtonWithDesArr:scaleArr colorArr:colorArr index:i];
                    
                    
                    
                    //創建文本按鈕
                    UILabel *hDesLabel = [self setUpLabelWithDescribeArr:describeArr index:i maxWidth:maxLabelWidth];
                    
                    //創建底層View
                    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(viewX, viewY, _viewWidth, _viewHeight)];
                    [showView addSubview:hDesLabel];
                    [showView addSubview:hScaleBtn];
                    [self addSubview:showView];
                }
            }
                break;
        }
    }
    return self;
}
  • 其中做了容錯處理

BigBackgroundView控制項解析

  • import以上兩個控制項在這個控制項中包含了以上兩個控制項的所有屬性, 以便於直接調用修改
  • 創建控制項的時候直接傳入兩個控制項的內邊距, BigBackgroundView控制項內部會做處理
  • 返回self創建控制項的時候不必設置frame, 只需要設置位置即可
#pragma mark - 創建控制項
- (instancetype)bigViewWithPieViewEdgeInset:(UIEdgeInsets)pieViewInset DescribeViewEdgeInset:(UIEdgeInsets)describeViewInset
{
    //容錯: 數組元素顯示不匹配將 直接return
    if (self.colorArr.count < self.scaleArr.count || self.colorArr.count < self.describeArr.count || self.describeArr.count < self.scaleArr.count || self.scaleArr.count < self.describeArr.count) {
        return nil;
    }
//    self.backgroundColor = [UIColor grayColor];
    
    [self setUpPieViewAndDesView];
    
    _pieViewInset = pieViewInset;
    _desViewInset = describeViewInset;
    
    
    //間隔距離
    _pieViewAndDesViewMargin = fabs(_pieViewInset.right)  ;
    
    //設置desView在bigView中的位置
    CGRect desViewFrame = _desView.frame;
    desViewFrame.origin.x = fabs(_pieViewInset.left) + self.basePieView.frame.size.width + _pieViewAndDesViewMargin;
    desViewFrame.origin.y = fabs(_desViewInset.top) ;
    _desView.frame = desViewFrame;
    
    //設置pieView在bigView中的位置
    CGRect basePieViewFrame = self.basePieView.frame;
    basePieViewFrame.origin.x = fabs(_pieViewInset.left) ;
    basePieViewFrame.origin.y = fabs(_pieViewInset.top) ;
    self.basePieView.frame = basePieViewFrame;
    
    
    //根據pieView 和 desView 計算bigView的寬 和 高
    CGRect bigViewFrame = self.frame;
    if (self.basePieView.frame.size.height > self.desView.frame.size.height) {
        bigViewFrame.size.height = fabs(_pieViewInset.top) + self.basePieView.frame.size.height + fabs(_pieViewInset.bottom);
        bigViewFrame.size.width = fabs(_pieViewInset.left) + self.basePieView.frame.size.width + _pieViewAndDesViewMargin + _desView.frame.size.width + fabs(_desViewInset.right);
        self.frame = bigViewFrame;
        
        //當pieView的高度 大於 desView的高度  desView 居中與PieView
        CGPoint desViewCenter = _desView.center;
        desViewCenter.y = self.basePieView.center.y;
        self.desView.center = desViewCenter;
        
    } else {
        bigViewFrame.size.height = fabs(_desViewInset.top) + _desView.frame.size.height + fabs(_desViewInset.bottom);
        bigViewFrame.size.width = fabs(_pieViewInset.left) + self.basePieView.frame.size.width + _pieViewAndDesViewMargin + _desView.frame.size.width + fabs(_desViewInset.right);
        self.frame = bigViewFrame;
        
        //當pieView的高度 小於 desView的高度PieView 居中與 desView
        CGPoint basePieViewCenter = self.basePieView.center;
        basePieViewCenter.y = self.desView.center.y;
        self.basePieView.center = basePieViewCenter;
    }
    return self;
}
  • 裡面做了容錯處理
    • 傳入的內邊距做了絕對值處理
    • 對傳入數組做了容錯處理
    • 對邊距做了容錯處理

使用方面

  • 我模擬了一個模型DescriptionModel
//模型
    DescriptionModel *model = [DescriptionModel new];

單獨使用PieView

警告⚠️:
1) 使用PieViews控制項, 一定要在調用 "changeScaleArrayToPieViewArray:" 方法前設置屬性.
2) 使用PieViews控制項, 一定要先調用轉換百分比方法 "changeScaleArrayToPieViewArray:" 再調用PieView製造者方法 "PieViewMaker"
3) 使用PieViews控制項, 一定要在 "addSubView" 之前 調用 "changeScaleArrayToPieViewArray:" 方法
4) 單獨使用PieViews控制項,需要自己在PieViews控制項外麵包一層View,否則移動時會出現錯亂.
PieView使用順序:
設置屬性 > 調用"changeScaleArrayToPieViewArray:" > 調用"PieViewMaker" > 包一層View > addSubViw

    /***********單獨使用**************/
    PieViews *pieView = [PieViews new];
    pieView.lineWidth = 30;
    pieView.pieViewRadius = 60;
    pieView.colorArr = model.colorArr;
    pieView.scaleArr = [pieView changeScaleArrayToPieViewArray:model.scaleArray];
    [pieView PieViewMaker];
    //包一層View
    UIView *basePieView = [UIView new];
    basePieView.frame = CGRectMake(20, 40, pieView.frame.size.width, pieView.frame.size.height);
    [basePieView addSubview:pieView];
    [self.view addSubview:basePieView];
    /********************************/
  • 控制項創建的時候不需要設置frame
  • 需要包一層View, 繪製圖形的通病
  • 如果要設置位置, 只需要改變外麵包的那層view的位置即可

單獨使用DescribeView

無特殊警告⚠️

    /***********單獨使用**************/
    DescribeView *desView = [DescribeView new];
    desView.frame = CGRectMake(20, pieView.frame.size.height + 50, 0, 0);
    desView.labelFont = 10;
    desView.desButtonAndLabelMargin = 5;
    desView.rowMargin = 5;
    desView.colMargin = 5;
    desView.breakLineNumber = 3;
    desView.positionStyle = kPositionTypeVertical;
    [desView describeInPieView:model.descriptionArray withColorArr:model.colorArr withScaleArr:model.scaleArray];
    [self.view addSubview:desView];
    /********************************/

整體使用BigBackgroundView

警告⚠️
1) 使用BigBackGroundView控制項時, 一定要在調用 "bigViewWithPieViewEdgeInset: DescribeViewEdgeInset:"方法前設置屬性.
2) 設置center屬性時, 要在 "bigViewWithPieViewEdgeInset: DescribeViewEdgeInset:"方法後設置. 直接設置frame無所謂.

BigBackgroundView使用順序:
設置屬性 > "bigViewWithPieViewEdgeInset: DescribeViewEdgeInset:" > 設置 center 屬性(不瞭解為什麼)

/***************整合*****************/
    BigBackgroundView *showView = [BigBackgroundView new];
    showView.pieViewRadius = 60;
    showView.lineWidth = 30;
    showView.positionStyle = kPositionTypeVertical;
    showView.breakLineNumber = 5;
    showView.colorArr = model.colorArr;
    showView.scaleArr = model.scaleArray;
    showView.describeArr = model.descriptionArray;
    [self.view addSubview:showView];
    [showView bigViewWithPieViewEdgeInset:UIEdgeInsetsMake(0, 0, 0, 10) DescribeViewEdgeInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    showView.center = self.view.center;
    /********************************/

YG -- 陽光

如果覺得寫得還不錯請給予一顆小⭐️⭐️

GitHub地址
博客園地址
YGPieView地址


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.節點-添加標簽 <body><div id="div1"><p id="p1">這是一個段落。</p><p id="p2">這是另一個段落。</p></div><script>var para=document.createElement("p"); //創建一個文本節<p>var node=d ...
  • 今天在用ionic2 的 生成新的icon和splash,生成後安裝,應用圖標和啟動畫面依然沒變化。。。 不知道大家有沒有被坑過,今天被坑了一下午,終於找到了辦法: 解決方法 第一次使用 後根文件夾下會生成一個res文件夾,比如你的項目文件夾名是 ,那麼就是 文件夾。 將res中的所有文件夾複製到 ...
  • 一.什麼是作用域 作用域是指對某一變數和方法具有訪問許可權的代碼空間,Javascript的作用域只有兩種:全局作用域和本地作用域,本地作用域是按照函數來區分的(即全局變數和局部變數)) 局部變數:只有局部能夠訪問的變數 例如:1.函數內部用var定義的變數 2.for迴圈的的時候遍歷是用到的變數i ...
  • 1、對於string,number等基礎類型,==和 是有區別的 1)不同類型間比較,==之比較“轉化成同一類型後的值”看“值”是否相等, 如果類型不同,其結果就是不等 2)同類型比較,直接進行“值”比較,兩者結果一樣 2、對於Array,Object等高級類型,==和 是沒有區別的 進行“指針地址 ...
  • 1. 簡介   SharedPreferences是一種輕型的數據存儲方式,通過key value鍵值對的方式將數據存儲在xml文件中,常用於存儲簡單的配置信息。 2. 使用方式 2.1 獲取SharedPreferences對象   Android中可通過以 ...
  • activity_main.xml arrays.xml: activity: ProcessView : ...
  • ListView想要添加headerview的話,就要通過addHeaderView這個方法,然後想要為ListView設置數據的話,就要調用setAdapter方法了。但是,在調用addHeaderView和setAdapter的順序上,有時會爆出Java.lang.IllegalStateExc ...
  • 在代碼中使用 listView .addHeaderView(...) 方法可以在ListView組件上方添加上其他組件,並且連結在一起像是一個新組件。如果多次使用 .addHeaderView(...) ,則最先添加的組件在最上方,按添加的先後順序由上到下羅列。 此時listView 的 posi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...