18

textViewをにautoLinkMask設定するLinkify.ALLと、リンクを開くことができ、ブラウザにWebページが表示されます。

アプリケーションを離れないwebViewでそれを行う別のアクティビティを呼び出す必要があります。

重要な注意事項:

  • textViewコンテンツを変更することはオプションではありません。リンクを、それらが持っているスキームと同じように表示する必要があります。
  • textViewには、リンクだけでなく多くのテキストがあります。

私は調べてみましmovementMethodIntentFiltersが、何かを見逃しているかもしれませんが、仕方がないようです。

それで、TextViewブラウザを開かずに何かをするために、で触れられたリンクを傍受するオプションはありますか?

このSOの質問に言及したい場合は、なぜそれが私と同じ問題を解決しないように見えるのか、いくつかの議論をしてください。

4

5 に答える 5

26

ステップ1:メソッドClickableSpanで必要なことを実行する独自のサブクラスを作成しますonClick()(例YourCustomClickableSpan:)

URLSpanステップ2:すべてのオブジェクトの一括変換を実行してオブジェクトにしYourCustomClickableSpanます。私はこれのためのユーティリティクラスを持っています:

public class RichTextUtils {
    public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(Spanned original,
    Class<A> sourceType,
    SpanConverter<A, B> converter) {
        SpannableString result=new SpannableString(original);
        A[] spans=result.getSpans(0, result.length(), sourceType);

        for (A span : spans) {
            int start=result.getSpanStart(span);
            int end=result.getSpanEnd(span);
            int flags=result.getSpanFlags(span);

            result.removeSpan(span);
            result.setSpan(converter.convert(span), start, end, flags);
        }

        return(result);
    }

    public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
        B convert(A span);
    }
}

次のように使用します。

yourTextView.setText(RichTextUtils.replaceAll((Spanned)yourTextView.getText(),
                                             URLSpan.class,
                                             new URLSpanConverter()));

このような習慣でURLSpanConverter

class URLSpanConverter
      implements
      RichTextUtils.SpanConverter<URLSpan, YourCustomClickableSpan> {
    @Override
    public URLSpan convert(URLSpan span) {
      return(new YourCustomClickableSpan(span.getURL()));
    }
  }

URLSpanすべてのオブジェクトをオブジェクトに変換しYourCustomClickableSpanます。

于 2012-07-10T16:12:27.407 に答える
3

URLスパンを置き換える同じメソッドに直接追加できるクリックリスナーを追加することで、@CommonsWareのコードをよりエレガントで明確にします。

  1. を定義しYourCustomClickableSpan Classます。

     public static class YourCustomClickableSpan extends ClickableSpan {
    
        private String url;
        private OnClickListener mListener;
    
        public YourCustomClickableSpan(String url, OnClickListener mListener) {
            this.url = url;
            this.mListener = mListener;
        }
    
        @Override
        public void onClick(View widget) {
            if (mListener != null) mListener.onClick(url);
        }
    
        public interface OnClickListener {
            void onClick(String url);
        }
    }
    
  2. RichTextUtils ClassTextViewのスパンテキストを操作するものを定義します。

    public static class RichTextUtils {
    
        public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll (
              Spanned original,
              Class<A> sourceType,
              SpanConverter<A, B> converter,
              final ClickSpan.OnClickListener listener) {
    
                  SpannableString result = new SpannableString(original);
                  A[] spans = result.getSpans(0, result.length(), sourceType);
    
                  for (A span : spans) {
                      int start = result.getSpanStart(span);
                      int end = result.getSpanEnd(span);
                      int flags = result.getSpanFlags(span);
    
                      result.removeSpan(span);
                      result.setSpan(converter.convert(span, listener), start, end, flags);
                  }
    
                  return (result);
              }
    
              public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
                  B convert(A span, ClickSpan.OnClickListener listener);
    
         }
    }
    
  3. URLSpanConverter classカスタムスパンでURLSpanを置き換える実際のコードを実行するコードを定義します。

        public static class URLSpanConverter
            implements RichTextUtils.SpanConverter<URLSpan, ClickSpan> {
    
    
            @Override
            public ClickSpan convert(URLSpan span, ClickSpan.OnClickListener listener) {
                return (new ClickSpan(span.getURL(), listener));
            }
       }
    
  4. 使用法

    TextView textView = ((TextView) this.findViewById(R.id.your_id));
    textView.setText("your_text");
    Linkify.addLinks(contentView, Linkify.ALL);
    
    Spannable formattedContent = UIUtils.RichTextUtils.replaceAll((Spanned)textView.getText(), URLSpan.class, new UIUtils.URLSpanConverter(), new UIUtils.ClickSpan.OnClickListener() {
    
        @Override
        public void onClick(String url) {
            // Call here your Activity
        }
    });
    textView.setText(formattedContent);
    

ここではすべてのクラスを静的として定義したので、Utilクラスに直接情報を入力して、どこからでも簡単に参照できることに注意してください。

于 2015-01-31T15:05:27.553 に答える
2

作成したTextooを使用して別のソリューションを共有するだけです。

    TextView yourTextView = Textoo
        .config((TextView) findViewById(R.id.your_text_view))
        .addLinksHandler(new LinksHandler() {
            @Override
            public boolean onClick(View view, String url) {
                if (showInMyWebView(url)) {
                    //
                    // Your custom handling here
                    //
                    return true;  // event handled
                } else {
                    return false; // continue default processing i.e. launch browser app to display link
                }
            }
        })
        .apply();

内部的には、ライブラリURLSpanはTextViewのをClickableSpan、指定されたユーザーにクリックイベントをディスパッチするカスタム実装に置き換えますLinksHandler。このメカニズムは、@commonsWareのソリューションと非常によく似ています。使いやすくするために、より高いレベルのAPIにパッケージ化するだけです。

于 2016-01-14T08:36:11.957 に答える
0

デビッド・ヘドルンドの彼自身への答えは進むべき道だと思います。私の場合、SMSコンテンツフォームユーザーの受信トレイを含むTextViewがあり、休眠中の動作を処理したいと思いました。

  1. WEB URLが見つかった場合は、それをリンクして、アプリケーション内でクリックを処理します。
  2. 電話番号が見つかった場合は、それをリンクし、ピッカーを表示するクリックを処理して、ユーザーがその番号に電話をかけるか、アドレス帳に追加するかを選択できるようにします(すべてアプリケーション内で)

これを達成するために、私はこのようにリンクされた答えを使用しました:

TextView tvBody = (TextView)findViewById(R.id.tvBody);
tvBody.setText(messageContentString);

// now linkify it with patterns and scheme
Linkify.addLinks(tvBody, Patterns.WEB_URL, "com.my.package.web:");
Linkify.addLinks(tvBody, Patterns.PHONE, "com.my.package.tel:");

今マニフェストで:

<activity
    android:name=".WebViewActivity"
    android:label="@string/web_view_activity_label">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.VIEW"/>
        <data android:scheme="com.duckma.phonotto.web"/>
    </intent-filter>
</activity>
...
<activity
    android:name=".DialerActivity"
    android:label="@string/dialer_activity_label">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.VIEW"/>
        <data android:scheme="com.duckma.phonotto.tel"/>
    </intent-filter>
</activity>
<activity
    android:name=".AddressBook"
    android:label="@string/address_book_activity_label">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.VIEW"/>
        <data android:scheme="com.duckma.phonotto.tel"/>
    </intent-filter>
</activity>

そして、それは私にとってはうまく機能します。ユーザーが電話番号をクリックすると、ピッカーがダイヤラー/アドレスブックの選択肢とともに表示されます。呼び出されたアクティビティgetIntent().getData()では、データを含む渡されたURLを見つけるために使用します。

于 2015-02-23T12:41:38.770 に答える
-3

これを行うより:

        TextView textView=(TextView) findViewById(R.id.link);
        textView.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Intent intent=new Intent(YourActivityName.this,WebActivity.class);
                startActivity(intent);
            }
        });

WebActivityクラスのonCreate:

WebView webView=(WebView) findViewById(R.id.web);
webView.loadUrl("http://www.google.co.in");

xmlのtextviewの下にこれを追加します:

android:clickable="true"
于 2012-07-10T13:22:24.990 に答える