webentwicklung-frage-antwort-db.com.de

Gibt es eine Möglichkeit, Ellipsize = "Marquee" immer scrollen zu lassen?

Ich möchte den Marquee-Effekt für eine TextView verwenden, der Text wird jedoch nur gescrollt, wenn die TextView den Fokus erhält. Das ist ein Problem, weil es in meinem Fall nicht geht.

Ich benutze:

  Android:ellipsize="Marquee"
  Android:marqueeRepeatLimit="Marquee_forever"

Gibt es eine Möglichkeit, die Textansicht immer durchlaufen zu lassen? Ich habe gesehen, wie dies in der Android Market-App durchgeführt wurde, wo der App-Name in der Titelleiste angezeigt wird, auch wenn er keinen Fokus erhält. In den API-Dokumenten wurde dies nicht erwähnt.

88
Matthias

Ich bin mit dem Problem konfrontiert und die kürzeste Lösung, die ich gefunden habe, ist das Erstellen einer neuen, von TextView abgeleiteten Klasse .. Die Klasse sollte die drei Methoden onFocusChanged, onWindowFocusChanged und isFocused überschreiben. ], um das TextView zu fokussieren.

@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;
}
61
hnviet

Ich bin heute endlich auf dieses Problem gestoßen und habe hierarchyviewer in der Android Market-Anwendung angeheizt.

Wenn Sie den Titel auf dem Detailbildschirm einer App betrachten, verwenden Sie ein einfaches altes TextView. Die Untersuchung seiner Eigenschaften zeigte, dass es nicht fokussiert war, konnte nicht fokussiert werden und war im Allgemeinen sehr gewöhnlich - mit Ausnahme der Tatsache, dass es als selected markiert war.

Eine Zeile Code später und ich hatte es funktioniert :)

textView.setSelected(true);

Dies ist sinnvoll, wenn man bedenkt, was der Javadoc sagt :

Eine Ansicht kann ausgewählt werden oder nicht. Beachten Sie, dass die Auswahl nicht mit dem Fokus identisch ist. Ansichten werden normalerweise im Kontext einer AdapterView wie ListView oder GridView ausgewählt.

wenn Sie in einer Listenansicht über ein Element blättern (wie in der Market-App), beginnt der Text jetzt ausgewählt zu blättern. Und da dieses bestimmte TextView nicht fokussierbar oder anklickbar ist, verliert es niemals seinen Auswahlstatus.

Meines Wissens gibt es leider keine Möglichkeit, den ausgewählten Status aus dem Layout-XML vorzugeben.
Aber der Ein-Liner oben funktioniert gut für mich.

115
Christopher Orr

Geben Sie diese Parameter einfach in Ihre TextView ein. Es klappt :)

    Android:singleLine="true" 
    Android:ellipsize="Marquee"
    Android:marqueeRepeatLimit ="Marquee_forever"
    Android:scrollHorizontally="true"
    Android:focusable="true"
    Android:focusableInTouchMode="true" 
72
Vinayak

TranslateAnimation arbeitet, indem Sie die Ansicht um einen bestimmten Betrag in eine Richtung "ziehen". Sie können festlegen, wo dieses "Ziehen" beginnen soll und wo Sie enden sollen.

TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);

fromXDelta legt den Versatz der Startposition der Bewegung in der X-Achse fest. 

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 Endposition der Verschiebung 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 Ihres Texts größer ist als das Modul der Differenz zwischen XDelta und XDelta, kann der Text nicht vollständig innerhalb des Bildschirms verschoben werden.


Beispiel

Nehmen wir an, unsere Bildschirmgröße beträgt 320x240 px. Wir haben eine Textansicht mit einem Text, der 700px breit ist, und wir möchten eine Animation erstellen, die den Text "zieht", damit wir das Ende der Phrase sehen können.

                                       (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 keinen Startversatz hat. Nun müssen wir den toXDelta-Wert berechnen. Um den gewünschten Effekt zu erzielen, müssen wir den Text genau so weit "ziehen", wie er aus dem Bildschirm herausragt. (In dem Schema wird dargestellt durch <<<< X px >>>>) Da unser Text eine Breite von 700 hat und der sichtbare Bereich 320px (Bildschirmbreite) ist, setzen wir:

tXDelta = 700 - 320 = 380

Und wie bestimmen wir die Bildschirmbreite und die Textbreite?


Code

Ausgehend vom Zarah-Snippet:

    /**
     * @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 gibt möglicherweise einfachere Möglichkeiten, dies auszuführen, aber dies funktioniert für jede Ansicht, die Sie sich vorstellen können, und ist wiederverwendbar. Dies ist besonders nützlich, wenn Sie eine TextView in einer ListView animieren möchten, ohne die aktivierten/onFocus-Fähigkeiten der TextView zu beschädigen. Es scrollt auch dann kontinuierlich, wenn die Ansicht nicht scharfgestellt ist. 

13
Tivie

Ich weiß nicht, ob Sie die Antwort noch brauchen, aber ich habe einen einfachen Weg gefunden, dies zu tun.

Richten Sie Ihre Animation so ein:

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 eine int ist, die ich mit meinen anderen Konstanten deklariert habe.

Dann können Sie diese Animation nun 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 außerhalb des Bildschirms (300f) und endet auf der linken Seite außerhalb des Bildschirms (-300f) mit einer Dauer von 15 Sekunden (15000).

12
Zarah

Ich habe den folgenden Code für eine ListView mit Marquee-Textelementen geschrieben. Sie basiert auf der oben beschriebenen setSelected-Lösung. Grundsätzlich erweitere ich die ArrayAdapter-Klasse und überschreibe die getView-Methode, um die TextView auszuwählen, bevor sie zurückgegeben wird: 

    // 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;

        }
    }
5
smichak

Dies ist die Antwort, die ganz oben in meiner Google-Suche angezeigt wird. Ich dachte, ich könnte hier eine nützliche Antwort posten, da ich mich ziemlich oft damit beschäftige, daran zu denken ..

//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);
            }
        }
    });
2
Thunderstick

// 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);
0
Soni Kumar