【问题标题】:Android list images gets reloaded when scrolling up/back (using lazy loading, Picasso and android data binding)Android 列表图像在向上/向后滚动时重新加载(使用延迟加载、Picasso 和 android 数据绑定)
【发布时间】:2016-12-07 13:04:27
【问题描述】:

我有一个非常常见的场景 - 带有图像和标题的项目的回收站视图。

我正在尝试使用 Android 数据绑定库来实现 MVVM 模式。

我正在使用 Picasso 库加载图像。

除了我有问题要解决的一件事之外,一切都像魅力一样 当我向后/向上滚动列表时,图像会重新加载。

比如我第一次进入屏幕:

1.) 我看到占位符

2.) 加载真实图像后不久

3.) 向下滚动 - 我看到更多占位符(这很好,延迟加载)

4.) 加载其他图像后不久(很棒)

5.) 向上滚动 - 我看到占位符 -???问题 - 如何避免这种情况,而是显示以前加载的图像?

这是代码(我已将其简化为相关部分):

ContactListAdapter.java

public class ContactListAdapter extends RecyclerView.Adapter<ContactListAdapter.ViewHolder> {

private List<Contact> items;

public Contact ListAdapter() {
    this.items = Collections.emptyList();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    ContactItemBinding itemBinding =
            DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.contact_item,
                    parent, false);
    return new ViewHolder(itemBinding);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bindItems(items.get(position));
}

@Override
public int getItemCount() {
    return items.size();
}

public void setList(List<Contact> items) {
    this.items = items;
    notifyDataSetChanged();
}

public static class ViewHolder extends RecyclerView.ViewHolder {
    ContactItemBinding itemBinding;

    public ViewHolder(ContactItemBinding contactItemBinding) {
        super(contactItemBinding.habitItem);
        this.itemBinding = habitItemBinding;
    }

    void bindItems(Contact item) {
        if (itemBinding.getViewModel() == null) {
            itemBinding.setViewModel(
                    new ContactItemViewModel(item, itemView.getContext()));
        } else {
            itemBinding.getViewModel().setItem(item);
        }
    }
}

}

ContactItemViewModel.java

public class ContactItemViewModel extends BaseObservable {

private Contact item;
private Context context;

public Contact getItem() {
    return item;
}

public ContactItemViewModel(Contact item, Context context) {
    this.item = item;
    this.context = context;
}

public void onItemClick(View view) {
    context.startActivity(ContactDetailActivity.launchDetail(view.getContext(), item));
}

public void setItem(Contact item) {
    this.item = item;
    notifyChange();
}

@BindingAdapter("android:src")
public static void loadImage(ImageView view, String imageUrl) {
    Picasso.with(view.getContext())
            .load(imageUrl)
            .placeholder(R.drawable.loading_image)
            .error(R.drawable.error_image)
            .into(view);
}

}

contact_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>

        <variable
            name="viewModel"
            type="com.example.danijela.sparkle.viewmodel.ContactItemViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/contact_image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@{viewModel.item.imageUrl}" />

        <TextView
            android:id="@+id/contact_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@{viewModel.item.fullName}" />

    </LinearLayout>

</layout>

【问题讨论】:

  • 尝试在毕加索代码中添加内存和网络策略。
  • 你检查Picasso.resumeTagPicasso.PauseTag了吗?它在滚动时暂停/恢复毕加索图像加载
  • Divyesh,这不应该是毕加索的默认行为(内存 + 磁盘捕获)吗?

标签: android mvvm android-recyclerview picasso android-databinding


【解决方案1】:

我认为你的代码有问题在onCreateViewHolder(),应该是这样的

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.contact_item, parent, false);
    return new ViewHolder(v);
}

您的 ViewHolder 构造函数应该如下所示,在构造函数中您将绑定您的 listItem

public ViewHolder(View v) {
    super(v);
    itemBinding = DataBindingUtil.bind(view);;
}

更多详情请参考RecyclerView With Android DataBinding

【讨论】:

  • 对不起,回复晚了,谢谢,我已经尝试过你的解决方案,但我的问题和我的一样。您是否尝试过使用更多项目(超过屏幕高度)的解决方案?向上滚动时不会重新加载吗?
猜你喜欢
  • 2013-11-09
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多