Czy istnieje sposób, aby ellipsize = "marquee" zawsze przewijał?

Chcę użyć efektu marquee w widoku tekstowym, ale tekst jest przewijany tylko wtedy, gdy Widok tekstowy zostanie ustawiony na ostrość. To jest problem, ponieważ w moim przypadku nie może.

Używam:

  android:ellipsize="marquee"
  android:marqueeRepeatLimit="marquee_forever"

Czy istnieje sposób, aby TextView zawsze przewijał swój tekst? Widziałem to robione w aplikacji Android Market, gdzie nazwa aplikacji będzie przewijać w pasku tytułu, nawet jeśli nie otrzyma fokus, ale nie mogłem znaleźć to jest wymienione w dokumentach API.

Author: Cristian, 2009-12-01

7 answers

Miałem do czynienia z problemem i najkrótszym rozwiązaniem, jakie wymyśliłem, jest stworzenie nowej klasy pochodzącej z TextView. Klasa powinna nadpisywać trzy metody onFocusChanged, onWindowFocusChanged and isFocused aby TextView był skupiony.

@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
Author: hnviet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-25 14:09:37

W końcu wpadłem dziś na ten problem i tak się hierarchyviewer w aplikacji Android Market.

[[4]}patrząc na tytuł na ekranie szczegółów aplikacji, używają zwykłego starego TextView. Badanie jego właściwości wykazało, że nie był skupiony, nie mógł być skupiony i był ogólnie bardzo zwyczajny-z wyjątkiem faktu, że został oznaczony jako wybrany.

Jedna linijka kodu później i miałem go działającego:)

textView.setSelected(true);

To ma sens, biorąc pod uwagę, co Javadoc mówi :

Widok może być wybrany lub nie. Zauważ, że wybór nie jest tym samym, co fokus. Widoki są zazwyczaj wybierane w kontekście widoku Adapter, takiego jak ListView lub GridView.

Tj. po przewinięciu elementu w widoku listy (jak w aplikacji rynek), dopiero wtedy rozpoczyna się przewijanie tekstu Teraz wybranego. A ponieważ ten konkretny TextView nie jest ustawialny ani klikalny, nigdy nie utraci swojego wyboru stan.

Niestety, z tego co wiem, nie ma możliwości wstępnego ustawienia wybranego stanu z layout XML.
Ale jednolinijkowy powyżej działa dobrze dla mnie.

 114
Author: Christopher Orr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-13 13:06:04

Po prostu umieść te parametry w widoku tekstowym. Działa :)

    android:singleLine="true" 
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:scrollHorizontally="true"
    android:focusable="true"
    android:focusableInTouchMode="true" 
 71
Author: Vinayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-29 07:11:03

Nie wiem, czy nadal potrzebujesz odpowiedzi, ale znalazłem na to łatwy sposób.

Ustaw swoją animację tak:

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 i END_POS_Y są wartościami float, podczas gdy TICKER_DURATION jest int zadeklarowałem z innymi stałymi.

Następnie możesz zastosować tę animację do widoku tekstu:

TextView tickerText = (TextView) findViewById(R.id.ticker);
tickerText.setAnimation(mAnimation);

I to wszystko. :)

Moja animacja zaczyna się po prawej stronie poza ekranem (300F), a kończy po lewej stronie poza ekranem (- 300F), z czasem 15s (15000).

 12
Author: Zarah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-12 07:13:18

TranslateAnimation działa poprzez "ciągnięcie" widoku w jednym kierunku o określoną kwotę. Możesz ustawić, gdzie zacząć to "ciągnięcie" i gdzie zakończyć.

TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);

Fromxdelta ustawia przesunięcie położenia początkowego ruchu w osi X.

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 określa przesunięcie położenia końcowego ruchu w osi X.

toXDelta = 0 //no offset. 
toXDelta = 300 //the movement ends at 300px to the right.
toXDelta = -300 //the movement ends at 300px to the left.

Jeśli szerokość Twojego tekstu jest większa niż Moduł różnicy między fromXDelta i toXDelta, tekst nie będzie w stanie całkowicie i przymusowo poruszać się po ekranie.


Przykład

Załóżmy, że nasz rozmiar ekranu to 320x240 pxs. Mamy TextView z tekstem o szerokości 700px i chcemy stworzyć animację, która "ciągnie" tekst, abyśmy mogli zobaczyć koniec frazy.

                                       (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... ||
                             ---------------------------+|
                             |                           |
                             |                           |
                             |                           |
                             +---------------------------+

Najpierw ustawiamy fromXDelta = 0 tak, aby ruch nie miał przesunięcia początkowego. Teraz musimy obliczyć wartość toXDelta. Aby uzyskać pożądany efekt, musimy" wyciągnąć " tekst dokładnie taki sam px, z którego rozciąga się ekran. (w schemacie jest reprezentowany przez >>>) ponieważ nasz tekst ma szerokość 700, a widoczny obszar to 320px (szerokość ekranu) ustawiamy:

tXDelta = 700 - 320 = 380

A jak obliczyć szerokość ekranu i szerokość tekstu?


Kod

Biorąc za punkt wyjścia fragment Zarah:

    /**
     * @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;
}

Mogą być łatwiejsze sposoby, aby to wykonać, ale działa to dla każdego widoku, który możesz wymyślić i jest wielokrotnego użytku. Jest to szczególnie przydatne, jeśli chcesz animować Widok tekstowy w ListView bez przerywania możliwości włączonego / włączonego ustawienia ostrości w widoku tekstowym. Przewija się również w sposób ciągły, nawet jeśli Widok nie jest skupiony.

 12
Author: Tivie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-16 14:07:52

Napisałem następujący kod dla ListView z elementami tekstowymi marquee. Opiera się na zestawie wybranych rozwiązań opisanych powyżej. Zasadniczo rozszerzam klasę ArrayAdapter i nadpisuję metodę getView, aby wybrać TextView przed zwróceniem:

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

        }
    }
 4
Author: smichak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-19 10:09:21

Jest to odpowiedź, która pojawia się na górze mojej wyszukiwarki google, więc pomyślałem, że mogę opublikować przydatną odpowiedź tutaj, ponieważ zmagam się z zapamiętywaniem tego dość często. W każdym razie, to działa dla mnie i wymaga atrybutów XML i an 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);
            }
        }
    });
 2
Author: Thunderstick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-29 19:16:38