Sélection TextView avec Spannable et LinkMovementMethod

Ce que j'ai fait jusqu'à présent est une vue en liste des pages de texte ayant le texte normal et les extensions cliquables: Article intact

En cliquant sur l'étendue, j'ouvre l'URL, en cliquant sur l'élément Afficher autour du texteView mène à la liste View OnItemClickListener naviguant aux détails de l'élément, c'est très bien: Objet touché en dehors du texteView

  • Exception inattendue de haut niveau dans android-support-v4.jar
  • Pourquoi INSERTs et UPDATES sont-ils plus lents sur Android 4.0?
  • Cacher l'indicateur "Loading ..." lors de la mise en œuvre d'un ListFragment
  • Erreur: "Impossible de faire une référence statique à la méthode non statique findViewById (int) du type Activité"
  • Galerie des images à l'aide de ViewPager + zoom dans ImageViews
  • Traitement de plus d'un bouton Cliquez sur Android Widget
  • Maintenant, le problème est:

    Article texteVoir le texte normal touchéÉlément textView span touché En touchant le textView rend le texte normal un peu en surbrillance (avec la même couleur qu'il a lorsque l'élément est complètement sélectionné), l' OnTouchListener tactile OnTouchListener de OnTouchListener déclenche, mais pas l'événement OnFocusChangeListener et la vue de l'élément n'obtient pas le style de sélection. Essayé toutes les variantes de FOCUS_BLOCK_DESCENDANTS pour listView, point d'affichage, la visualisation textView a été activée ou désactivée avec le même résultat.

    Heureusement, l'événement TextView OnClickListener déclenche de cette façon, mais c'est tellement laid: le texte est invisible alors que la touche n'est pas diffusée car la couleur de texte sélectionnée est identique à la couleur de l'élément, il n'y a pas d'autre indication que l'utilisateur accède aux détails de l'article Autrement que ce texte laid disparaît.

    Je soupçonne que cela se produit parce que le contenu du textView est Spannable , et les parties qui ne sont pas CliclableSpan-s se comportent de cette façon étrange.

    Quelque chance de pouvoir sélectionner l'élément une fois que le texte normal est touché?


    La disposition des articles listView:

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:descendantFocusability="blocksDescendants" android:orientation="horizontal" > <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginTop="5dp" android:focusable="false" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:focusable="false" android:text="" android:textAppearance="?android:attr/textAppearanceLarge" android:textStyle="bold" /> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:focusable="false" android:text="" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/details" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:focusable="false" android:gravity="fill_horizontal|right" android:text="" android:textAppearance="?android:attr/textAppearanceMedium"/> </LinearLayout> </LinearLayout> 

    Avec la vue de texte setClickable (false), je peux désactiver ce style de sélection étrange de la façon dont rien ne se produit en touchant la zone de visualisation du texte, pas bon mais peut être utile pour la solution.

    Également essayé d'ajouter un bouton non focalisable et non cliquable à chaque élément, lorsqu'il est touché, l'élément complet est sélectionné et lorsque Touch est relâché, l'événement de clic de l'élément est passé, c'est exactement ce que j'attendais du TextView avec le contenu Spannable.

  • Vérifiez la méthode onReceivedSslError () d'un WebViewClient si un certificat est signé à partir d'un CA auto-signé spécifique
  • Android switchpreference Comment puis-je définir la valeur par défaut de la préférence par défaut?
  • Obtenez la hauteur du clavier virtuel dans Android
  • Comment arrêter Handler Runnable?
  • Comment ouvrir les liens de TextView dans le Webview
  • Répertoires de buildscript Android: jcenter VS mavencentral
  • 4 Solutions collect form web for “Sélection TextView avec Spannable et LinkMovementMethod”

    Avez-vous essayé de définir l'arrière-plan de votre TextView sur le list_selector_background par défaut d' list_selector_background ?

      textView.setMovementMethod(LinkMovementMethod.getInstance()); textView.setBackgroundResource(android.R.drawable.list_selector_background); 

    Pour moi, cela semble donner le résultat que vous voulez.

    MISE À JOUR: Après avoir vu que l'élément n'est pas seulement un seul TextView

    Eh bien, ce n'est pas une solution parfaite (car il est préférable de réparer d'une manière ou d'une autre l'interaction de mise en évidence TextView – ListView), mais cela fonctionne bien.

    J'ai compris que, au lieu de définir la méthode de mouvement sur le TextView (qui déclenche le problème), il est plus simple de vérifier l' onItemClick() (après un clic est définitivement confirmé) pour voir si nous devrions lancer onClick() Sur nos systèmes ClickableSpans:

     public class MyActivity extends Activity { private final Rect mLastTouch = new Rect(); private boolean spanClicked(ListView list, View view, int textViewId) { final TextView widget = (TextView) view.findViewById(textViewId); list.offsetRectIntoDescendantCoords(widget, mLastTouch); int x = mLastTouch.right; int y = mLastTouch.bottom; x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); final Layout layout = widget.getLayout(); final int line = layout.getLineForVertical(y); final int off = layout.getOffsetForHorizontal(line, x); final Editable buffer = widget.getEditableText(); final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length == 0) return false; link[0].onClick(widget); return true; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (spanClicked(listView, view, R.id.details)) return; // no span is clicked, normal onItemClick handling code here .. } }); listView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { mLastTouch.right = (int) event.getX(); mLastTouch.bottom = (int) event.getY(); } return false; } }); // ... } } 

    La méthode spanClicked() est essentiellement une version abrégée de la méthode onTouchEvent() de onTouchEvent() dans le cadre. Pour capturer les dernières coordonnées de MotionEvent (pour vérifier l'événement de clic), nous ajoutons simplement un OnTouchListener sur notre ListView.

    Je pense que la meilleure façon de résoudre ce problème est d'utiliser un sélecteur. Vous pouvez choisir la couleur du backgroun de sélection afin qu'ils soient identiques

    Exemple de code de sélection:

     <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="#000000" /> <!-- pressed --> <item android:state_focused="true" android:color="#000000" /> <!-- focused --> <item android:color="#FFFFFF" /> <!-- default --> </selector> 

    Mettez en œuvre cette méthode dans votre lien.

    Faites-moi connaissance du résultat

    Quote from documentation de setMovementMethod() de TextView

    Définit la méthode de déplacement (gestionnaire de touches fléchées) à utiliser pour cette TextView. Cela peut être nul pour interdire l'utilisation des touches fléchées pour déplacer le curseur ou faire défiler la vue.

    Soyez averti que si vous souhaitez que le TextView avec un auditeur de touches ou une méthode de mouvement ne soit pas focalisable, ou si vous souhaitez effectuer une recherche de texte sans écoute de touches ou méthode de mouvement, vous devez appeler android.view.View.setFocusable (boolean) À nouveau après avoir appelé cela pour que la focalisation soit réactive comme vous le souhaitez.

    Le deuxième paragraphe explique que nous devrions appeler explicitement la méthode setFocusable après avoir défini le LinkMovementMethod pour que la mise au point fonctionne comme nous le voulons.

    Vous devez le faire dans le code après avoir gonflé l'élément de la liste. Une fois que vous êtes en mesure d'obtenir l'accent, vous pouvez définir le sélecteur pour avoir un texte couleur différent.

    Voici le code source de setMovementMethod .

    Utilisez le TextView de setHighlightColor(Color.TRANSPARENT);

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.