【问题标题】:Android and a TextView's horizontal marquee scroll rateAndroid 和 TextView 的水平选取框滚动率
【发布时间】:2011-06-28 05:25:56
【问题描述】:

我有一个带有以下 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 中)?

提前谢谢你。

【问题讨论】:

    标签: android animation scroll textview


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      这就是我的做法,它很脏,但它可以完成工作,直到他们醒来并使其可配置!

      你能相信在 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
          }
      }
      

      【讨论】:

      • 我不相信——太搞笑了!也感谢您的帖子。
      • 奇怪... f.get(tv) 为我返回 null。我在 xml 中将 ellipsize 设置为“marquee”,所以我认为会设置“mMarquee”变量。 textview 仍然滚动,只是没有达到我试图用上面的漂亮代码设置的速度。有什么想法吗?
      • f.get(tv) 也为我返回 null 。 java.lang.reflect.field.get() 似乎说它不应该为空; mMarquee 是私有的而不是静态的。嗯.. 这在 Android 2.2.2 上
      • 在 HTC Hero (2.1-update1) 和 LG Optimus 2X Speed (a.k.a. LG-P990 with 2.2.2) 上也返回 null
      • 为什么对我一点效果都没有?
      【解决方案3】:

      这是我关于 SO 的第一个答案,所以我没有声誉,所以我无法评论 Mike 的答案,但我对其进行了一些修改以使其适用于 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();
          }
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2011-07-25
          • 1970-01-01
          • 2020-08-17
          • 1970-01-01
          • 2013-11-11
          • 2011-03-20
          • 1970-01-01
          • 1970-01-01
          • 2013-06-19
          相关资源
          最近更新 更多