web-dev-qa-db-fra.com

Liaison de données Android avec adaptateur personnalisé

J'essaie d'utiliser les fonctions de liaison de données d'Android avec un adaptateur personnalisé et un ListView. Je ne parviens pas à remplacer la méthode getView de l'adaptateur personnalisé:

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?
    }

}

Donc mes questions sont:

  • Où puis-je obtenir l'élément View que je devrais retourner? Ou, en d'autres termes, comment puis-je lier l'objet à une vue gonflée/convertie?
  • Comment puis-je réutiliser convertView lors de l'utilisation de la liaison de données?
  • Est-ce la bonne façon de mettre cela en œuvre? Le guide n'est pas très clair sur ListViews

Voici la seule référence de ListViews dans le guide:

Si vous utilisez des éléments de liaison de données dans un adaptateur ListView ou RecyclerView, vous préférerez peut-être utiliser:

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

Selon this , vous devriez retourner binding.getRoot().

View getRoot ()

Renvoie la vue la plus externe dans le fichier de mise en page associé à la liaison . Si cette liaison concerne un fichier de mise en forme de fusion, cela renverra La première racine de la balise de fusion.

10
csenga

Vous devez cependant procéder comme suit pour un défilement régulier.

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

Pour compléter voici la variante 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

La méthode recommandée consiste à utiliser la classe Binding générée au lieu de la classe DataBindingUtil. Voir Documentation.

Si vous utilisez des éléments de liaison de données dans un adaptateur Fragment, ListView ou RecyclerView, vous préférerez peut-être utiliser les méthodes inflate() de Les classes de liaison.

Utilisation

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

au lieu de

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

L'autre code sera identique à @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;
}
0
Khemraj
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