UITableView中的单元重用问题

时间:2015-07-02 15:17:01

标签: ios objective-c uitableview

我有UITableView显示信息,但大多数我坚持的位显示星级评分。我设法创建了一个自定义UITableViewCell,其中包含显示每个单元格的星级评分的逻辑。因此,如果等级为3,它将显示3颗黄色星和2个空白星,因此总共得到5分。当显示UITableView时,我可以看到前4个单元格的星级评分是正确的:

仅显示TEN细胞。

Rating in order of cell (what comes back from the Database):
5
3
3
1
0
0
0
0
0
0

但最新发生的是,当我滚动细胞时,我得到了这些评级,似乎重复了第一个细胞评级:

Rating in order of cell when scrolled (UI Scrolling):
5
3
3
1
5
3
3
1
5
3

为什么会这样?

如果需要,我会给你代码和编辑。

修改

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(tableView == tableViewTopThreads){

        static NSString *simpleTableIdentifier = @"SimpleTableItem";

        ThreadTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
        //cell.layer.shouldRasterize = YES;
        //cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
        if (cell == nil) {
            cell = [[ThreadTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        }

        Thread *t = (Thread*)[tmpArray4 objectAtIndex:indexPath.row];
        cell.labelTitle.text = t.title;
        cell.labelCat.text = t.cat;
        cell.labelUser.text = [NSString stringWithFormat:@"%@ %@", t.firstname, t.lastname];
        cell.labelDate.text = [NSString stringWithFormat:@"%@", t.date];
        cell.labelCountry.text = t.country;
        cell.labelSubCat.text = t.subcat;
        cell.rating = t.rating;

        [cell.contentView setNeedsUpdateConstraints];
        [cell.contentView updateConstraintsIfNeeded];
        [cell.contentView setNeedsLayout];
        [cell.contentView layoutIfNeeded];

        return cell;
    }

}

自定义单元格:

        #import "ThreadTableViewCell.h"


        @implementation ThreadTableViewCell

        @synthesize main;
        @synthesize top;
        @synthesize center;
        @synthesize bottom;
        @synthesize rate;
        @synthesize rating;
        @synthesize labelTitle;
        @synthesize labelCat;
        @synthesize labelSubCat;
        @synthesize labelUser;
        @synthesize labelDate;
        @synthesize labelCountry;
        @synthesize imageviewThreadImage;
        @synthesize imageviewRating1;
        @synthesize imageviewRating2;
        @synthesize imageviewRating3;
        @synthesize imageviewRating4;
        @synthesize imageviewRating5;


        - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
            self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
            if (self) {

            //self.contentView.backgroundColor = [UIColor lightGrayColor];

            [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
            self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;

            //CGRect screenBound = [[UIScreen mainScreen] bounds];
            //CGSize screenSize = screenBound.size;
            //CGFloat screenWidth = screenSize.width;
            //CGFloat screenHeight = screenSize.height;

            main = [UIView new];
            [self.contentView addSubview:main];
            main.translatesAutoresizingMaskIntoConstraints = NO;
            //[main sizeToFit];
            main.backgroundColor = [UIColor whiteColor];

            top = [UIView new];
            [main addSubview:top];
            top.translatesAutoresizingMaskIntoConstraints = NO;
            //[top sizeToFit];
            top.backgroundColor = [UIColor whiteColor];

            labelUser = [UILabel new];
            [top addSubview:labelUser];
            labelUser.translatesAutoresizingMaskIntoConstraints = NO;
            //[labelUser sizeToFit];
            [labelUser setFont:[UIFont systemFontOfSize:14]];
            labelUser.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];

            labelDate = [UILabel new];
            [top addSubview:labelDate];
            labelDate.translatesAutoresizingMaskIntoConstraints = NO;
            [labelDate sizeToFit];
            [labelDate setFont:[UIFont systemFontOfSize:14]];
            labelDate.textColor = [UIColor colorWithRed:(114.0/255.0) green:(114.0/255.0) blue:(114.0/255.0) alpha:1.0];

            center = [UIView new];
            [main addSubview:center];
            center.translatesAutoresizingMaskIntoConstraints = NO;
            [center sizeToFit];
            center.backgroundColor = [UIColor whiteColor];

            imageviewThreadImage = [UIImageView new];
            [center addSubview:imageviewThreadImage];
            imageviewThreadImage.translatesAutoresizingMaskIntoConstraints = NO;
            imageviewThreadImage.backgroundColor = [UIColor colorWithRed:(207.0/255.0) green:(215.0/255.0) blue:(248.0/255.0) alpha:1.0];

            labelTitle = [UILabel new];
            [center addSubview:labelTitle];
            labelTitle.translatesAutoresizingMaskIntoConstraints = NO;
            [labelTitle sizeToFit];
            labelTitle.lineBreakMode = NSLineBreakByWordWrapping;
            [labelTitle setFont:[UIFont systemFontOfSize:14]];
            labelTitle.textColor = [UIColor lightGrayColor];
            labelTitle.numberOfLines = 0;
            //labelTitle.preferredMaxLayoutWidth = screenWidth - 10 - 36;

            bottom = [UIView new];
            [main addSubview:bottom];
            bottom.translatesAutoresizingMaskIntoConstraints = NO;
            [bottom sizeToFit];

            labelCat = [UILabel new];
            [bottom addSubview:labelCat];
            labelCat.translatesAutoresizingMaskIntoConstraints = NO;
            [labelCat sizeToFit];
            [labelCat setFont:[UIFont systemFontOfSize:12]];
            labelCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];

            labelSubCat = [UILabel new];
            [bottom addSubview:labelSubCat];
            labelSubCat.translatesAutoresizingMaskIntoConstraints = NO;
            [labelSubCat sizeToFit];
            [labelSubCat setFont:[UIFont systemFontOfSize:12]];
            labelSubCat.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];

            labelCountry = [UILabel new];
            [bottom addSubview:labelCountry];
            labelCountry.translatesAutoresizingMaskIntoConstraints = NO;
            [labelCountry sizeToFit];
            [labelCountry setFont:[UIFont systemFontOfSize:12]];
            labelCountry.textColor = [UIColor colorWithRed:(58.0/255.0) green:(82.0/255.0) blue:(207.0/255.0) alpha:1.0];


            rate = [UIView new];
            [bottom addSubview:rate];
            rate.translatesAutoresizingMaskIntoConstraints = NO;
            [rate sizeToFit];


            imageviewRating1 = [UIImageView new];
            [rate addSubview:imageviewRating1];
            imageviewRating1.translatesAutoresizingMaskIntoConstraints = NO;
            [imageviewRating1 sizeToFit];

            imageviewRating2 = [UIImageView new];
            [rate addSubview:imageviewRating2];
            imageviewRating2.translatesAutoresizingMaskIntoConstraints = NO;
            [imageviewRating2 sizeToFit];

            imageviewRating3 = [UIImageView new];
            [rate addSubview:imageviewRating3];
            imageviewRating3.translatesAutoresizingMaskIntoConstraints = NO;
            [imageviewRating3 sizeToFit];

            imageviewRating4 = [UIImageView new];
            [rate addSubview:imageviewRating4];
            imageviewRating4.translatesAutoresizingMaskIntoConstraints = NO;
            [imageviewRating4 sizeToFit];

            imageviewRating5 = [UIImageView new];
            [rate addSubview:imageviewRating5];
            imageviewRating5.translatesAutoresizingMaskIntoConstraints = NO;
            [imageviewRating5 sizeToFit];


            UIImage *imageStarDisabled = [UIImage imageNamed:@"star.png"];
            //UIImage *imageStarEnabled = [UIImage imageNamed:@"star2.png"];


            imageviewRating1.image = imageStarDisabled;
            imageviewRating2.image = imageStarDisabled;
            imageviewRating3.image = imageStarDisabled;
            imageviewRating4.image = imageStarDisabled;
            imageviewRating5.image = imageStarDisabled;





            }

            return self;
        }

        - (void)layoutSubviews
        {
            [super layoutSubviews];

            // Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
            // need to use to set the preferredMaxLayoutWidth below.
            [self.contentView setNeedsLayout];
            [self.contentView layoutIfNeeded];

            // Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
            // as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
            self.labelTitle.preferredMaxLayoutWidth = CGRectGetWidth(self.labelTitle.frame);
        }

        - (void)updateConstraints {
            [super updateConstraints];

            if (self.didSetupConstraints) return;


            //UIImage *imageStarDisabled = [UIImage imageNamed:@"star.png"];
            UIImage *imageStarEnabled = [UIImage imageNamed:@"star2.png"];

            if(rating > 0){

            for(int i = 1; i < rating + 1; i++){

                if(i == 1){
                imageviewRating1.image = imageStarEnabled;
                }

                if (i == 2) {
                imageviewRating2.image = imageStarEnabled;
                }

                if (i == 3) {
                imageviewRating3.image = imageStarEnabled;
                }

                if (i == 4) {
                imageviewRating4.image = imageStarEnabled;
                }

                if (i == 5) {
                imageviewRating5.image = imageStarEnabled;
                }


            }

            }




            NSDictionary *viewsDictionary7 = @{@"main":main};
            NSArray *constraint_H37 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[main]|"
                                             options:0
                                             metrics:nil
                                               views:viewsDictionary7];

            NSArray *constraint_V37 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[main]|"
                                          options:0
                                           metrics:nil
                                            views:viewsDictionary7];
            [self.contentView addConstraints:constraint_H37];
            [self.contentView addConstraints:constraint_V37];


            NSDictionary *viewsDictionary3 = @{@"top":top,@"center":center,@"bottom":bottom};
            NSArray *constraint_H3 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[top]-5-[center]-5-[bottom]-10-|"
                                             options:0
                                             metrics:nil
                                               views:viewsDictionary3];

            NSArray *constraint_H33 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[top]|"
                                             options:0
                                             metrics:nil
                                            views:viewsDictionary3];

            NSArray *constraint_H333 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[center]|"
                                             options:0
                                             metrics:nil
                                             views:viewsDictionary3];

            NSArray *constraint_H3335657 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottom]|"
                                               options:0
                                               metrics:nil
                                             views:viewsDictionary3];

            NSDictionary *viewsDictionary4 = @{@"labelUser":labelUser,@"labelDate":labelDate};
            NSArray *constraint_H4 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[labelUser]|"
                                            options:0
                                            metrics:nil
                                               views:viewsDictionary4];

            NSDictionary *viewsDictionary45 = @{@"labelDate":labelDate};
            NSArray *constraint_H4555 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[labelDate]|"
                                             options:0
                                             metrics:nil
                                               views:viewsDictionary45];

            NSArray *constraint_H44 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[labelUser]-20-[labelDate]-5-|"
                                             options:0
                                             metrics:nil
                                            views:viewsDictionary4];

            NSDictionary *viewsDictionary48 = @{@"labelTitle":labelTitle,@"imageviewThreadImage":imageviewThreadImage};
            NSArray *constraint_H48 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[labelTitle]|"
                                             options:0
                                             metrics:nil
                                            views:viewsDictionary48];

            NSArray *constraint_H48342 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[imageviewThreadImage(36)]|"
                                              options:0
                                              metrics:nil
                                            views:viewsDictionary48];

            NSArray *constraint_H448 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[imageviewThreadImage(36)]-5-[labelTitle]|"
                                              options:0
                                              metrics:nil
                                             views:viewsDictionary48];

            NSDictionary *viewsDictionary488 = @{@"labelCat":labelCat,@"labelCountry":labelCountry,@"labelSubCat":labelSubCat,@"rate":rate};
            NSArray *constraint_H488 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[labelCat]|"
                                              options:0
                                              metrics:nil
                                             views:viewsDictionary488];
            NSArray *constraint_H48898 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[labelCountry]|"
                                               options:0
                                               metrics:nil
                                               views:viewsDictionary488];
            NSArray *constraint_H48898fgf54 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[labelSubCat]|"
                                             options:0
                                             metrics:nil
                                                views:viewsDictionary488];
            NSArray *constraint_H48898fgf54fdf = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[rate]|"
                                                  options:0
                                                  metrics:nil
                                                views:viewsDictionary488];

            NSArray *constraint_H4488 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[labelCat]-10-[labelSubCat]-10-[labelCountry]-10-[rate]"
                                               options:0
                                               metrics:nil
                                             views:viewsDictionary488];




            NSDictionary *viewsDictionary4885 = @{@"imageviewRating1":imageviewRating1,@"imageviewRating2":imageviewRating2,@"imageviewRating3":imageviewRating3,@"imageviewRating4":imageviewRating4,@"imageviewRating5":imageviewRating5};

            NSArray *constraint_H488fbfb = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageviewRating1(15)]|"
                                               options:0
                                               metrics:nil
                                             views:viewsDictionary4885];

            NSArray *constraint_H48898xfb = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageviewRating2(15)]|"
                                             options:0
                                             metrics:nil
                                                  views:viewsDictionary4885];

            NSArray *constraint_H48898xfbfg = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageviewRating3(15)]|"
                                                options:0
                                                metrics:nil
                                                  views:viewsDictionary4885];

            NSArray *constraint_H48898xfbxfg = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageviewRating4(15)]|"
                                                options:0
                                                metrics:nil
                                                  views:viewsDictionary4885];

            NSArray *constraint_H48898xfrtbxfg = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageviewRating5(15)]|"
                                                options:0
                                                metrics:nil
                                                  views:viewsDictionary4885];

            NSArray *constraint_H48898fgf54fxb = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageviewRating1(15)]-2-[imageviewRating2(15)]-2-[imageviewRating3(15)]-2-[imageviewRating4(15)]-2-[imageviewRating5(15)]"
                                                  options:0
                                                  metrics:nil
                                                views:viewsDictionary4885];




            [main addConstraints:constraint_H3];
            [main addConstraints:constraint_H33];
            [main addConstraints:constraint_H333];
            [top addConstraints:constraint_H4];
            [top addConstraints:constraint_H44];
            [center addConstraints:constraint_H48];
            [center addConstraints:constraint_H448];
            [top addConstraints:constraint_H4555];
            [main addConstraints:constraint_H3335657];
            [main addConstraints:constraint_H488];
            [main addConstraints:constraint_H4488];
            [main addConstraints:constraint_H48898];
            [main addConstraints:constraint_H48342];
            [main addConstraints:constraint_H48898fgf54];
            [main addConstraints:constraint_H48898fgf54fdf];

            [bottom addConstraints:constraint_H488fbfb];
            [bottom addConstraints:constraint_H48898xfb];
            [bottom addConstraints:constraint_H48898xfbfg];
            [bottom addConstraints:constraint_H48898xfbxfg];
            [bottom addConstraints:constraint_H48898xfrtbxfg];
            [bottom addConstraints:constraint_H48898fgf54fxb];



            self.didSetupConstraints = YES;

        }


        - (void)awakeFromNib {
            // Initialization code



        }

        - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
            [super setSelected:selected animated:animated];

            // Configure the view for the selected state
        }

        @end

ViewController,用于设置数据库的评级:

        dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        // 3) Load picker in background
            dispatch_async(concurrentQueue, ^{


            NSString *myRequestString = [NSString stringWithFormat:@"threadTitle=%@&threadCountry=%@&threadCategory=%@&threadSubCategory=%@",searchThreadTitleTopThreads, searchThreadCountryTopThreads, searchThreadCategoryTopThreads, searchThreadSubCategoryTopThreads];
            __block NSString *response = [self setupPhpCall:myRequestString :@"xxx.php"];


            dispatch_async(dispatch_get_main_queue(), ^{

                if(response.length > 0){

                    NSDictionary *dic = [response JSONValue];

                    if((NSNull*)dic != [NSNull null]){
                        int at_ID = 0;
                        int at_U_ID = 0;
                        int rating = 0;
                        NSString *at_Title;
                        NSString *at_Desc;
                        NSString *at_Cat;
                        NSString *at_SubCat;
                        NSString *at_Date;
                        NSString *at_Country;
                        NSString *at_FirstName;
                        NSString *at_LastName;
                        for(NSDictionary *dict in dic)
                        {
                            counter = counter + 1;
                            if((NSNull *)[dict objectForKey:@"AT_ID"] != [NSNull null]){
                                at_ID = [[dict objectForKey:@"AT_ID"] intValue];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_U_ID"] != [NSNull null]){
                                at_U_ID = [[dict objectForKey:@"AT_U_ID"] intValue];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_Title"] != [NSNull null]){
                                at_Title = [dict objectForKey:@"AT_Title"];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_Desc"] != [NSNull null]){
                                at_Desc = [dict objectForKey:@"AT_Desc"];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_Cat"] != [NSNull null]){
                                at_Cat = [dict objectForKey:@"AT_Cat"];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_SubCat"] != [NSNull null]){
                                at_SubCat = [dict objectForKey:@"AT_SubCat"];
                            }
                            if((NSNull *)[dict objectForKey:@"AT_Country"] != [NSNull null]){
                                at_Country = [dict objectForKey:@"AT_Country"];
                            }
                            if((NSNull *)[dict objectForKey:@"U_FirstName"] != [NSNull null]){
                                at_FirstName = [dict objectForKey:@"U_FirstName"];
                            }
                            if((NSNull *)[dict objectForKey:@"U_LastName"] != [NSNull null]){
                                at_LastName = [dict objectForKey:@"U_LastName"];
                            }
                            if((NSNull *)[dict objectForKey:@"AVG(r.TR_Value)"] != [NSNull null]){
                                rating = [[dict objectForKey:@"AVG(r.TR_Value)"] intValue];
                            }
                            NSString *dateTS = [dict objectForKey:@"AT_Date"];
                            if((NSNull *)[dict objectForKey:@"AT_Date2"] != [NSNull null]){
                                NSString *timestampString = [dict objectForKey:@"AT_Date2"];
                                double timestampDate = [timestampString doubleValue];
                                NSDate *d = [NSDate dateWithTimeIntervalSince1970:timestampDate];
                                NSDateFormatter *_formatter=[[NSDateFormatter alloc]init];
                                [_formatter setDateFormat:@"dd.MM.yyyy HH:mm:ss"];
                                at_Date = [_formatter stringFromDate:d];
                                if (counter == 1) {
                                    //lastDateForumActivity = dateTS;
                                }
                            }
                            if(counter == 1){
                                //lastDateForumActivity = dateTS;
                            }
                            Thread *thread = [[Thread alloc] init];
                            thread.tag = at_ID;
                            thread.idUser = at_U_ID;
                            thread.firstname = at_FirstName;
                            thread.lastname = at_LastName;
                            thread.idThread = at_ID;
                            thread.title = at_Title;
                            thread.desc = at_Desc;
                            thread.cat = at_Cat;
                            thread.date = at_Date;
                            thread.country = at_Country;
                            thread.subcat = at_SubCat;
                            thread.rating = rating; //RATING SET
                            [tmpArray4 addObject:thread];

                            //cell = nil;

                        }

                        at_ID = 0;
                        at_U_ID = 0;
                        at_Title = @"";
                        at_Desc = @"";
                        at_Cat = @"";
                        at_Date = @"";
                        at_Country = @"";
                        at_FirstName = @"";
                        at_LastName = @"";
                    }
                }

2 个答案:

答案 0 :(得分:1)

您的问题在于您不会考虑重复使用的单元格。由于单元格被重复使用,单元格的初始化会将图像设置为禁用的星形,但在代码中正确设置星形,您只需将它们切换为启用的星形图像。如果当前单元格的等级为0,则永远不会将它们设置回来,但是它被应用于等级为3的重用单元格。因此,您的代码不会更改任何图像,因此3个已启用的星形图像会保持。

为rating属性添加一个setter,类似于此。此外,从Xcode 4.4开始,不需要@synthesize,所以你可以摆脱它。

- (void)setRating: (int)newRatingValue {
        _rating = newRatingValue;

        UIImage *imageStarDisabled = [UIImage imageNamed:@"star.png"];
        UIImage *imageStarEnabled = [UIImage imageNamed:@"star2.png"];

        imageviewRating1.image = rating >= 1 ? imageStarEnabled : imageStarDisabled;
        imageviewRating2.image = rating >= 2 ? imageStarEnabled : imageStarDisabled;
        imageviewRating3.image = rating >= 3 ? imageStarEnabled : imageStarDisabled;
        imageviewRating4.image = rating >= 4 ? imageStarEnabled : imageStarDisabled;
        imageviewRating5.image = rating >= 5 ? imageStarEnabled : imageStarDisabled;

}

我相信下面的内容会有效,但如果你在后台线程上更新评级,可能会导致一些问题。您可能需要在调度异步调用中包装更新图像,以便在主(UI)线程上执行它,如下所示:

dispatch_async( dispatch_get_main_queue(), ^{

        imageviewRating1.image = rating >= 1 ? imageStarEnabled : imageStarDisabled;
        imageviewRating2.image = rating >= 2 ? imageStarEnabled : imageStarDisabled;
        imageviewRating3.image = rating >= 3 ? imageStarEnabled : imageStarDisabled;
        imageviewRating4.image = rating >= 4 ? imageStarEnabled : imageStarDisabled;
        imageviewRating5.image = rating >= 5 ? imageStarEnabled : imageStarDisabled;
});`

此外,您应该学习如何使用调试器来放置断点并逐步执行代码,检查事物的状态。这将有助于将来解决和诊断这些类型的问题。

答案 1 :(得分:0)

我把你的逻辑移到了@wottle:

CardView

这是放置逻辑的最佳位置吗?