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
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
.
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.
RecyclerView
n'autorise pas les modifications de l'adaptateur lors du calcul d'une présentation ou d'un défilement. (Numéro 202046)notifyItemChanged()
sur un élément non visible. (Numéro 202136)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.
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
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.
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.
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!
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.
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.
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.
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" />
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.
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.