链接跨度从ListView convertView丢失

时间:2014-01-17 10:24:06

标签: android listview textview linkify spannablestring

为什么滚动时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的重用做了一个肮脏的修复:(任何想法如何更好地解决这个问题?

4 个答案:

答案 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>