Android和TextView的水平选框滚动率

时间:2011-02-16 09:18:19

标签: android animation scroll textview

我有一个包含以下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 个答案:

答案 0 :(得分:8)

我认为您不能为此目的在XML中设置属性。

对你来说可能有点矫枉过正,但看看这个自定义extended marquee for Android,所有设置都可以在编码部分自定义,你需要使用动画的setDuration来达到你想要的速度。 / p>

答案 1 :(得分:5)

这就是我做的方式,它很脏,但它完成了工作,直到它们唤醒并使其可配置!

你能相信在Marquee私有静态内部类中有一个“ // TODO添加一个选项来配置这个”!

    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 :(得分:2)

这是我在SO上的第一个答案,所以我没有声誉,所以我不能评论迈克的答案,但我稍微修改了它以使其与Android L一起使用。

除此之外,如果f.get(tv)返回null,请在调用setMarqueeSpeed()之前尝试调用mTextView.setSelected(true)。这对我有用。

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();
    }
}

答案 3 :(得分:0)

只是迈克回答的补充。因为在使用NoSuchFieldException时会返回AppCompatActivity

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