滚动向上/向后(使用延迟加载,毕加索和Android数据绑定)重新加载Android列表图像

时间:2016-12-07 13:04:27

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

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

我正在尝试使用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>

1 个答案:

答案 0 :(得分:0)

我认为您的代码问题在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);;
}

请参阅ArrayList了解更多详情