Monotouch适用于定制细胞太慢

时间:2013-07-22 14:31:07

标签: c# uitableview xamarin.ios

我的表和我的自定义单元格有以下代码:

以下是我的viewcontroller的代码

public void SearchHotel (){

            Hotel hotel = new Hotel();
            var distribution = new HotelDistribution[]{new HotelDistribution(){ Adults = 1, Children = 0, ChildrenAges = new int[0]} };
            var items = hotel.SearchHotels(Convert.ToDateTime("2013-08-08"),Convert.ToDateTime("2013-09-09 "),"(MIA)", distribution,"","","",0);


            List<DtoHotelinformation> data = new List<DtoHotelinformation>();

            foreach (var item in items)
            {
                DtoHotelinformation DtoHotelinformation = new DtoHotelinformation();
                DtoHotelinformation.price  = item.Price.ToString();
                DtoHotelinformation.title =  item.Name.ToString();
                DtoHotelinformation.subtitle = item.Address.ToString();
                DtoHotelinformation.price = item.Price.ToString();
                DtoHotelinformation.imageUlr = item.ImageUrl;

                data.Add(DtoHotelinformation);
            }

            hud.Hide(true);
            hud.RemoveFromSuperview();
            HotelSearchTable.Source = new HotelTableSource(data.ToArray());
            HotelSearchTable.ReloadData();

        }

这是我的tablesource的代码

    public class HotelTableSource : UITableViewSource
    {

        DtoHotelinformation[] tableItems;
        NSString cellIdentifier = new NSString("TableCell");

        public HotelTableSource (DtoHotelinformation[] items)
        {
            tableItems = items;
        }
        public override int RowsInSection (UITableView tableview, int section)
        {
            return tableItems.Length;
        }

        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            new UIAlertView("Row Selected", tableItems[indexPath.Row].title, null, "OK", null).Show();
            tableView.DeselectRow (indexPath, true); // normal iOS behaviour is to remove the blue highlight
        }

        public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            CustomCell cell = tableView.DequeueReusableCell(cellIdentifier) as CustomCell;
            if (cell == null)
                cell = new CustomCell(cellIdentifier);
            cell.UpdateCell(tableItems[indexPath.Row].title, tableItems[indexPath.Row].subtitle, tableItems[indexPath.Row].price,
                            tableItems[indexPath.Row].imageUlr );
            return cell;


        }

        public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
        {
            return 60;
        }
    }
}

这是自定义单元代码:

public class CustomCell : UITableViewCell
{
    UILabel headingLabel, subheadingLabel, priceLabel;
    UIImageView imageService;
    UIImageView star, star2, star3, star4, star5;
    public CustomCell (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
    {
        imageService = new UIImageView();
        star   = new UIImageView();
        star2  = new UIImageView();
        star3  = new UIImageView();
        star4  = new UIImageView();
        star5  = new UIImageView();
        headingLabel = new UILabel(){
            Font = UIFont.FromName("Verdana-Bold", 14f),
            BackgroundColor = UIColor.Clear,
            TextColor = UIColor.FromRGB(241, 241, 211)
        };
        subheadingLabel = new UILabel(){
            Font = UIFont.FromName("Verdana-Bold", 8f),
            TextColor = UIColor.FromRGB(60, 0, 100),
            BackgroundColor = UIColor.Clear
        };
        priceLabel = new UILabel(){
            Font = UIFont.FromName("Verdana", 14f),
            TextColor = UIColor.FromRGB(241, 241, 211),
            BackgroundColor = UIColor.Clear
        };
            AddSubview(imageService);
        AddSubview(headingLabel);
        AddSubview(subheadingLabel);
        AddSubview(priceLabel);

    }

    public void UpdateCell (string title, string subtitle, string price, string imageUlr )
    {
        if (imageUlr != null) {
            NSUrl nsUrl = new NSUrl(imageUlr);
            NSData data = NSData.FromUrl(nsUrl);
            imageService.Image = new UIImage(data);
        } else {
            imageService.Image = UIImage.FromFile("generic_no_image_tiny.jpg");
        }

        headingLabel.Text = title;
        subheadingLabel.Text = subtitle;
        priceLabel.Text = price;

    }



    public override void LayoutSubviews ()
    {
        base.LayoutSubviews ();
        imageService.Frame = new RectangleF(10, 10, 50, 33);
        headingLabel.Frame = new RectangleF(70, 4, 220, 25);
        subheadingLabel.Frame = new RectangleF(100, 30, 100, 20);
        priceLabel.Frame = new RectangleF(250, 30, 100, 20);
    }
}

该表运行良好,我得到了我需要的数据,但它的工作速度非常慢。我的意思是当我试图滚动桌子时,一切都变得非常缓慢。任何想法?

3 个答案:

答案 0 :(得分:2)

覆盖GetHeightForRow以返回常量值。而是将RowHeight的{​​{1}}属性设置为您需要显示单元格的常量值。

这背后的原因是,当您覆盖UITableView iOS GetHeightForRow时,需要查询每个单元格以计算总高度。一旦你拥有数以千计的潜在细胞,那就非常缓慢(充其量)并且无法使用。

答案 1 :(得分:1)

避免分配可能很大且易于重用的对象。在这里,每次要显示单元格时都要创建一个UIImage。更糟糕的是,你可能正在打开一个文件,读取它并将其解压缩然后创建可显示的UIImage。您应该使用缓存来避免同一UIImage的重复实例。这个小班应该做的工作:

public class ImageCache {
    private Dictionary<string, UIImage> cache = new Dictionary<string, UIImage>();
    public static readonly ImageCache SharedInstance = new ImageCache();

    public ImageCache() {
    }

    private UIImage ImageForUrl(string url) {
        UIImage image = null;

        if (!this.cache.TryGetValue(url, out image)) {
            NSUrl url = new NSUrl(url);
            NSData data = NSData.FromUrl(url);
            image = UIImage.FromData(data);
            if (image != null) {
                this.cache[url] = image;
            }
        }

        return image;
    }

    public UIImage this[string url] {
        get { return this.ImageForUrl(url); }
    }
}

我刚写了它并没有尝试过,但它应该做的伎俩。像

一样使用它
UIImage image = ImageCache.SharedInstance["blabla.png"];

注意:poupou还有一个错误,解释了每次更新时添加视图的位置。

答案 2 :(得分:0)

我的问题是图像,这里是如何使用MonoTouch.Dialog.Utilities.ImageLoader解决问题

using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.Dialog.Utilities;

namespace Zurfers.Mobile.iOS
{
    public class CustomCell : UITableViewCell, IImageUpdated
    {
        UILabel headingLabel, subheadingLabel, priceLabel;
        UIImageView imageService;
        UIImageView star, star2, star3, star4, star5;
        public CustomCell (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
        {
            imageService = new UIImageView();
            star   = new UIImageView();
            star2  = new UIImageView();
            star3  = new UIImageView();
            star4  = new UIImageView();
            star5  = new UIImageView();
            headingLabel = new UILabel(){
                Font = UIFont.FromName("Verdana-Bold", 14f),
                BackgroundColor = UIColor.Clear,
                TextColor = UIColor.FromRGB(241, 241, 211)
            };
            subheadingLabel = new UILabel(){
                Font = UIFont.FromName("Verdana-Bold", 8f),
                TextColor = UIColor.FromRGB(255, 255, 255),
                BackgroundColor = UIColor.Clear
            };
            priceLabel = new UILabel(){
                Font = UIFont.FromName("Verdana", 14f),
                TextColor = UIColor.FromRGB(241, 241, 211),
                BackgroundColor = UIColor.Clear
            };

            AddSubview(imageService);
            AddSubview(headingLabel);
            AddSubview(subheadingLabel);
            AddSubview(priceLabel);
            AddSubview(star);
            AddSubview(star2);
            AddSubview(star3);
            AddSubview(star4);
            AddSubview(star5);

        }

        public void UpdateCell (string title, string subtitle, string price, string imageUlr, string rating )
        {
            if (imageUlr != null) {
                var u = new Uri(imageUlr);
                ImageLoader MyLoader= new ImageLoader(50,50);
                imageService.Image = MyLoader.RequestImage(u,this);

            } else {
                imageService.Image = UIImage.FromFile("generic_no_image_tiny.jpg");
            }


            headingLabel.Text = title;
            subheadingLabel.Text = subtitle;
            if (subtitle.Length > 40) {
                subheadingLabel.LineBreakMode = UILineBreakMode.WordWrap;
                subheadingLabel.Lines = 0;
            }

            switch (rating) {
                case "T":
                    star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    break;
                case "S":
                    star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    break;
                case "F":
                    star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star4.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    break;
                case "L":
                    star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star4.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    star5.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
                    break;
            }


            priceLabel.Text = "USD" + price;
            priceLabel.Font = UIFont.BoldSystemFontOfSize (16);
        }


        public void UpdatedImage (Uri uri)
        {
            imageService.Image = ImageLoader.DefaultRequestImage(uri, this);
        }


        public override void LayoutSubviews ()
        {
            base.LayoutSubviews ();
            imageService.Frame = new RectangleF(10, 10, 50, 33);
            headingLabel.Frame = new RectangleF(70, 4, 240, 25);
            subheadingLabel.Frame = new RectangleF(70, 25, 240, 20);
            priceLabel.Frame = new RectangleF(220, 45, 100, 20);
            star.Frame = new RectangleF(70, 45, 15, 15);
            star2.Frame = new RectangleF(85, 45, 15, 15);
            star3.Frame = new RectangleF(100, 45, 15, 15);
            star4.Frame = new RectangleF(115, 45, 15, 15);
            star5.Frame = new RectangleF(130, 45, 15, 15);
        }
    }
}

非常感谢你的帮助。