如何在列表视图中使用 Android DataBinding 并仍然使用 ViewHolder 模式?

How can I use Android DataBinding in a listview and still use a ViewHolder pattern?

我有一个 Android activity 从适配器 class.

内的可观察列表中提取数据

我的适配器 class 中的 getView() 方法是:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (inflater == null) {
        inflater = (LayoutInflater) parent.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    // Perform the binding
    ActivityTeamMessageListRowBinding binding = DataBindingUtil.inflate(inflater, R.layout.my_activity_list_row, parent, false);
    binding.setInfo(list.get(position));
    binding.executePendingBindings();

    // Return the bound view
    return binding.getRoot();
}

这很管用。但是,我在 ActivityTeamMessageListRowBinding binding ... 行的视图适配器 中看到 Android-警告 无条件布局 inflation。

我一直在研究 ViewHolders 来解决这个问题,但我似乎无法弄清楚如何完成这个并仍然使用我的数据绑定。据推测,列表越长,我在不使用 ViewHolder 的情况下看到的性能越差。

有谁知道如何扩展我的 getView(...) 代码以合并视图活页夹? 我有 3 个 TextView 和 1 个 ImageView 在我的 my_activity_list_row.xml.

试试这个:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (inflater == null) {
        inflater = ((Activity) parent.getContext()).getLayoutInflater();
    }

    // Perform the binding

    ActivityTeamMessageListRowBinding binding = DataBindingUtil.getBinding(convertView);

    if (binding == null) {
        binding = DataBindingUtil.inflate(inflater, R.layout.my_activity_list_row, parent, false);
    }

    binding.setInfo(list.get(position));
    binding.executePendingBindings();

    // Return the bound view
    return binding.getRoot();
}

我还没有使用 ListView 的数据绑定(我将使用 RecyclerView),但即兴发挥,这就是我要尝试的。使用断点或日志记录来确认,当 convertView 不是 null 时,您经常从 getBinding() 返回 binding(也许一直都是——我我不清楚数据绑定的缓存是如何工作的。

DataBindingUtil 已经实现了

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return getViewForResource(mResourceId, position, convertView, parent);
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return getViewForResource(mDropDownResourceId, position, convertView, parent);
}

public View getViewForResource(int resourceId, int position, View convertView, ViewGroup parent) {
    final ViewDataBinding binding = (convertView != null) 
                    ? DataBindingUtil.getBinding(convertView) 
                    : DataBindingUtil.inflate(mLayoutInflater, resourceId, parent, false);
    binding.setVariable(BR.viewModel, getItem(position));
    return binding.getRoot();
}