Gibt es eine Möglichkeit ellipsize = „Marquee“ immer bewegen zu machen?
Frage
Ich mag den Marquee-Effekt auf einem Textview verwenden, aber der Text nur gescrollt wird, wenn die Textview des Fokus erhält. Das ist ein Problem, weil in meinem Fall, kann es nicht.
Ich bin mit:
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
Gibt es eine Möglichkeit, die Textview zu haben, immer bewegt den Text? Ich habe dies im Android Market App getan gesehen zu werden, in dem der App-Name in der Titelleiste bewegen, auch wenn es den Fokus nicht erhalten, aber ich konnte nicht, dass dies in der API-Dokumentation erwähnt werden.
Lösung
Ich habe das Problem wurde gegenüber und die kürzeste Lösung, die ich gekommen bin mit ist eine neue Klasse von Textview abgeleitet zu erstellen. Die Klasse soll Vorrang vor drei Methoden onFocusChanged , onWindowFocusChanged und IsFocused , um die Textview alle konzentriert zu machen.
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(focused)
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
public void onWindowFocusChanged(boolean focused) {
if(focused)
super.onWindowFocusChanged(focused);
}
@Override
public boolean isFocused() {
return true;
}
Andere Tipps
Ich kam schließlich gegen dieses Problem heute und so Feuer und Flamme hierarchyviewer
im Android Market-Anwendung.
auf den Titel auf einer App Detail-Bildschirm, verwenden sie eine einfache alte TextView
. Untersuchen seiner Eigenschaften wird gezeigt, dass es nicht konzentriert war, konnte nicht fokussiert werden und war im Allgemeinen sehr gewöhnliche -. Mit Ausnahme der Tatsache, dass es als markiert wurde ausgewählt
Eine Zeile Code später und ich hatte es funktioniert:)
textView.setSelected(true);
Dies macht Sinn, da was die Javadoc sagt
Eine Ansicht kann ausgewählt werden oder nicht. Beachten Sie, dass die Auswahl nicht die gleichen wie scharf ist. Ansichten werden in der Regel im Rahmen eines AdapterView wie Listview oder Gridview ausgewählt.
d. Wenn Sie über einen Eintrag blättern in einer Listenansicht (wie in dem Market-App), hat nur dann den jetzt ausgewählte Text Scrollen starten. Und da dieser besondere TextView
nicht fokussierbar oder anklickbare ist, wird es nie seinen Auswahlstatus verlieren.
Leider soweit ich weiß, gibt es keine Möglichkeit, den ausgewählten Zustand aus dem Layout XML voreingestellt.
Doch die Einzeiler oben funktioniert gut für mich.
Gerade diese Parameter in Ihrem Textview setzen. Es funktioniert:)
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
TranslateAnimation
funktioniert durch die Ansicht in eine Richtung um einen bestimmten Betrag „Ziehen“. Sie können festlegen, wo dieses „Ziehen“ beginnen und wo enden.
TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);
fromXDelta eingestellt dem Offset der Ausgangsposition der Bewegung in der X-Achse.
fromXDelta = 0 //no offset.
fromXDelta = 300 //the movement starts at 300px to the right.
fromXDelta = -300 //the movement starts at 300px to the left
toXDelta definiert die Offset-Endposition der Bewegung in der X-Achse.
toXDelta = 0 //no offset.
toXDelta = 300 //the movement ends at 300px to the right.
toXDelta = -300 //the movement ends at 300px to the left.
Wenn die Breite des Textes größer ist, dass das Modul der Differenz zwischen fromXDelta und toXDelta, wird der Text nicht in der Lage sein Totaly und compeltely Bewegung innerhalb des Bildschirms.
Beispiel
Nehmen wir an, unsere Bildschirmgröße 320x240 pxs ist. Wir haben eine Textview mit einem Text, 700px Breite hat, und wir wollen eine Animation erstellen, die „zieht“ den Text so, dass wir das Ende der Phrase sehen.
(screen)
+---------------------------+
|<----------320px---------->|
| |
|+---------------------------<<<< X px >>>>
movement<-----|| some TextView with text that goes out...
|+---------------------------
| unconstrained size 700px |
| |
| |
+---------------------------+
+---------------------------+
| |
| |
<<<< X px >>>>---------------------------+|
movement<----- some TextView with text that goes out... ||
---------------------------+|
| |
| |
| |
+---------------------------+
Zuerst setzen wir fromXDelta = 0
so dass die Bewegung nicht über ein Start-Offset. Jetzt müssen wir den Wert toXDelta Figur. Zur Erzielung der gewünschten Wirkung, die wir brauchen, um „ziehen“ den Text genau das gleiche Pixel, die sie aus dem Bildschirm erstreckt. (In der Regelung wird durch <<<< X Pixel dargestellt >>>>) Da unser Text 700 Breite hat, und der sichtbare Bereich ist 320px (Bildschirmbreite) wird gesetzt:
tXDelta = 700 - 320 = 380
Und wie tun wir herauszufinden, die Bildschirmbreite und der Text Breite?
Code
Unter dem Zarah Snippet als Ausgangspunkt:
/**
* @param view The Textview or any other view we wish to apply the movement
* @param margin A margin to take into the calculation (since the view
* might have any siblings in the same "row")
*
**/
public static Animation scrollingText(View view, float margin){
Context context = view.getContext(); //gets the context of the view
// measures the unconstrained size of the view
// before it is drawn in the layout
view.measure(View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED);
// takes the unconstrained wisth of the view
float width = view.getMeasuredWidth();
// gets the screen width
float screenWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
// perfrms the calculation
float toXDelta = width - (screenWidth - margin);
// sets toXDelta to 0 if the text width is smaller that the screen size
if (toXDelta < 0) {toXDelta = 0; } else { toXDelta = 0 - toXDelta;}
// Animation parameters
Animation mAnimation = new TranslateAnimation(0, toXDelta, 0, 0);
mAnimation.setDuration(15000);
mAnimation.setRepeatMode(Animation.RESTART);
mAnimation.setRepeatCount(Animation.INFINITE);
return mAnimation;
}
Es könnte einfache Möglichkeiten, dies durchzuführen, aber das funktioniert für jede Ansicht können Sie denken und sind wiederverwendbar. Es ist besonders nützlich, wenn Sie einen Textview in einem Listview animieren möchten, ohne die aktiviert / onFocus Fähigkeiten des Textview zu brechen. Es rollt auch kontinuierlich, auch wenn der Blick nicht fokussiert.
Ich weiß nicht, ob Sie noch die Antwort benötigen, aber ich fand eine einfache Möglichkeit, dies zu tun.
Richten Sie Ihre Animation in etwa so:
Animation mAnimation = new TranslateAnimation(START_POS_X, END_POS_X,
START_POS_Y, END_POS_Y);
mAnimation.setDuration(TICKER_DURATION);
mAnimation.setRepeatMode(Animation.RESTART);
mAnimation.setRepeatCount(Animation.INFINITE);
START_POS_X
, END_POS_X
, START_POS_Y
und END_POS_Y
sind float
Werte, während TICKER_DURATION
ist ein int
ich mit meinen anderen Konstanten erklärt.
Dann können Sie jetzt diese Animation auf Ihre Textview anwenden:
TextView tickerText = (TextView) findViewById(R.id.ticker);
tickerText.setAnimation(mAnimation);
Und das ist es. :)
Meine Animation beginnt auf der rechten Seite Off-Screen (300f) und endet auf der linken Seite Off-Screen (-300f), mit einer Dauer von 15 Sekunden (15000).
Ich schrieb den folgenden Code für eine Listview mit Marquee Textelementen. Es basiert auf der setSelected oben beschriebene Lösung. Grundsätzlich bin ich der ArrayAdapter-Klasse erweitern und die getView Methode überschreiben, das Textview zu wählen, bevor er zurückkehrt:
// Create an ArrayAdapter which selects its TextViews before returning
// them. This would enable marqueeing while still making the list item
// clickable.
class SelectingAdapter extends ArrayAdapter<LibraryItem>
{
public
SelectingAdapter(
Context context,
int resource,
int textViewResourceId,
LibraryItem[] objects
)
{
super(context, resource, textViewResourceId, objects);
}
@Override
public
View getView(int position, View convertView, ViewGroup parent)
{
View view = super.getView(position, convertView, parent);
TextView textview = (TextView) view.findViewById(
R.id.textview_playlist_item_title
);
textview.setSelected(true);
textview.setEnabled(true);
textview.setFocusable(false);
textview.setTextColor(0xffffffff);
return view;
}
}
Dies ist die Antwort, die an der Spitze meiner Google-Suche erscheint so dass ich dachte, dass ich hier eine nützliche Antwort schreiben könnte, da ich mit der Erinnerung dies ziemlich oft kämpfen. Wie dem auch sei, das funktioniert für mich und erfordert XML-Attribute und A ein onFocusChangeListener.
//XML
<TextView
android:id="@+id/blank_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#a4868585"
android:textColor="#fff"
android:textSize="15sp"
android:singleLine="true"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
tools:ignore="Deprecated" />
//JAVA
titleText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
titleText.setSelected(true);
}
}
});
// xml
<TextView
android:id="@+id/tvMarque"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:layout_gravity="center_horizontal"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:padding="5dp"
android:textSize="16sp"
android:text=""
android:textColor="@color/colorSyncText"
android:visibility="visible" />
// In Java
mtvMarque.setEllipsize(TextUtils.TruncateAt.MARQUEE);
mtvMarque.setSelected(true);
mtvMarque.setSingleLine(true);