Android TextView的设置会停止其他TextView的字幕滚动
其他地方也有人问过这个问题,但解决方案对我来说并不奏效。因此,用更多的上下文来再次呈现它。问题在于,活动包含滚动音乐标题文本视图,该视图被更新已用时间计数器文本视图中断 我的活动布局中有这两个TextView小部件(尽管它们被其他布局容器所包含) 但是如果我为当前时间设置文本,音乐标题将停止。按“暂停”按钮会使滚动重新启动,但按“播放”会导致当前时间更新并再次停止 根据此线程中的建议,我尝试将时间文本的设置与重新启用滚动标题结合起来,如下所示:Android TextView的设置会停止其他TextView的字幕滚动,android,scroll,marquee,Android,Scroll,Marquee,其他地方也有人问过这个问题,但解决方案对我来说并不奏效。因此,用更多的上下文来再次呈现它。问题在于,活动包含滚动音乐标题文本视图,该视图被更新已用时间计数器文本视图中断 我的活动布局中有这两个TextView小部件(尽管它们被其他布局容器所包含) 但是如果我为当前时间设置文本,音乐标题将停止。按“暂停”按钮会使滚动重新启动,但按“播放”会导致当前时间更新并再次停止 根据此线程中的建议,我尝试将时间文本的设置与重新启用滚动标题结合起来,如下所示: tvCurrentTime.setText(Dat
tvCurrentTime.setText(DataFormat.formatTime(progress));
tvTitle.setEnabled(true);
这对故障没有影响,只是在每次重新启动时重置滚动条
是否有我遗漏的一些细节,或者关于可能出现的问题的任何其他想法?非常感谢 选框有问题。当TextView(或包含TextView的窗口)失去焦点时,字幕将停止并重置(请参阅TextView的来源)。 我想这里有3种可能的解决方案:
android:focusable=“false”
。这样你的文本视图就不会失去焦点。但这可能不是你想要的解决方案李>
onFocusChanged()
和onWindowFocusChanged()
,以防止停止和重置选框还有另一种方法可以解决这个问题,而无需删除所有RelativeLayout
您可以简单地在RelativeLayout中使用LinearLayout将字幕文本视图包装为容器 (将上面的注释升级为答案)如果我去掉布局文件中的RelativeLayout并将其替换为LinearLayout,则上述TextView XML配置在没有任何运行时更改(重置为enabled=true或其他)的情况下可以正常工作。如果我不同意,上面的建议1或2(不确定3)都不起作用。这似乎是一个微妙的、虚假的、没有记录的相对论失败 在java代码中,执行
tvTitle.setSelected(true)代码>(这里,tvTitle是您的滑动文本视图变量)对我有用。这样做,似乎使它再次集中。所以工作起来很有魅力。我们有一个具有多种视图类型的适配器,第一项是一个带有字幕TextView的适配器。滚动回屏幕顶部后,文本未显示(我们称为textView.isSelected==true)
此外,问题不是RelativeLayout,不需要使用LinearLayout包装TextView,因为布局中的当前结构是:
RelativeLayout
Button
TextView
下面是从TextView开始选取框的方法:
private void startMarquee() {
// Do not ellipsize EditText
if (getKeyListener() != null) return;
if (compressText(getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight())) {
return;
}
if ((mMarquee == null || mMarquee.isStopped()) && (isFocused() || isSelected())
&& getLineCount() == 1 && canMarquee()) {
if (mMarqueeFadeMode == MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
mMarqueeFadeMode = MARQUEE_FADE_SWITCH_SHOW_FADE;
final Layout tmp = mLayout;
mLayout = mSavedMarqueeModeLayout;
mSavedMarqueeModeLayout = tmp;
setHorizontalFadingEdgeEnabled(true);
requestLayout();
invalidate();
}
if (mMarquee == null) mMarquee = new Marquee(this);
mMarquee.start(mMarqueeRepeatLimit);
}
}
它要求视图具有焦点或被选中以开始选取框
在TextView.onFocusChanged(…)中,调用startStopMarquee(聚焦)方法,它将触发滚动动画。这种方法的问题是我们需要使用postDelayed请求焦点,这可能会导致一些问题
在检查TextView.setSelected(boolean)方法正在执行的操作之后,很清楚为什么TextView.isSelected=true没有触发动画。在它内部,它检查以前的isSelected状态,如果新的isSelected状态与以前的不同,它将处理startMarquee()或stopMarquee()
解决方案是将所选状态更改为false,然后将其设置为true,这非常有效
下面是setSelected和onFocusChanged两种方法
@Override
public void setSelected(boolean selected) {
boolean wasSelected = isSelected();
super.setSelected(selected);
if (selected != wasSelected && mEllipsize == TextUtils.TruncateAt.MARQUEE) {
if (selected) {
startMarquee();
} else {
stopMarquee();
}
}
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (isTemporarilyDetached()) {
// If we are temporarily in the detach state, then do nothing.
super.onFocusChanged(focused, direction, previouslyFocusedRect);
return;
}
if (mEditor != null) mEditor.onFocusChanged(focused, direction);
if (focused) {
if (mSpannable != null) {
MetaKeyKeyListener.resetMetaState(mSpannable);
}
}
startStopMarquee(focused);
if (mTransformation != null) {
mTransformation.onFocusChanged(this, mText, focused, direction, previouslyFocusedRect);
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
事实证明,如果我去掉布局文件中的RelativeLayout并用LinearLayout替换它们,则上述TextView XML配置在没有任何运行时更改的情况下(重置为enabled=true或其他)可以正常工作。如果我不同意,上面的建议1或2(不确定3)都不起作用。这是一个微妙的、虚假的、没有记录的相对论失败。除了重新排列布局文件以不使用相对布局之外,是否还有其他已知的解决方法?我甚至不确定这是否可能,因为我记得需要使用相对布局来克服线性布局的布局问题。谢谢你的评论RelativeLayout
导致了这种情况。使用LinearLayout
时,字幕工作正常,更新其他视图不会破坏字幕。这个信息应该有自己的答案…到目前为止,这是最好的答案!
private void startMarquee() {
// Do not ellipsize EditText
if (getKeyListener() != null) return;
if (compressText(getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight())) {
return;
}
if ((mMarquee == null || mMarquee.isStopped()) && (isFocused() || isSelected())
&& getLineCount() == 1 && canMarquee()) {
if (mMarqueeFadeMode == MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
mMarqueeFadeMode = MARQUEE_FADE_SWITCH_SHOW_FADE;
final Layout tmp = mLayout;
mLayout = mSavedMarqueeModeLayout;
mSavedMarqueeModeLayout = tmp;
setHorizontalFadingEdgeEnabled(true);
requestLayout();
invalidate();
}
if (mMarquee == null) mMarquee = new Marquee(this);
mMarquee.start(mMarqueeRepeatLimit);
}
}
@Override
public void setSelected(boolean selected) {
boolean wasSelected = isSelected();
super.setSelected(selected);
if (selected != wasSelected && mEllipsize == TextUtils.TruncateAt.MARQUEE) {
if (selected) {
startMarquee();
} else {
stopMarquee();
}
}
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (isTemporarilyDetached()) {
// If we are temporarily in the detach state, then do nothing.
super.onFocusChanged(focused, direction, previouslyFocusedRect);
return;
}
if (mEditor != null) mEditor.onFocusChanged(focused, direction);
if (focused) {
if (mSpannable != null) {
MetaKeyKeyListener.resetMetaState(mSpannable);
}
}
startStopMarquee(focused);
if (mTransformation != null) {
mTransformation.onFocusChanged(this, mText, focused, direction, previouslyFocusedRect);
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}