web-dev-qa-db-ja.com

Androidカスタムアダプターを使用したデータバインディング

Androidのデータバインディング機能 をカスタムアダプタとListViewで使用しようとしています。カスタムアダプタのgetViewメソッドを上書きするのに問題があります。

public class ChecksAdapter extends ArrayAdapter<Check> {

    public ChecksAdapter(Context context, ObservableList<Check> checks) {
        super(context, R.layout.check, checks);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        CheckBinding binding = DataBindingUtil.inflate(
                LayoutInflater.from(getContext()),
                R.layout.check, parent, false);
        binding.setCheck(this.getItem(position));

        // Return what?
    }

}

だから私の質問は:

  • 返す必要のあるView要素はどこで入手できますか?つまり、オブジェクトを膨張/変換されたビューにバインドするにはどうすればよいですか?
  • データバインディングを使用するときにconvertViewを再利用するにはどうすればよいですか?
  • これはこれを実装する正しい方法ですか?リストビューのガイドはあまり明確ではありません

ガイド内のListViewsの唯一のリファレンスは次のとおりです。

ListViewまたはRecyclerViewアダプター内でデータ・バインディング項目を使用している場合は、以下を使用することをお勧めします。

   ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
   //or
   ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
15
jlhonora

this によると、binding.getRoot()を返す必要があります。

View getRoot ()

バインディングに関連付けられたレイアウトファイルの最も外側のビューを返します。このバインディングがマージレイアウトファイル用である場合、これはマージタグの最初のルートを返します。

10
csenga

ただし、スムーズにスクロールするには、次のようにする必要があります。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CheckBinding binding;
    if(convertView == null) {
        binding = DataBindingUtil.inflate(
                LayoutInflater.from(getContext()),
                R.layout.check, parent, false);
        convertView = binding.getRoot();
    }
    else {
        binding = (CheckBinding) convertView.getTag();
    }

    binding.setCheck(this.getItem(position));
    convertView.setTag(binding);
    return convertView;
}
22
sergi

推奨される方法

DataBindingUtilクラスの代わりに生成されたBindingクラスを使用します。 ドキュメント を参照してください

FragmentListView、またはRecyclerViewアダプター内でデータバインディングアイテムを使用している場合は、バインディングクラスのinflate()メソッドを使用することをお勧めします。

使用する

binding = CheckBinding.inflate(this, parent, false);

の代わりに

binding = DataBindingUtil.inflate(
                LayoutInflater.from(getContext()),
                R.layout.check, parent, false);

他のコードは@sergiと同じになります

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CheckBinding binding;
    if(convertView == null) {
        binding = CheckBinding.inflate(this, parent, false);
        convertView = binding.getRoot();
    }
    else {
        binding = (CheckBinding) convertView.getTag();
    }

    binding.setCheck(this.getItem(position));
    convertView.setTag(binding);
    return convertView;
}
1
Khemraj

完全なものについては、kotlinバリアントがあります:

    val binding = convertView?.tag as? CheckBinding ?: CheckBinding.inflate(layoutInflater, parent, false)
    binding.check = this.getItem(position)
    binding.root.tag = binding

    return binding.root
1
Calin
ItemTickFilterBinding mFilterBinding;

    if (convertView==null) {
        mFilterBinding= DataBindingUtil.inflate(
                LayoutInflater.from(mContext),
                R.layout.item_tick_filter, parent, false);
        convertView.setTag(mFilterBinding);
    }
    else {
        mFilterBinding=(ItemTickFilterBinding)convertView.getTag();
    }
0
smith kashyap