webentwicklung-frage-antwort-db.com.de

Scrollable TextView erlaubt es nicht, Text auszuwählen, nachdem die Anwendung angehalten wurde

Ich habe eine scrollbare TextViewname__, in der ein Benutzer Text auswählen kann. Ich füge eine Bildlaufleiste hinzu, indem ich die Bewegungsmethode auf ScrollingMovementMethodsetze.

Problem: Die Auswahl funktioniert gut, es sei denn, die Anwendung wurde angehalten (z. B. nach dem Wechsel der Apps). Sobald die App wieder aktiv ist, funktioniert die Auswahl nicht mehr und ich erhalte die folgende Meldung im Protokoll:

W/TextView: TextView unterstützt keine Textauswahl. Auswahl aufgehoben.

Mein Setup:

Ich habe eine Aktivität mit CoordinatorLayoutund ein Fragment mit einem TextViewin RelativeLayoutgewickelt, die wie folgt aussieht:

<TextView
    Android:id="@+id/text_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignParentStart="true"
    Android:scrollbars="vertical" />

Und in Java-Code muss ich tun:

textView.setMovementMethod(new ScrollingMovementMethod());
textView.setTextIsSelectable(true);
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

denn dies war der einzige arbeitsweg nach diesem , diesem und diesem ausgaben.

BEARBEITEN:

Das Problem ist im folgenden Aufruf

textView.setMovementMethod(new ScrollingMovementMethod());

Wenn ich es entferne, funktioniert es, aber ich kann nicht verstehen, warum.

Minimale Schritte zum Reproduzieren des Problems:

1) Erstellen Sie eine leere Aktivität mit einem TextViewunter Verwendung des folgenden Layouts.

<Android.support.design.widget.CoordinatorLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <TextView
        Android:id="@+id/text_view"
        Android:text="Some very very very long text..."
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_alignParentStart="true"
        Android:scrollbars="vertical" />

</Android.support.design.widget.CoordinatorLayout>

2) Richten Sie die Sichtbarkeitsparameter der Methode TextViewin onStart() ein.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        TextView textView = findViewById(R.id.text_view);
        textView.setMovementMethod(new ScrollingMovementMethod());
        textView.setTextIsSelectable(true);
        textView.setFocusable(true);
        textView.setFocusableInTouchMode(true);
    }
}

3) Versuchen Sie, das Kontextmenü für TextViewvor und nach dem Anhalten der Anwendung zu verwenden.

EDIT 2:

Das Entfernen von setMovementMethod(new ScrollingMovementMethod()) löst mein Problem und die Funktionalität funktioniert danach gut. Aber ich bin nicht ganz sicher, warum es hinzugefügt wurde und ich fürchte, es wird etwas bremsen, wenn ich es entferne. Jede Idee, warum man ScrollingMovementMethodin Kombination mit Android:scrollbars="vertical" verwenden könnte. Möglicherweise funktioniert XML in einigen Fällen nicht? Ideen? Und ich bin immer noch daran interessiert, warum ScrollingMovementMethoddie Funktion zur Auswahl von Bremsen verwendet?

8

die Einstellung ScrollingMovementMethod gibt TextView die Möglichkeit, "von selbst" zu scrollen, z. wenn Sie sehr langen Text setzen und dieser unten oder am Rand abgeschnitten ist. mit ScrollingMovementMethod können Sie durch TextView scrollen, es ist nicht erforderlich, sie in einen scrollbaren Container zu legen, z. in ScrollView oder HorizontalScrollView

In der Zeile Android:scrollbars="vertical" heißt es, dass die Benutzeroberfläche nur die Bildlaufleiste View anzeigen sollte, wenn diese vertical "scrollbar" ist (z. B. durch die oben beschriebene Bewegungsmethode). von docs:

Legt fest, welche Bildlaufleisten beim Scrollen angezeigt werden sollen oder nicht.

und es ist View docs, nicht TextView, insbesondere, weil nur wenige erweiterte "Arten" von Views "scolllability" erlangen können, einschließlich aller ViewGroups wie ScrollView, ListView, RecyclerView usw.

und schließlich, was diese Zeile in Ihrem Code tut? innerhalb von setTextIsSelectable haben Sie diese Zeile:

setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);

tatsächlich setzen Sie bei der Methode zum Überschreiben von Bewegungen einige Zeilen oben in Ihren eigenen Code. Ich wette, dass Ihre TextView vor einiger Zeit "von selbst" scollable war und eines Tages ein kluger Kerl dies umschrieb und TextView in z. ScrollView in XML und die Verschiebungsmethode blieben im Code.

textIsSelectable funktioniert bis zum Anhalten von Activity, da Sie nach dem Fortsetzen (wieder) ScrollableMovementMethod einstellen, aber innerhalb von setTextIsSelectable haben

 if (mEditor.mTextIsSelectable == selectable) return;

sie setzen dieses mTextIsSelectable-Flag beim ersten Start vor der Pause von Activity, und dieses Flag wird wiederhergestellt, damit der folgende Code nicht ausgelöst wird (sodass die Bewegungsmethode bei ArrowKeyMovementMethod nicht zurückgesetzt wird und Ihre ScrollableMovementMethod erhalten bleibt). Beantworten Sie also die Frage, was diese Zeile in Ihrem Code tut: Sie unterbricht die "Selektionsfähigkeit", nachdem Sie Activity angehalten und fortgesetzt haben, sonst nichts

anmerkung aus Quellen von ScrollingMovementMethod und ArrowKeyMovementMethod : Nur in ArrowKeyMovementMethod (als Bewegungsmethode in setTextIsSelectable wie oben eingestellt) haben Sie onTouchEvent Methode überschrieben und darin einige Zeilen, die Auswahl behandeln

edit: beachte auch, dass du in setTextIsSelectable "focusability" eingestellt hast, so dass diese Zeilen unnötig sind:

textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

so können Sie Ihren Code auf nur eine Zeile verkürzen:

textView.setTextIsSelectable(true);

oder entfernen Sie den gesamten Java-Code in Anführungszeichen und fügen Sie eine XML-Zeile hinzu:

Android:textIsSelectable="true"
1
snachmsm

Bitte ersetzen Sie den folgenden Code aus Ihrem XML.

<TextView
    Android:id="@+id/text_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignParentStart="true"
    Android:enabled="true"
    Android:textIsSelectable="true"
    Android:focusable="true"
    Android:longClickable="true" 
    Android:scrollbars="vertical" />

Entfernen Sie den folgenden Code aus dem Programm:

textView.setTextIsSelectable(true);
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

Der interne Code von setTextIsSelectable () method:

public void setTextIsSelectable(boolean selectable) {
        if (!selectable && mEditor == null) return; // false is default value with no edit data

        createEditorIfNeeded();
        if (mEditor.mTextIsSelectable == selectable) return;

        mEditor.mTextIsSelectable = selectable;
        setFocusableInTouchMode(selectable);
        setFocusable(FOCUSABLE_AUTO);
        setClickable(selectable);
        setLongClickable(selectable);

        // mInputType should already be EditorInfo.TYPE_NULL and mInput should be null

        setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
        setText(mText, selectable ? BufferType.SPANNABLE : BufferType.NORMAL);

        // Called by setText above, but safer in case of future code changes
        mEditor.prepareCursorControllers();
    }

Programmatisch machen sie auch dasselbe, was ich in XML erwähnt habe. Je nach Ihren Anforderungen können wir es also verwenden.

3
jitesh mohite

Sie können TextView auf zwei Arten auswählbar machen

durch XML:

 Android:textIsSelectable="true"

durch Java-Code:

 textView.setTextIsSelectable(true);
0
Uma Achanta