为什么滚动时ListView
中的链接会丢失?从调试中可以清楚地看出,TextView
的{{1}}上没有第二次添加跨度。
这是从适配器的convertView
调用的一段代码。
getView
...
String body = MyItemDetails.getBody(); // String to linkify
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
viewHolder.textView.setText(spannable);
viewHolder.textView.setTextIsSelectable(true); // adds additional spans
viewHolder.textView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
viewHolder.textView.setAutoLinkMask(Linkify.WEB_URLS);
...
使用MyCustomUri.addHashtagSpans()
SpannableString
创建MyCustomSpan
。
问题是,当我在URLSpan
链接中向上和向下滚动时,会丢失。而当屏幕第一次打开时,它设置正确。
现在我通过禁用ListView
的重用做了一个肮脏的修复:(任何想法如何更好地解决这个问题?
答案 0 :(得分:1)
当textview的数据写入包裹以进行保留时,某些可跨越的信息可能会丢失。
请参阅TextView.onSaveInstanceState(),TextView.onRestoreInstanceState()和TextView.SavedState。
确定android将保留和不保留的内容通常会非常令人沮丧。我经常在我的视图上setSaveEnabled(false)
来禁用基本小部件的不可预测的默认行为。
此外,视图模式仅用于保留视图/布局实例层次结构。为了避免每次getView()
充气或查看您的观看次数。在getView()
提供视图数据时,您始终有责任更新视图的数据。
您不需要完全禁用视图图案模式,而只是简单地每getView()
更新一次文本,就像您可能已经在做的那样。
答案 1 :(得分:1)
Hello使用此自定义类
public class MyCustomSpannable extends ClickableSpan {
String Url;
Context mContext;
public MyCustomSpannable(String Url, Context context) {
this.Url = Url;
mContext = context;
}
@Override
public void updateDrawState(TextPaint ds) {
// Customize your Text Look if required
ds.setColor(mContext.getResources().getColor(R.color.red_text));
ds.setFakeBoldText(true);
// ds.setStrikeThruText(true);
ds.setTypeface(CommonFunctios.getfontNormal(mContext));
// ds.setUnderlineText(true);
// ds.setShadowLayer(10, 1, 1, Color.WHITE);
// ds.setTextSize(15);
}
@Override
public void onClick(View widget) {
}
public String getUrl() {
return Url;
}
}
并在适配器中用此
替换您的代码String text = holder.txt_terms.getText().toString();
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text);
MyCustomSpannable customSpannable = new MyCustomSpannable(text,
mcontext) {
@Override
public void onClick(View widget) {
Log.e("on click", "message");
((OpticalOffersActivity) mcontext).callDialogBox(position);
}
};
stringBuilder.setSpan(customSpannable, 0, text.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
holder.txt_terms.setText(stringBuilder, BufferType.SPANNABLE.SPANNABLE);
holder.txt_terms.setMovementMethod(LinkMovementMethod.getInstance());
希望它会对你有所帮助。
答案 2 :(得分:1)
if(convertView==null)
{
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
...
String body = MyItemDetails.getBody(); // String to linkify
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
viewHolder.textView.setText(spannable);
viewHolder.textView.setTextIsSelectable(true); // adds additional spans
viewHolder.textView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
viewHolder.textView.setAutoLinkMask(Linkify.WEB_URLS);
...
该spannable代码必须放在getView()
方法的if-else循环之外,就像我在上面的代码中所做的那样。
答案 3 :(得分:1)
这里有几个问题,所以让我一次解决一个问题。您直接询问的问题(链接消失)是一个副作用,即当您还手动将自己的跨度添加到文本时,TextView
中的自动链接行为不一定能正常工作。 ..不要使用它。删除setAutoLinkMask()
触发器,消失的链接问题将消失。
相反,您可以使用Linkify
轻松地将相同的网络链接行为直接添加到文本范围中。但是,这只是您问题的一部分。您选择的MovementMethod
与可点击链接不兼容。它(部分)在您的代码中工作的原因现在是因为自动链接掩码导致视图的MovementMethod
被隐藏在引擎盖下LinkMovementMethod
...然后被重置视图被回收。我通常使用的模式(应用于您的代码示例)将是:
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
Linkify.addLinks(spannable, Linkify.WEB_URLS);
viewHolder.textView.setText(spannable);
addLinkMovementMethod(textView);
addLinkMovementMethod()
是帮手,我看起来像这样:
private void addLinkMovementMethod(TextView t) {
MovementMethod m = t.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (t.getLinksClickable()) {
t.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
如果没有必要,这就不会重置每个视图回收的值。之前的代码块将为您提供正确点击并永不消失的链接...
但是,我猜测你调用的方法是否也试图使列表中的链接文本可选(例如,调用setTextIsSelectable()
并选择ArrowKeyMovementMethod
)。由于我上面讨论的MovementMethod
问题,这有点棘手。为了创建支持链接点击和文本选择的MovementMethod
,我将引导您访问该主题的现有SO帖子,其中包含您需要进行的自定义设置的示例代码:Can a TextView be selectable AND contain links? < / p>