1、固定高度导致的
已设置
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
但是不生效。。。
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()) {
}
}
这里判断主要条件有三个:
isFocused() || isSelected():焦点选中或者设置selected=true
getLineCount() == 1:singleLine=“true”
canMarquee()
断点发现canMarquee返回false。
private boolean canMarquee() {
int width = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
return width > 0 && (mLayout.getLineWidth(0) > width
|| (mMarqueeFadeMode != MARQUEE_FADE_NORMAL && mSavedMarqueeModeLayout != null
&& mSavedMarqueeModeLayout.getLineWidth(0) > width));
}
断点发现mRight和mLeft为0,其赋值发生在调用判断之后。。。所以这里返回了false。
我断点去看了其他可以正常滚动的TextView。发现了问题:
在makeNewLayout中有一段代码:
if (height != LayoutParams.WRAP_CONTENT && height != LayoutParams.MATCH_PARENT) {
startMarquee();
} else {
// Defer the start of the marquee until we know our width (see setFrame())
mRestartMarquee = true;
}
正常的view走了下面,这个标记mRestartMarquee置为true,然后后面会多次调用restartMarqueeIfNeeded
private void restartMarqueeIfNeeded() {
if (mRestartMarquee && mEllipsize == TextUtils.TruncateAt.MARQUEE) {
mRestartMarquee = false;
startMarquee();
}
}
而出问题的view因为在makeNewLayout中走了if分支,结果又还没layout给mRight和mLeft赋值,导致startMarquee没成功,标志位又是false,导致后面也不会尝试重新startMarquee。
改进方法:高度设为wrap_content
2、RecyclerView中item中的textview没滚动
如上述:
if ((mMarquee == null || mMarquee.isStopped()) && (isFocused() || isSelected())
&& getLineCount() == 1 && canMarquee()) {
}
这个判断中 (isFocused() || isSelected())返回了false,因为我设置的是itemview根布局可以获取焦点,而内部的textview没获取焦点。
改进方法:
itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
v.findViewById(R.id.tv_name).setSelected(hasFocus);
}
});