c# - 使用 Akavache 在 ListView 适配器中显示图像

标签 c# android listview xamarin akavache

我正在使用 Xamarin 开发跨平台应用程序。我找到了 Akavache,但我无法在 ListView 适配器中使用 Akavache 处理图像加载。它的工作真的很慢。所以我需要修复它或找到另一种方法来处理这个问题。我也找不到好的例子或样本。

我正在尝试使用 getView 方法在 Listview Adapter 中下载和加载图像,如下所示:

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        var view = convertView;
        ViewHolder holder = null;
        if (view != null) // otherwise create a new one
            holder = view.Tag as ViewHolder;

        if (holder == null)
        {
            holder = new ViewHolder();
            view = _activity.LayoutInflater.Inflate(Resource.Layout.Book_Item, null);
            holder.TextItem1 = view.FindViewById<TextView>(Resource.Id.TextItem1);
            holder.TextItem2 = view.FindViewById<TextView>(Resource.Id.TextItem2);
            holder.ImageView = view.FindViewById<ImageView>(Resource.Id.BookImage);
            getImage(position, holder.ImageView, image => holder.ImageView.SetImageDrawable(image.ToNative())); 
        }

        holder.TextItem1.Text = _list[position].volumeInfo.title;
        holder.TextItem2.Text = _list[position].volumeInfo.publishedDate;
        return view;
    }


    public async void getImage(int position, ImageView imageView, Action <IBitmap> setImage)
    {
        var image = await _cache.GetAnImage(_list[position].volumeInfo.imageLinks.smallThumbnail);
        setImage(image);
    }

在我的 DataCache 类中,我尝试通过以下方式获取图像,loadImageFromUrl 在滚动时没有按预期工作,重新加载图像花费了很多时间。 GetAndFetchLatest 和 GetOrFetchObject 方法给出 InvalidCastException。异常消息在最后。你有任何类似的例子或任何建议来解决我的问题吗?

    public async Task<IBitmap> GetAnImage(string imageUrl)
    {
        // return await BlobCache.InMemory.GetAndFetchLatest( imageUrl, async() => await DownloadImage(imageUrl), offset => true);
        // return await BlobCache.InMemory.GetOrFetchObject(imageUrl, async () => await DownloadImage(imageUrl));
        return await DownloadImage(imageUrl);
    }

    public async Task<IBitmap> DownloadImage(string imageUrl)
    {
        return await BlobCache.InMemory.LoadImageFromUrl(imageUrl, true, 100, 100);
    }

UNHANDLED EXCEPTION: 12-11 12:48:54.560 I/MonoDroid( 2017): System.InvalidCastException: Cannot cast from source type to destination type. 12-11 12:48:54.560 I/MonoDroid( 2017): at (wrapper castclass) object:__castclass_with_cache (object,intptr,intptr) 12-11 12:48:54.564 I/MonoDroid( 2017): at Akavache.JsonSerializationMixin+c__AnonStorey11[System.Byte[]].<>m__0 (System.Exception _) [0x00000] in <filename unknown>:0 12-11 12:48:54.564 I/MonoDroid( 2017): at System.Reactive.Linq.ObservableImpl.Catch2+_[System.Byte[],System.Exception].OnError (System.Exception error) [0x00000] in :0 12-11 12:48:54.572 I/MonoDroid( 2017): --- End of stack trace from previous location where exception was thrown --- 12-11 12:48:54.572 I/MonoDroid( 2017): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in :0 12-11 12:48:54.580 I/MonoDroid( 2017): at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow (System.Exception exception) [0x00000] in :0 12-11 12:48:54.580 I/MonoDroid( 2017): at System.Reactive.ExceptionHelpers.ThrowIfNotNull (System.Exception exception) [0x00000] in :0 12-11 12:48:54.580 I/MonoDroid( 2017): at System.Reactive.Subjects.AsyncSubject`1[Splat.IBitmap].GetResult () [0x00000] in :0 An unhandled exception occured.

更新: Paul 回答了我,所以现在我知道我不能将 GetOrFetchObject 与 IBitmap 一起使用,因为它们是 UI 元素。所以现在不需要异常消息了。 但是 loadImageFromUrl 方法在滚动时阻塞了我的 UI 线程。所以这对我来说仍然是个大问题。

最佳答案

我终于解决了这个问题。首先,我通过尝试不同的库 (MonoDroid.UrlImageViewHelper) 发现这不是 Akavache 问题 然后我认为这个问题可能与 ListView 本身有关。我是一名高级开发人员,所以我知道 ListView 优化,但我仍然在寻找新的优化策略,看看是否遗漏了什么。

首先我推荐你看看这个网站: http://leftshift.io/6-ways-to-make-your-lists-scroll-faster-than-the-wind

我已经知道其中的许多建议,但真正不同的是更改 ListView 的高度以匹配父内容和包装内容。您也可以尝试将其设置为 0dp。它产生相同的结果。

然后我找到了这个线程,它讲述了“match_parent”优化背后的故事

Why is 0dp considered a performance enhancement?

关于c# - 使用 Akavache 在 ListView 适配器中显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425301/

相关文章:

c# - 您会使用什么报告工具?

c# - 如何将组框锚定到左侧但允许组框在拉伸(stretch)时增长到最大宽度

android - 单个 StaggeredGridView 中有多个列?

java - 如何在 Android Spinner 的下拉菜单中启用快速滚动(拇指)?

c++ - 编辑 ListView 控件项

c# - 标签不会在 while 循环内更改值

android - 如何更改正在运行的 AlertDialog 的文本

来自 PreferenceActivity 的 Android SharedPreferences

java - android:SharedPreferences不保存数据

c# - 为什么不能直接调用扩展方法?