La différence entre Vérifié et Activé est en fait assez intéressante. Même la documentation Google s'excuse (soulignement ci-dessous ajouté):
... Par exemple, dans une vue de liste avec sélection unique ou multiple activée, les vues du jeu de sélection actuel sont activées. (Euh, oui, nous sommes profondément désolés pour la terminologie ici.) L'état activé est propagé aux enfants de la vue sur laquelle il est défini.
Voici donc la différence:
Activated a été introduit dans Honeycomb, vous ne pouvez donc pas l'utiliser avant cela
Activé est désormais une propriété de chaque vue. Il a les méthodes setActivated () et isActivated ()
Activé se propage aux enfants de la vue sur laquelle il est défini
Checked tourne autour d'une vue implémentant l'interface Checkable. Méthodes setChecked (), isChecked (), toggle ()
ListView (après Honeycomb) appelle setChecked () OU setActivated () selon la version Android comme ci-dessous (extrait du code source Android):
Notez la variable mCheckStates. Il garde une trace des positions de votre liste qui sont vérifiées / activées. Ceux-ci sont accessibles via, par exemple, getCheckedItemPositions (). Notez également qu'un appel à ListView.setItemChecked () appelle ce qui précède. En d'autres termes, il pourrait également être appelé setItemActivated ().
Avant Honeycomb, nous devions implémenter des solutions de contournement pour refléter state_checked dans nos éléments de liste. Ceci est dû au fait que ListView appelle setChecked () UNIQUEMENT sur la vue la plus haute de la mise en page (et les mises en page n'implémentent pas checkable) ... et il ne se propage PAS sans aide. Ces solutions de contournement étaient de la forme suivante: Étendez la disposition racine pour implémenter Checkable. Dans son constructeur, recherchez récursivement tous les enfants qui implémentent Checkable. Lorsque setChecked () etc ... sont appelés, passez l'appel à ces vues. Si ces vues implémentent des listes d'états dessinables (par exemple une CheckBox) avec un dessin différent pour state_checked alors l'état vérifié est reflété dans l'interface utilisateur.
Pour faire un joli arrière-plan à un élément de liste après Honeycomb, tout ce que vous devez faire est d'avoir une liste d'états dessinable avec un dessinable pour l'état state_activated comme ceci (et utilisez bien sûr setItemChecked ()):
Pour créer un joli arrière-plan sur un élément de liste avant HoneyComb, vous feriez quelque chose comme ci-dessus pour state_checked et vous devez ÉGALEMENT étendre votre vue supérieure pour implémenter l'interface Checkable. Dans ce contexte, vous devez ensuite indiquer à Android si l'état que vous implémentez est vrai ou faux en implémentant onCreateDrawableState () et en appelant refreshDrawableState () chaque fois que l'état change.
cette réponse n'a pas de prix. J'aurais aimé le lire avant d'essayer de savoir comment mettre en œuvre une mise en page Checkable, etc. Merci beaucoup.
Blake Mumford le
12
excellente réponse, mais ne traite pas des éléments "sélectionnés". J'ai trouvé la réponse dans les phrases juste avant celle que vous avez citée: Selection is a transient property, representing the view (hierarchy) the user is currently interacting with. Activation is a longer-term state that the user can move views in and out of. For example, in a list view with single or multiple selection enabled, the views in the current selection set are activated. (Um, yeah, we are deeply sorry about the terminology here.)source
woojoo666
ma couleur d'arrière-plan personnalisée n'apparaît que derrière les éléments sélectionnés / ciblés, non les éléments cochés, lorsque vous utilisez la méthode post-Honeycomb que vous avez publiée ci-dessus: appel setItemChecked()puis utilisation d'un sélecteur avec une propriétéandroid:state_activated="true"
woojoo666
1
Merci beaucoup, j'ai perdu 3 jours à essayer de comprendre cela jusqu'à ce que je décide enfin de me demander "quelle est la différence entre coché, sélectionné et activé", craint que gérer quelque chose d'aussi simple qu'un menu doive être aussi compliqué, sur-ingénierie par les génies de Google, semble presque être un obstacle mis exprès par cette société pour en ralentir les autres.
android: booléen state_selected . " true" si cet élément doit être utilisé lorsque l'objet est la sélection actuelle de l'utilisateur lors de la navigation avec une commande directionnelle (comme lors de la navigation dans une liste avec un pavé directionnel); " false" si cet élément doit être utilisé lorsque l'objet n'est pas sélectionné. L'état sélectionné est utilisé lorsque le focus (android: state_focused) n'est pas suffisant (par exemple lorsque la vue de liste a le focus et qu'un élément qu'il contient est sélectionné avec un d-pad).
android: booléen state_checked . " true" si cet élément doit être utilisé lorsque l'objet est vérifié; " false" s'il doit être utilisé lorsque l'objet n'est pas coché.
android: state_activated Boolean . " true" si cet élément doit être utilisé lorsque l'objet est activé en tant que sélection persistante (par exemple pour "mettre en surbrillance" l'élément de liste précédemment sélectionné dans une vue de navigation persistante); " false" s'il doit être utilisé lorsque l'objet n'est pas activé. Introduit au niveau d'API 11 .
Je pense que la doc est assez claire, alors quel est le problème?
Pouvez-vous élaborer sur Android: state_selected. Dans quelles circonstances il est défini sur vrai?
Anderson le
@Anderson cela dépendra du ViewGroup que vous utilisez - ListView, RecyclerView (probablement ses LayoutManagers), GridView peut avoir des implémentations différentes: ListView appelle setFocused là où GridView appelle setSelected par exemple. Il peut s'agir simplement de vérifier votre application sur différentes versions de plate-forme.
ataulm
1
@Anderson: Si vous avez une liste et que l'utilisateur a des touches fléchées, l'une est "sélectionnée", et quand elles fléchent vers le haut / bas, la sélection se déplace vers le haut / vers le bas. Quand ils appuient sur la touche "activer", cela "active" le contrôle, pensez à sa sélection comme vaguement apparentée au survol de la souris, et la vérification / activation comme vaguement semblable à un clic.
Mooing Duck
Je me demandais, je vais utiliser activé pour mettre en surbrillance un élément dans une vue de liste, mais est-ce que cela définit l'activation des autres éléments de la liste sur false ... si ce n'est pas le cas, faites-le pour ne pas avoir à trouver l'autre élément enfant activé et définissez l'activation sur false?
J'ai remplacé la méthode setOnItemClickListener et vérifié les différents cas dans le code. Mais définitivement la solution de Marvin est bien meilleure.
listView.setOnItemClickListener(newOnItemClickListener(){@Overridepublicvoid onItemClick(AdapterView<?> adapterView,View view,int position,long id){CheckedTextView checkedTextView =(CheckedTextView)view.findViewById(R.id.checkedTextView);// Save the actual selected row databooleanchecked= checkedTextView.isChecked();int choiceMode = listView.getChoiceMode();switch(choiceMode){// Not choosing anythingcase(ListView.CHOICE_MODE_NONE):// Clear all selected data
clearSelection();//printCheckedElements();break;// Single choicecase(ListView.CHOICE_MODE_SINGLE):// Clear all the selected data// Revert the actual row data
clearSelection();
toggle(checked, checkedTextView, position);//printCheckedElements();break;// Multiple choicecase(ListView.CHOICE_MODE_MULTIPLE):case(ListView.CHOICE_MODE_MULTIPLE_MODAL):// Revert the actual selected row data
toggle(checked, checkedTextView, position);//printCheckedElements();break;}}});
Réponses:
La différence entre Vérifié et Activé est en fait assez intéressante. Même la documentation Google s'excuse (soulignement ci-dessous ajouté):
Voici donc la différence:
ListView (après Honeycomb) appelle setChecked () OU setActivated () selon la version Android comme ci-dessous (extrait du code source Android):
Notez la variable mCheckStates. Il garde une trace des positions de votre liste qui sont vérifiées / activées. Ceux-ci sont accessibles via, par exemple, getCheckedItemPositions (). Notez également qu'un appel à ListView.setItemChecked () appelle ce qui précède. En d'autres termes, il pourrait également être appelé setItemActivated ().
Avant Honeycomb, nous devions implémenter des solutions de contournement pour refléter state_checked dans nos éléments de liste. Ceci est dû au fait que ListView appelle setChecked () UNIQUEMENT sur la vue la plus haute de la mise en page (et les mises en page n'implémentent pas checkable) ... et il ne se propage PAS sans aide. Ces solutions de contournement étaient de la forme suivante: Étendez la disposition racine pour implémenter Checkable. Dans son constructeur, recherchez récursivement tous les enfants qui implémentent Checkable. Lorsque setChecked () etc ... sont appelés, passez l'appel à ces vues. Si ces vues implémentent des listes d'états dessinables (par exemple une CheckBox) avec un dessin différent pour state_checked alors l'état vérifié est reflété dans l'interface utilisateur.
Pour faire un joli arrière-plan à un élément de liste après Honeycomb, tout ce que vous devez faire est d'avoir une liste d'états dessinable avec un dessinable pour l'état state_activated comme ceci (et utilisez bien sûr setItemChecked ()):
Pour créer un joli arrière-plan sur un élément de liste avant HoneyComb, vous feriez quelque chose comme ci-dessus pour state_checked et vous devez ÉGALEMENT étendre votre vue supérieure pour implémenter l'interface Checkable. Dans ce contexte, vous devez ensuite indiquer à Android si l'état que vous implémentez est vrai ou faux en implémentant onCreateDrawableState () et en appelant refreshDrawableState () chaque fois que l'état change.
... et le code pour implémenter Checkable combiné avec state_checked dans un RelativeLayout pourrait être:
Merci à ce qui suit:
http://sriramramani.wordpress.com/2012/11/17/custom-states/
Stackoverflow: comment ajouter un état de bouton personnalisé
Stackoverflow: vue vérifiable personnalisée qui répond au sélecteur
http://www.charlesharley.com/2012/programming/custom-drawable-states-in-android/
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
http://blog.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
la source
Selection is a transient property, representing the view (hierarchy) the user is currently interacting with. Activation is a longer-term state that the user can move views in and out of. For example, in a list view with single or multiple selection enabled, the views in the current selection set are activated. (Um, yeah, we are deeply sorry about the terminology here.)
sourcesetItemChecked()
puis utilisation d'un sélecteur avec une propriétéandroid:state_activated="true"
D'après le doc :
android: booléen state_selected . "
true
" si cet élément doit être utilisé lorsque l'objet est la sélection actuelle de l'utilisateur lors de la navigation avec une commande directionnelle (comme lors de la navigation dans une liste avec un pavé directionnel); "false
" si cet élément doit être utilisé lorsque l'objet n'est pas sélectionné. L'état sélectionné est utilisé lorsque le focus (android: state_focused) n'est pas suffisant (par exemple lorsque la vue de liste a le focus et qu'un élément qu'il contient est sélectionné avec un d-pad).android: booléen state_checked . "
true
" si cet élément doit être utilisé lorsque l'objet est vérifié; "false
" s'il doit être utilisé lorsque l'objet n'est pas coché.android: state_activated Boolean . "
true
" si cet élément doit être utilisé lorsque l'objet est activé en tant que sélection persistante (par exemple pour "mettre en surbrillance" l'élément de liste précédemment sélectionné dans une vue de navigation persistante); "false
" s'il doit être utilisé lorsque l'objet n'est pas activé. Introduit au niveau d'API 11 .Je pense que la doc est assez claire, alors quel est le problème?
la source
Voici une autre solution à ce problème: https://github.com/jiahaoliuliu/CustomizedListRow/blob/master/src/com/jiahaoliuliu/android/customizedlistview/MainActivity.java
J'ai remplacé la méthode setOnItemClickListener et vérifié les différents cas dans le code. Mais définitivement la solution de Marvin est bien meilleure.
la source