Je suis confronté à un problème très courant: j'ai mis en page une activité et il s'avère maintenant qu'elle devrait afficher quelques éléments à l'intérieur ScrollView
. La manière normale de faire cela serait d'utiliser l'existant ListAdapter
, de le connecter à un ListView
et BOOM j'aurais ma liste d'articles.
MAIS vous ne devriez pas placer un imbriqué ListView
dans un ScrollView
car il bousille le défilement - même Android Lint s'en plaint.
Alors voici ma question:
Comment connecter un ListAdapter
à un LinearLayout
ou quelque chose de similaire?
Je sais que cette solution ne s'adapte pas à beaucoup d'éléments, mais mes listes sont très courtes (<10 éléments), donc la réutilisation des vues n'est pas vraiment nécessaire. En termes de performances, je peux vivre en plaçant toutes les vues directement dans le LinearLayout
.
Une solution que j'ai trouvée serait de placer ma disposition d'activité existante dans la section headerView du ListView
. Mais cela donne l'impression d'abuser de ce mécanisme, alors je cherche une solution plus propre.
Des idées?
MISE À JOUR: Afin d'inspirer la bonne direction, j'ajoute un exemple de mise en page pour montrer mon problème:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/news_detail_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="visible">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFF"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/news_detail_layout_side_padding"
android:paddingRight="@dimen/news_detail_layout_side_padding"
android:paddingTop="@dimen/news_detail_layout_vertical_padding"
android:paddingBottom="@dimen/news_detail_layout_vertical_padding"
>
<TextView
android:id="@+id/news_detail_date"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:text="LALALA"
android:textSize="@dimen/news_detail_date_height"
android:textColor="@color/font_black"
/>
<Gallery
android:id="@+id/news_detail_image"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:paddingTop="5dip"
android:paddingBottom="5dip"
/>
<TextView
android:id="@+id/news_detail_headline"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:text="Some awesome headline"
android:textSize="@dimen/news_detail_headline_height"
android:textColor="@color/font_black"
android:paddingTop="@dimen/news_detail_headline_paddingTop"
android:paddingBottom="@dimen/news_detail_headline_paddingBottom"
/>
<TextView
android:id="@+id/news_detail_content"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Here comes a lot of text so the scrollview is really needed."
android:textSize="@dimen/news_detail_content_height"
android:textColor="@color/font_black"
/>
<!---
HERE I NEED THE LIST OF ITEMS PROVIDED BY THE EXISTING ADAPTER.
They should be positioned at the end of the content, so making the scrollview smaller is not an option.
---->
</LinearLayout>
</ScrollView>
</LinearLayout>
MISE À JOUR 2 J'ai changé le titre pour le rendre plus facile à comprendre (j'ai obtenu un vote défavorable, doh!).
la source
Réponses:
Vous devriez probablement simplement ajouter manuellement vos éléments à
LinearLayout
:EDIT : J'ai rejeté cette approche quand j'avais besoin d'afficher environ 200 éléments de liste non triviaux, c'est très lent - Nexus 4 avait besoin d'environ 2 secondes pour afficher ma "liste", ce qui était inacceptable. Je me suis donc tourné vers l'approche de Flo avec des en-têtes. Cela fonctionne beaucoup plus rapidement car les vues de liste sont créées à la demande lorsque l'utilisateur fait défiler, et non au moment de la création de la vue.
Resume: L'ajout manuel de vues à la mise en page est plus facile à coder (donc potentiellement moins de pièces mobiles et de bugs), mais souffre de problèmes de performances, donc si vous avez 50 vues ou plus, je vous conseille d'utiliser l'approche d'en-tête.
Exemple. Fondamentalement, la disposition de l'activité (ou du fragment) se transforme en quelque chose comme ça (plus besoin de ScrollView):
Ensuite, dans
onCreateView()
(je vais utiliser un exemple avec un fragment), vous devez ajouter une vue d'en-tête, puis définir un adaptateur (je suppose que l'ID de ressource d'en-tête estheader_layout
):la source
ListAdapter
et laListView
magie fait plus derrière les écrans que je ne fais alors pas manuellement.notifyDataSetChanged
méthode de l'adaptateur ? Cela fonctionne bien sur un adaptateur différent que j'ai connecté à unListView
, mais cela ne semble pas fonctionner avec celui que j'ai connecté à unLinearLayout
.Je m'en tiendrai à la solution de vue d'en-tête. Il n'y a rien de mal à cela. En ce moment, je mets en œuvre une activité en utilisant exactement la même approche.
De toute évidence, la "partie élément" est plus dynamique que statique (nombre d'éléments variable par rapport au nombre d'éléments corrigés, etc.) sinon vous ne penserez pas du tout à utiliser un adaptateur. Ainsi, lorsque vous avez besoin d'un adaptateur, utilisez ListView.
L'implémentation d'une solution qui remplit un LinearLayout à partir d'un adaptateur n'est finalement rien d'autre que la construction d'un ListView avec une disposition personnalisée.
Juste mes 2 cents.
la source
ListView
. Pas sûr que j'aime ce travail de patch.Définissez votre vue sur main.xml onCreate, puis gonflez à partir de row.xml
main.xml
row.xml
la source
J'utilise le code suivant qui réplique la fonctionnalité de l'adaptateur avec
ViewGroup
etTabLayout
. La bonne chose à ce sujet est que si vous modifiez votre liste et liez à nouveau, cela n'affectera que les éléments modifiés:Usage:
Pour
ViewGroups
:Car
TabLayout
j'ai ceci:la source