Ich habe eine scrollbare TextView
name__, in der ein Benutzer Text auswählen kann. Ich füge eine Bildlaufleiste hinzu, indem ich die Bewegungsmethode auf ScrollingMovementMethod
setze.
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 CoordinatorLayout
und ein Fragment mit einem TextView
in RelativeLayout
gewickelt, 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 TextView
unter 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 TextView
in 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 TextView
vor 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 ScrollingMovementMethod
in 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 ScrollingMovementMethod
die Funktion zur Auswahl von Bremsen verwendet?
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 View
s "scolllability" erlangen können, einschließlich aller ViewGroup
s 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"
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.
Sie können TextView auf zwei Arten auswählbar machen
durch XML:
Android:textIsSelectable="true"
durch Java-Code:
textView.setTextIsSelectable(true);