2014-01-17 6 views
5

スクロールするとListViewのリンクが失われるのはなぜですか?デバッグからは、convertViewTextViewにスパンが2回追加されないことは明らかです。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()URLSpanを拡張してMyCustomSpanSpannableStringを作成します。

問題は、私が上下にスクロールすると、ListViewのリンクが失われることです。一方、画面が最初に開かれたときは、正しく設定されています。

は、今私はconvertViewの再利用を無効にすることで、汚れの修正をした:(任意のアイデアを、より良い、この問題を解決する方法?のTextViewのデータを保持するために小包に書き込まれたときspannable情報の

+0

getViewメソッド(または、CursorAdapterを拡張する場合はbindViewとnewView)。 –

答えて

1

一部はおそらく失われています。

は参照TextView.onSaveInstanceState()TextView.onRestoreInstanceState()、およびTextView.SavedState

多くの場合、どのようなアンドロイドの意思を決定することは非常にイライラすることができます。私は、多くの場合、ちょうどsetSaveEnabled(false)私の見解で予測不可能なデフォルトが可能無効に保持していますベースのウィジェットの動き。

また、ビューホルダーパターンは実際にはビュー/レイアウトインスタンス階層を保持するためのものです。あなたの意見を膨らませたり見つけたりすることを避けるために、すべてgetView()getView()から表示するときは、常にビューのデータを更新するのはあなたの責任です。

ビューホールダーパターンを完全に無効にする必要はありません。単に、テキストをgetView()ごとに更新するだけで済みます。

+0

'setSaveEnabled(偽)'しようとしましたが、ちょうどさておきだという雅:( – ViliusK

+0

を助けていない。ポイントに直接 –

+0

を問題を解決するつもりはないと、あなたは常にあなたのビューステートを保持するためにアンドロイドに頼ることはできませんとであるべきであるということですそれを自分で行うことの習慣。 –

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

でコードを置き換え、それはあなたを助けることを願っています。 spannableコードは、私は上記のコードでそれをやった方法のように、getView()方法であれば、他のループの外に配置されなければならないことを

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

+0

それは本当です、私はspannableコードをif-elseブロックの外側に置きました。 convertViewが再利用されると問題が発生します。 「MyCustomUri」スパンは2回追加されません。 – ViliusK

1

ここにはいくつかの問題がありますので、一度に1つずつ取り上げてください。あなたが直接尋ねた問題(リンクが消えていく)は、TextViewでの自動リンクの動作が、手動でテキストに手動でスパンを追加しているときに必ずしもうまくいかないという事実の副作用です。それを使用する。 setAutoLinkMask()トリガーを削除すると、消えているリンクの問題はなくなります。

代わりに、Linkifyを使用して、同じWebリンク動作をテキスト範囲に直接簡単に追加できます。しかし、これはあなたの問題の一部です。あなたが選択したMovementMethodは、クリック可能なリンクと実際には互換性がありません。あなたのコードでそれが(部分的に)動作する理由は、オートリンクマスクがビューのMovementMethodをフードの下に密かにマッサージしてLinkMovementMethodにしているからです。ビューがリサイクルされた後にリセットされます。 (あなたのコード例に適用される)私は一般的に使用パターンは次のようになります。addLinkMovementMethod()はヘルパーは私が持っているが、このようになりますです

final Spannable spannable = MyCustomUri.addHashtagSpans(context, body); 
Linkify.addLinks(spannable, Linkify.WEB_URLS); 
viewHolder.textView.setText(spannable); 

addLinkMovementMethod(textView); 

:これは単純に各上の値をリセットするから続け

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を作成するには、作成する必要のあるカスタマイズのサンプルコードを含む、このトピックの既存の投稿に移動します:Can a TextView be selectable AND contain links?

+0

これは有望な解決策に見えます。試してみる。 – ViliusK

関連する問題