web-dev-qa-db-fra.com

L'élément de vue Recycler remplit toute la hauteur de la vue de recycleur après la mise à niveau de la bibliothèque de support de "23.1.1" à "23.2.1"

Auparavant, j'utilisais les anciennes bibliothèques de support suivantes "23.1.1".

compile 'com.Android.support:appcompat-v7:23.1.1'
compile 'com.Android.support:support-v4:23.1.1'
compile 'com.Android.support:preference-v7:23.1.1'
compile 'com.Android.support:preference-v14:23.1.1'
compile 'com.Android.support:design:23.1.1'
compile 'com.Android.support:recyclerview-v7:23.1.1'

Ça marche plutôt bien. Voici à quoi ressemble mon RecyclerView

enter image description here

Maintenant, je souhaite migrer vers "23.2.1", à cause de quelques corrections de bugs apportées.

compile 'com.Android.support:appcompat-v7:23.2.1'
compile 'com.Android.support:support-v4:23.2.1'
compile 'com.Android.support:preference-v7:23.2.1'
compile 'com.Android.support:preference-v14:23.2.1'
compile 'com.Android.support:design:23.2.1'
compile 'com.Android.support:recyclerview-v7:23.2.1'

Cependant, tout à coup, tous mes articles RecyclerView semblent remplir toute la hauteur de RecyclerView.

enter image description here

enter image description here

Voici l'extrait de code de mon fichier de mise en page: https://Gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb16

Ce qui me laisse vraiment perplexe, c'est que bien que j'utilise "wrap_content" Dans la présentation de mon élément de vue Recycler, cela ne fonctionne pas comme prévu.

Je n'utilise aucun gestionnaire de disposition personnalisé pour mon RecyclerView.

De http://developer.Android.com/tools/support-library/index.html , je me rends compte que 23.2.1 fait pas mal de changements sur RecyclerView cette fois.

  • Correction de bugs liés aux différentes méthodes de mesure. (Numéro 201856)
  • Réduction de la période de verrouillage durant laquelle RecyclerView n'autorise pas les modifications de l'adaptateur lors du calcul d'une présentation ou d'un défilement. (Numéro 202046)
  • Correction d'un crash lors de l'appel de notifyItemChanged() sur un élément non visible. (Numéro 202136)
  • Correction d'un crash qui se produit lorsque RecyclerView.LayoutManager Ajoute et supprime une vue dans la même passe de mesure. (Numéro 193958)

Ce que je soupçonne le plus, c’est https://code.google.com/p/Android/issues/detail?id=201856 , car il faut changer différentes mesures méthodes spec

Jusqu'ici, j'essaie de reproduire le problème avec un simple projet RecyclerView, avec 23.2.1 mais en vain! Il n'a pas "l'élément remplit le problème RecyclerView hauteur totale". Mon hypothèse est que mon projet simple ne simule pas la structure de mise en page complexe de mon projet de production. Mon projet de production a la disposition suivante

<Activity>
    <Fragment>
        <View Pager>
            <Fragment>
                <RecyclerView />
            </Fragment>
        </View Pager>
    </Fragment>
</Activity>

Après quelques heures de débogage, je ne parviens toujours pas à trouver la cause première d'un tel problème, aucun indice?

Merci.

Ce que j'avais essayé

J'avais essayé de changer RecyclerView

de

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"

à

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"

Ça a l'air bien au début. Cependant, lorsque vous effectuez un défilement, cela ne fonctionne pas comme prévu: https://www.youtube.com/watch?v=U2EChFn6WkI

MISE À JOUR: J'ai enfin trouvé la cause

C'est une erreur à mes côtés! Puisque j'ai besoin d'une marge différente pour le dernier élément de la ligne, voici le code de mon adaptateur.

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    final List<TransactionSummary> transactionSummaries = buyArray.transactionSummaries;

    if (position == transactionSummaries.size() - 1) {
        holder.itemView.setLayoutParams(lastLayoutParams);
    } else {
        holder.itemView.setLayoutParams(normalLayoutParams);
    }

Malheureusement, lastLayoutParams et normalLayoutParams sont initialisés en tant que

    normalLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );

    lastLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );

En utilisant LinearLayout.LayoutParams.WRAP_CONTENT, Résolvez le problème.

44
Cheok Yan Cheng

Mise à jour

Il semble que vous mettiez à jour le LayoutParam de votre View dans votre Adapter.

Il est possible de le savoir car votre interface utilisateur semble tout à fait correcte jusqu'à ce que vous commenciez à faire défiler. Cela signifie que votre code XML est correct tel qu'il est défini dans votre fichier de présentation XML.

Le fait que cela change après le début du défilement signifie qu'il y a une erreur de logique dans votre implémentation onBindViewHolder. C'est pourquoi l'erreur apparaît lorsque vous faites défiler l'écran vers le bas, puis l'erreur persiste lorsque vous faites défiler vers le haut.

Ancienne réponse

Votre problème est que votre diviseur est devenu voyou:

<View
    Android:layout_width="1px"
    Android:layout_height="match_parent"
    Android:background="?attr/buyPortfolioSeperatorBackground"
    Android:layout_marginRight="5dp"
    Android:layout_marginLeft="5dp" />

À des fins de test, définissez-le sur:

<View
    Android:layout_width="1px"
    Android:layout_height="30dp"
    Android:background="?attr/buyPortfolioSeperatorBackground"
    Android:layout_marginRight="5dp"
    Android:layout_marginLeft="5dp" />

Assurez-vous de changer les deux!

17
Knossos

J'avais un problème similaire. En fin de compte, le recycleur n'était pas le problème. Vérifiez que les mesures de vos éléments CardView se traduisent par quelque chose comme ceci:

<Android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    ...
/>

Si vous n'utilisez pas CardView, assurez-vous que l'élément que vous utilisez dans votre adaptateur pour la vue a Android:layout_height="wrap_content" et pas match_parent.

Si cela ne fonctionne pas, vous pouvez ajouter un autre attribut en définissant minHeight ou maxHeight pour l'élément de vue.

10
Patrick W

La bonne nouvelle:

Je peux vous indiquer la version exacte qui a modifié le comportement de RecyclerView: il ne s'agit pas d'un changement dans 23.2.1 mais plutôt d'un changement dans 23.2.0 (février 2016) . Plus précisement:

RecyclerView.LayoutManager n'ignore plus certains paramètres de RecyclerView.LayoutParams, tels que MATCH_PARENT dans le sens du défilement.

Remarque: ces restrictions levées peuvent entraîner un comportement inattendu dans vos présentations. Assurez-vous de spécifier les paramètres de présentation corrects.

En effet, si vous lancez les bibliothèques 23.2.0, vous verrez le même comportement. Ce comportement peut être simplifié dans votre cas en tant que:

Maintenant, quand vous avez les enfants de RecyclerView avec Android:layout_x="match_parent", cela affectera le Android:layout_x, ce qui n’était pas le cas dans les versions 23.1.1 et antérieures.

La mauvaise nouvelle:

Même si je suis sûr à 99% que c'est la raison de votre problème, je ne vois toujours aucun problème dans votre code. J'ai en fait configuré RecyclerView avec votre structure XML (en modifiant uniquement les paramètres couleur/arrière-plan), avec LinearLayoutManager et fonctionne comme prévu dans 23.2.1. Je peux partager mon implémentation si vous souhaitez effectuer un contrôle de cohérence.

Vous devez vérifier deux fois l’implémentation/manipulation de votre adaptateur, même s’il est très étendu.

8
Sevle

Pour résoudre ce problème, row_layout devrait avoir une hauteur fixe ou wrap_content! J'ai également eu ce problème et je viens de me rendre compte que la hauteur de row_layout était match_parent.

4
Liridon Sadiku

La hauteur de la vue de recyclage doit être "wrap_content" uniquement. La vue de recyclage gérera la hauteur si la taille de la cellule augmente.

buy_portfolio_fragment.xml

 <Android.support.v7.widget.RecyclerView
        Android:id="@+id/recycler_view"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="?attr/buyPortfolioListViewBackground"
        Android:requiresFadingEdge="none"
        Android:scrollbars="vertical"
        Android:paddingTop="@dimen/default_tab_layout_height"
        Android:clipToPadding="false" />
3

Je crois que c'est la ligne problématique:

<View   Android:layout_width="1px"
            Android:layout_height="match_parent"    <!--change this to wrap_content-->
            Android:background="?attr/buyPortfolioSeperatorBackground"
            Android:layout_marginRight="5dp"
            Android:layout_marginLeft="5dp" />

Il y a 2 endroits dans votre mise en page qui ont layout_height = "match_parent". Vous devriez les changer tous les deux en wrap_content.

2
Tiago

Juste faire row_layout hauteur à wrap_content donc il ne faudra que l'espace de la hauteur réelle de la ligne pour tous les éléments.

1
Abhishek Kumar