2014-01-17 96 views
5

为什么在滚动时丢失ListView中的链接?从调试中可以明显看出,这些跨度不会在convertViewTextView上第二次添加。链接跨度从ListView的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()MyCustomSpan创建SpannableString与延伸URLSpan

问题是,当我在ListView上下滚动链接丢失。而第一次打开屏幕时,屏幕设置正确。

现在我通过禁用convertView重用:(任何想法做了一个肮脏的修复如何解决这个问题好?

+0

请将您的完整代码发布到getView方法(如果您正在扩展CursorAdapter,则为bindView和newView)。 –

回答

1

一些spannable信息当TextView中的数据被写入到保留一个包裹可能丢失。

TextView.onSaveInstanceState()TextView.onRestoreInstanceState(),并TextView.SavedState

它往往是非常令人沮丧,以确定哪些Android将并不会挽留。我往往只是setSaveEnabled(false)对我的看法禁用不可预知的默认是基础小部件的好处。

此外,视图模式仅用于保留视图/布局实例层次结构。每隔getView()即可免去充气或找到您的看法。从getView()提交视图时,始终有责任更新视图数据。

您不需要完全禁用视图模式,而只是简单地更新每个getView()的文本,就像您可能已经在做的那样。

+0

尝试了'setSaveEnabled(false)',但没有帮助:( – ViliusK

+0

雅只是放在一边。它不会直接解决问题 –

+0

关键是你不能总是依靠android来保留你的视图状态,并应该 –

1

您好使用此自定义类

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()); 

更换你的代码希望它会帮助你。

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代码必须被放置在的if-else循环之外的getView()方法,像我这样做是在上面的代码的方式。

+0

的确如此,我在if-else块之外放置了可扩展的代码。问题出现在convertView被重用时。 'MyCustomUri'跨度不会被第二次添加。 – ViliusK

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?

+0

这看起来很有前途的解决方案。将尝试它。 – ViliusK