Question

J'ai la structure suivante dans mon application:

FragmentActivity avec ViewPager tenant plusieurs fragments gérés par FragmentStatePagerAdapter utilisant pack compativility avec les applications 2.1

Chaque fragment contient ListView. Chaque élément du ListView a un LinearLayout avec deux TextViews et un Button. Le LinearLayout et le bouton ont onClickListeners (séparés). En cliquant sur le LinearLayout démarre un autre Activity. J'ai remarqué que le comportement des clics est très inégale: parfois l'action est exécutée immédiatement, mais très souvent, il est retardé et il est parfois tout simplement ignorés, peu importe combien de fois je tape. Il est encore plus étrange parce que je peux taper et l'action ne sera exécuté que quand je commence à défiler la liste. J'ai essayé différentes combinaisons de setFocusable(false) et setSelectable(true), mais il semble ne faire aucune différence. Des idées? Je serai heureux de vous fournir plus de détails.

Était-ce utile?

La solution 3

Au cas où quelqu'un se demandait comment je résolu ce problème. Fondamentalement, je devais simplifier mes mises en page. Il semble que lorsque vous avez des événements complexes structures imbriquées peuvent prendre trop de temps à bulle et si vous commencez à faire défiler la liste en même temps événement peut déclencher mauvaise action. Je parés les mises en page en passant à RelativeLayout autant que possible et qui semblait aider beaucoup

Autres conseils

J'ai eu un problème similaire et il m'a fallu 2 jours pour le débogage et le résoudre. J'ai un ListAdapter qui crée plusieurs TextViews dans un LinearLayout pour chaque élément de la liste. Chaque TextView a son propre OnClickListener, parce que je dois gérer les clics sur chaque élément.

Quand j'ai changé la mise en œuvre afin que je réutilise les vues du OnClickListener a cessé de fonctionner correctement. Sur la plupart des clics 4.4.2 travaillé, mais parfois il n'y avait pas de réaction jusqu'à ce que je dans la liste défile. Sur les 2,3 premiers clics ne fonctionneront pas et puis tous les clics où manipulables en rafale.

Dans mon cas particulier, j'ai créé toute la vue dans le code Java et non en gonflant les ressources. Et le point critique était, que je ne mets les LayoutParams du LinearLayout même si la vue a été réutilisé (cela semble être plus en sécurité, puis en supposant que la vue réutilisée a les paramètres de mise en page correcte). Quand je ne mets pas les LayoutParams quand tout réutilisant fonctionne très bien! Voici le code critique:

public View getView(int position, View convertView, ViewGroup parent) {
    LinearLayout tapeLine = null;
    if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view
    else tapeLine = new LinearLayout(activity);
    if (convertView == null) { // Don't set LayoutParams when reusing view
        ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        tapeLine.setLayoutParams(tapeLineLayoutParams);
    }
    ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape();
    int tapeWidthPx = parent.getWidth();
    TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx);
    ScrollingTapeLine line = scrollingTape.getLine(position);
    tapeLine.setOrientation(LinearLayout.HORIZONTAL);
    int tapeBackgroundColor = getBackgroundColor(line);
    tapeLine.setBackgroundColor(tapeBackgroundColor);
    addColumnViews(tapeLine, line, tapeLineTextSizeInfo);
    tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position);
    tapeLine.setOnLongClickListener(longClickListener);
    tapeLine.setOnClickListener(remainClickListener);
    return tapeLine;
}

Quel est le contexte de ce comportement étrange de la vue de la liste? Je l'ai fait un peu de débogage et de recherche dans les sources Android. Lorsque les mises à jour Android une vue il y a deux étapes importantes onMeasure et OnLayout. La méthode getView du ListAdapter est non seulement appelé à tirer la vue mais aussi plus tôt au cours onMeasure. Dans ce dernier cas, la vue est créé, mais il n'a pas encore été enregistré dans la chaîne d'événements pour les événements de clic de la poignée.

Quand une vue qui a été créé pour onMeasure est réutilisé plus tard à acutally dessiné à l'écran, il doit être inscrit dans le système Android pour les événements de clic de la poignée. Pour ce cas particulier les develepers Android avaient fait quelque chose, ce qui pourrait être considéré comme un hack sale. Un drapeau spécial dans les LayoutParams est utilisé pour décider que la vue doit être enregistré dans le changement de l'événement.

Maintenant, mon problème: en remettant à zéro les LayoutParams également lorsqu'une vue est réutilisée, ce drapeau a toujours été remis à zéro. Par conséquent, le système Android n'enregistrerait pas la vue et les événements ne fonctionnent pas.

pour résumer:. Quand resusing une vue en getView d'un ListAdapter ne remplace pas les LayoutParams parce qu'ils gardent l'information interne du système Android

Je suis tombé sur même problème, mais dans mon cas, la solution est de ne pas garder les références à des vues, qui ont causé des problèmes avec la mise en cache de vue de ListView. Après la mise en œuvre correctement méthode getView() avec l'utilisation de converView, tout comportement étrange avec les appels perdus / clic inattendu a disparu.

Ce qui a fonctionné pour moi a été l'attribution d'un OnItemClickListener au ListView par setOnItemClickListener, plutôt que d'un OnClickListener aux éléments de liste. Il est évident que le bouton a encore besoin de son propre OnClickListener, mais je n'ai pas testé ce scénario.

Je ne sais pas si cela aide quelqu'un, mais j'ai eu un problème similaire à la place d'un TableLayout. Les solutions ci-dessus ne permettent pas de résoudre mon problème.

Pour moi, le problème était: android:animateLayoutChanges="true"

La suppression de ce permis à mes clics de bouton dans mes lignes TableLayout fonctionne correctement. Je devais animer alors mon point de vue manuellement au lieu de compter sur la propriété ci-dessus.

Il semble que vous exécutez un processus de blocage (comme l'invocation webservices ou fichiers d'ouverture) en fil d'événements, de sorte que votre fil de l'événement est bloqué. Si tel est le cas, S'il vous plaît traiter votre blocage de code dans un autre thread que Enfilez événement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top