Android и горизонтальная скорость прокрутки в TextView - PullRequest
5 голосов
/ 16 февраля 2011

У меня есть текстовое представление со следующими атрибутами XML:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="14dip"
    android:maxLines="1"
    android:scrollHorizontally="true"
    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:marqueeRepeatLimit="1"
    android:textColor="@android:color/black"
    android:id="@+id/ticker"
    />

Я бы хотел установить горизонтальную скорость прокрутки, чтобы она была немного выше, чем по умолчанию. Как мне с этим (в XML)?

Заранее благодарю.

Ответы [ 4 ]

8 голосов
/ 16 февраля 2011

Я не думаю, что есть атрибут, который вы можете установить в XML для этой цели.

Это может быть немного излишним для вас, но посмотрите этот настроенный расширенное выделение для Android , все настройки можно настроить в части кодирования, вам нужно поиграть с setDuration анимации, чтобы добиться желаемой скорости.

5 голосов
/ 25 февраля 2011

Вот как я это сделал, он грязный, но он выполняет свою работу, пока они не проснутся и не сделают его настраиваемым!

Не могли бы вы поверить, что есть " // TODO Add опция для настройки этого " в приватном статическом внутреннем классе Marquee!

    protected void setMarqueeSpeed(TextView tv, float speed, boolean speedIsMultiplier) {

    try {
        Field f = tv.getClass().getDeclaredField("mMarquee");
        f.setAccessible(true);
        Object marquee = f.get(tv);
        if (marquee != null) {
            Field mf = marquee.getClass().getDeclaredField("mScrollUnit");
            mf.setAccessible(true);
            float newSpeed = speed;
            if (speedIsMultiplier) {
                newSpeed = mf.getFloat(marquee) * speed;
            }
            mf.setFloat(marquee, newSpeed);
            Log.i(this.getClass().getSimpleName(), String.format("%s marquee speed set to %f", tv, newSpeed));
        }
    } catch (Exception e) {
        // ignore, not implemented in current API level
    }
}
2 голосов
/ 13 ноября 2014

Это мой первый ответ на SO, поэтому у меня нет репутации, поэтому я не могу комментировать ответ Майка, но я немного изменил его, чтобы он работал с Android L.

Кроме того, если f.get (tv) возвращает null, попробуйте вызвать mTextView.setSelected (true) перед вызовом setMarqueeSpeed ​​(). Это сработало для меня.

protected void setMarqueeSpeed(TextView tv, float speed, boolean speedIsMultiplier) {

    try {
        Field f = tv.getClass().getDeclaredField("mMarquee");
        f.setAccessible(true);

        Object marquee = f.get(tv);
        if (marquee != null) {

            String scrollSpeedFieldName = "mScrollUnit";
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.L)
                scrollSpeedFieldName = "mPixelsPerSecond";

            Field mf = marquee.getClass().getDeclaredField(scrollSpeedFieldName);
            mf.setAccessible(true);

            float newSpeed = speed;
            if (speedIsMultiplier)
                newSpeed = mf.getFloat(marquee) * speed;

            mf.setFloat(marquee, newSpeed);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
0 голосов
/ 21 октября 2017

Просто дополнение к ответу Майка. Потому что он возвращает NoSuchFieldException при работе с AppCompatActivity:

Field f;     
if (tv instanceof AppCompatTextView) {
    f = tv.getClass().getSuperclass().getDeclaredField("mMarquee");
} else {
    f = tv.getClass().getDeclaredField("mMarquee");
}
...