Comment pouvez-vous masquer un élément dans un ListView ou au moins définir sa hauteur à zéro?
J'ai essayé de régler la visibilité de la vue sur GONE, mais il conserve toujours l'espace (hauteur) de l'élément.
Resserrer une vieille question, mais je venais de rencontrer ce problème dans lequel je voulais masquer temporairement les éléments de la liste en fonction de critères extérieurs à la liste. Ce que je finis par faire fut de créer une mise en page "Null Item" dans XML et de la renvoyer en fonction de mes critères plutôt que de la vue convertie dans getView ().
au lieu de renvoyer convertView, j'ai renvoyé mon null_item ...
return inflater.inflate(R.layout.null_item, null);
null_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</LinearLayout>
si vous voulez masquer l'élément comme ceci:
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
convertView.setVisibility(View.GONE);
ne peut pas être AbsListView.LayoutParams (-1,0);
si convertview est réutilisé, vous devriez ajouter ceci ci-dessous pour le régler en hauteur:
if(convertView.getVisibility() == View.GONE) {
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
convertView.setVisibility(View.VISIBLE);
}
Pour optimiser l'efficacité de ListView, nous utilisons le modèle ViewHolder. Comment utiliser ViewHolder Pattern et R.layout.row_null du fichier XML suivant
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</LinearLayout>
est à utiliser avec getViewTypeCount () et getItemViewType (int position) comme suit.
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
return (hideStatusCheck(position)) ? 1 : 0;
}
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
if (hideStatusCheck(pos)) {
if (rowView == null || rowView.getTag() != null) {
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.row_null, parent, false);
}
} else {
if (rowView == null) {
rowView = inflateNormalView(parent);
} else if (rowView.getTag() == null) {
rowView = inflateNormalView(parent);
} else {
ViewHolder holderToCheck = (ViewHolder) rowView.getTag();
Integer storedPos = (Integer) holderToCheck.getTag(POSITION);
if (storedPos == null || storedPos != pos)
rowView = inflateNormalView(parent);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.setTag(POSITION,pos);
/*
Populate data
*/
return rowView;
}
private View inflateNormalView(ViewGroup parent) {
View rowView;
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.normal_item, parent, false);
ViewHolder viewHolder = new ViewHolder();
assert rowView != null;
/* Initiate normal findViewById thing*/
rowView.setTag(viewHolder);
return rowView;
}
Nous vérifions le type de vue de l'élément et, s'il répond au contrôle de masquage, il renverra 1, sinon 0. ListView sait qu'il y aura 2 types de vue de getViewTypeCount. À présent, getView renverra la vue appropriée en fonction de hideStatusCheck. Pour créer un ListView robuste, nous souhaitons utiliser le modèle ViewHolder. Nous n'avons pas besoin d'utiliser ViewHolder lorsqu'il est masqué. Nous gonflons simplement le R.layout.row_null et le retournons. Nous allons utiliser le ViewHolder pour le R.layout.normal_item. Voici la partie délicate en supposant que le test de dissimulation n’est pas statique. La première vérification de rowView==null
est standard. La deuxième vérification de rowView.getTag()==null
consiste à vérifier si la vue revient à la normale après s’être cachée. La troisième vérification de la dernière clause else
consiste à vérifier si ViewHolder conservé dans la balise est le droit ViewHolder. Si ces conditions sont remplies, nous gonflons toujours à nouveau la vue. Oui, il est vrai que le modèle ViewHolder n’est pas utilisé dans l’ensemble, mais qu’il l’utilise dans certains cas. C'est mieux que rien.
J'ai regarder le code source. Et il n'y a qu'un seul moyen de masquer un élément sans notifyDataSetChanged()
. Vous devez définir la visibilité GONE
pour toutes les vues intérieures et supprimer l'image d'arrière-plan et les marges de la vue de l'élément.
Remarque: La ligne avec cet élément invisible sera sélectionnable.
P.S: Ceci est très utile pour ExpandableListView
si vous voulez masquer le groupe lui-même.
J'ai fait du bricolage avec une liste de glisser-déposer de ici . Lorsqu'un élément est extrait de la liste pour être déplacé dans l'espace de la cellule qu'il occupe, sa hauteur est définie sur 1px (voir la ligne 238), de sorte qu'il apparaît "parti". Je ne pouvais pas trouver un meilleur moyen de gérer cela, car régler la hauteur sur 0 échoue, tout comme la visibilité GONE.
Cela dit, si vous voulez vraiment vous débarrasser temporairement d’une ligne, il peut être judicieux de modifier le support de la variable Adapter
et d’appeler notifyDataSetChanged()
dessus.
ajouter à votre objet ListView: Android: dividerHeight = "0px" Android: divider = "# FFFFFF"
La couleur du séparateur n'a pas d'importance, seul le réglage de dividerHeight ne fonctionne pas
Cela supprime le diviseur si ...
Je pense avoir une solution beaucoup plus simple et plus sûre: vous devez simplement "incorporer" votre élément dans une mise en page et modifier la visibilité de cette mise en page parent.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal" >
<!-- Embed ListView Item into a "parent" Layout -->
<LinearLayout
Android:id="@+id/parentLayout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal" >
<!-- This is the normal content of your ListView Item -->
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Hello" />
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="World" />
</LinearLayout>
</LinearLayout>
Ensuite, dans votre code, faites simplement:
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater li = mActivity.getLayoutInflater();
view = li.inflate(R.layout.my_listview_item, null);
}
LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout);
if (shouldDisplayItem(position)) {
parentLayout.setVisibility(View.VISIBLE);
} else {
parentLayout.setVisibility(View.GONE);
}
return view;
}
De cette façon, vous utilisez/réutilisez toujours le même élément, et vous ne l’affichez/l’affichez.