TextView的设置阻止其他TextView的跑马灯滚动
这是在其他地方问过的,但该解决方案对我不起作用。因此,在更多背景下再次提出它。问题是活动包含滚动音乐标题文本视图,该视图被更新的经过时间计数器文本视图中断。
我的活动布局中有这两个 TextView 小部件(尽管它们被其他布局容器包含)。
<TextView android:id="@+id/v_current_time"
android:minWidth="26dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="right|center_vertical"
android:singleLine="true"
android:textSize="12sp"
android:enabled="false"
/>
<TextView android:id="@+id/v_track_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="normal"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:enabled="true"
/>
音乐标题动态设置为(在测试用例中)一长行文本。如果我从未使用以下行更新当前时间的文本,则无论我如何与暂停和播放按钮交互,音乐标题都会愉快地永远滚动。
tvCurrentTime.setText(DataFormat.formatTime(progress));
但如果我确实将文本设置为当前时间,音乐标题就会停止。按我的暂停按钮会以某种方式将滚动重新启动,但按播放会导致当前时间更新并再次停止。
根据此线程中的建议,我尝试将时间文本的设置与重新启用滚动标题结合起来,如下所示:
tvCurrentTime.setText(DataFormat.formatTime(progress));
tvTitle.setEnabled(true);
除了每次重新启动时重置滚动条之外,这对失败没有任何影响。
我是否遗漏了一些细节,或者对可能出现问题的任何其他想法?多谢!
This was asked elsewhere, but the solution did not work for me. So posing it again with more context. The issue is that an activity contains a scrolling music title text view which is disrupted by an updating elapsed time counter text view.
I have these two TextView widgets in my activity layout (although they are encompassed by other layout containers).
<TextView android:id="@+id/v_current_time"
android:minWidth="26dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="right|center_vertical"
android:singleLine="true"
android:textSize="12sp"
android:enabled="false"
/>
<TextView android:id="@+id/v_track_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="normal"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:enabled="true"
/>
The music title is dynamically set to (in the test case) a long line of text. If I never update the text for the current time with the following line, the music title will happily scroll forever no matter how I interact with my pause and play buttons.
tvCurrentTime.setText(DataFormat.formatTime(progress));
But if I do set the text for the current time, the music title will stop. Pressing my pause button somehow kicks scrolling back into gear, but pressing play will cause the current time to update and stop it again.
Per the suggestion in this thread, I attempted to couple the setting of the time text with re-enabling of the scrolling title as follows:
tvCurrentTime.setText(DataFormat.formatTime(progress));
tvTitle.setEnabled(true);
This has no effect on the failure other than to reset the scroller each time it restarts.
Is there some detail that I am missing, or any other thoughts as to what could be going wrong? Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
字幕有问题。当 TextView(或包含 TextView 的窗口)失去焦点时,选取框将停止并重置(请参阅 TextView 的源代码)。
我猜你这里有 3 种可能的解决方案:
android:focusable="false"
。这样你的 TextView 就不会失去焦点。但这可能不是您想要的解决方案。onFocusChanged()
和onWindowFocusChanged()
以防止选取框停止和重置。Marquee is problematic. When TextView (or the Window containing the TextView)loses focus the marquee is stopped and reset (see the sources for TextView).
I guess you have 3 possible solutions here:
android:focusable="false"
in all other Views in your layout. That way your TextView shouldn't lose focus. But that's probably not the solution you want.onFocusChanged()
andonWindowFocusChanged()
to prevent marquee from being stopped and reset.还有另一种方法可以解决这个问题,而无需删除所有RelativeLayout。
您可以简单地将选取框 TextView 与 LinearLayout 包装在relativelayout 内作为容器。
There is another way to solve this without removing all RelativeLayout.
You can simply wrap the marquee TextView with a LinearLayout inside the RelativeLayout as a container.
(将上面的评论提升为答案)事实证明,如果我删除布局文件中的RelativeLayout并将其替换为LinearLayout,则上面的TextView XML配置可以正常工作,无需任何运行时更改(重置enabled=true或其他)。如果我不这样做,上面的建议 1 或 2(不确定 3)都不起作用。这似乎是相对布局的一个微妙且虚假的、未记录的失败。
(Promoting comment above to an answer) Turns out that the TextView XML configs above work fine without any runtime changes (to reset enabled=true or whatever) IF I get rid of the RelativeLayout's in my layout file and replace them with LinearLayout's. And neither suggestion 1 or 2 above (not sure about 3) works if I don't. That seems like a subtle and bogus undocumented failure of RelativeLayout.
在java代码中,做
tvTitle.setSelected(true);
(这里,tvTitle是你的滑动TextView变量)对我有用。这样做,似乎又让它集中了注意力。所以工作起来就像一个魅力。In java code, doing
tvTitle.setSelected(true);
(here, tvTitle is your sliding TextView variable) worked for me. Doing this, seems to make it focused again. So worked like a charm.我们有一个具有多种视图类型的适配器,第一个项目是带有选取框 TextView 的适配器。滚动回屏幕顶部后,未显示文本(我们调用了textView.isSelected == true)。
另外,问题不在于RelativeLayout,不需要用LinearLayout 包装TextView,因为布局中的当前结构是:
下面是TextView 启动选取框的方法:
它需要视图具有焦点或被选中才能启动选取框。
在 TextView.onFocusChanged(...) 中,调用 startStopMarquee(focused) 方法,它将触发滚动动画。这种方法的问题是我们需要使用 postDelayed 来请求焦点,这可能会导致一些问题。
检查 TextView.setSelected(boolean) 方法的作用后,很清楚为什么 textView.isSelected = true 没有触发动画。在它内部,它检查先前的 isSelected 状态,如果新的 isSelected 状态与前一个不同,它将处理 startMarquee() 或 stopMarquee() 。
解决方案是将所选状态更改为 false,然后将其设置为 true,效果非常好。
下面是 setSelected 和 onFocusChanged 这两个方法。
We had an adapter with multiple view types, and first item was one with marquee TextView. After scrolling back to top of the screen text was not shown (we've called textView.isSelected == true).
Also, issue was not the RelativeLayout, there was no need to wrap TextView with LinearLayout, as current structure in layout is:
Below is method from TextView to start marquee:
It requires for view to have focus or to be selected to start marquee.
In TextView.onFocusChanged(...) the startStopMarquee(focused) method is called and it will trigger the scroll animation. Issue we had with this approach is that we needed to request focus by using postDelayed, which might cause some issues.
After checking what TextView.setSelected(boolean) method was doing, it was clear why textView.isSelected = true was not triggering animation. Inside it it was checking previous isSelected state, and it would handle startMarquee() or stopMarquee() if new isSelected state was different from the previous one.
Solution was to change selected state to false and after that to set it to true which worked perfectly.
Below are both methods, setSelected, and onFocusChanged.