Android data binding with custom adapter

According to this, you should return binding.getRoot().

View getRoot ()

Returns the outermost View in the layout file associated with the Binding. If this binding is for a merge layout file, this will return the first root in the merge tag.


You should do the following for smooth scrolling though..

@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;
}

For completes here is the kotlin variant:

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

    return binding.root

Recommended way

Use generated Binding class instead of DataBindingUtil class. See Documentation.

If you are using data binding items inside a Fragment, ListView, or RecyclerView adapter, you may prefer to use the inflate() methods of the bindings classes

Use

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

instead of

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

Other code will be same as @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;
}