Android上TextView中的多个可点击链接

And*_*ast 19 java android textview android-layout

我想添加多个链接以类似于谷歌与Flipboard的下面已经与他们做一个TextView 条款和条件隐私政策在下面的屏幕截图所示:

到目前为止,我偶然发现了使用这种方法

textView.setText(Html.fromHtml(myHtml); textView.setMovementMethod(LinkMovementMethod.getInstance());

其中myHtml是一个href.

但它并没有给我控制我需要例如发射片段等.

知道如何在下面的两个例子中实现这一点吗?

Flipboard条款和条件视图

谷歌条款和条件查看

Tus*_*gna 82

我认为我分享这个有点晚了,但我已经使用SpannableStringBuilder实现了相同的目标.

只需初始化TextView您要添加2个或更多侦听器的内容,然后将其传递给我创建的以下方法:

private void customTextView(TextView view) {
        SpannableStringBuilder spanTxt = new SpannableStringBuilder(
                "I agree to the ");
        spanTxt.append("Term of services");
        spanTxt.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getApplicationContext(), "Terms of services Clicked",
                        Toast.LENGTH_SHORT).show();
            }
        }, spanTxt.length() - "Term of services".length(), spanTxt.length(), 0);
        spanTxt.append(" and");
        spanTxt.setSpan(new ForegroundColorSpan(Color.BLACK), 32, spanTxt.length(), 0);
        spanTxt.append(" Privacy Policy");
        spanTxt.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(getApplicationContext(), "Privacy Policy Clicked",
                        Toast.LENGTH_SHORT).show();
            }
        }, spanTxt.length() - " Privacy Policy".length(), spanTxt.length(), 0);
        view.setMovementMethod(LinkMovementMethod.getInstance());
        view.setText(spanTxt, BufferType.SPANNABLE);
    } 
Run Code Online (Sandbox Code Playgroud)

在您的XML中,用于android:textColorLink添加您选择的自定义链接颜色.像这样:

   <TextView
     android:id="@+id/textView1"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="TextView"
     android:textColorLink="#C36241" />  //#C36241 - Rust
Run Code Online (Sandbox Code Playgroud)

这看起来像这样:

在此输入图像描述

希望它可以帮助某人.:)

  • 我认为这应该是公认的答案:-) (16认同)
  • 如果不需要翻译字符串,此方法效果很好 (2认同)

har*_*ane 12

你可以使用Linkify(android.text.Spannable,java.util.regex.Pattern,java.lang.String)

String termsAndConditions = getResources().getString(R.string.terms_and_conditions);
String privacyPolicy = getResources().getString(R.string.privacy_policy);

legalDescription.setText(
    String.format(
        getResources().getString(R.string.message),
        termsAndConditions,
        privacyPolicy)
);
legalDescription.setMovementMethod(LinkMovementMethod.getInstance());

Pattern termsAndConditionsMatcher = Pattern.compile(termsAndConditions);
Linkify.addLinks(legalDescription, termsAndConditionsMatcher, "terms:");

Pattern privacyPolicyMatcher = Pattern.compile(privacyPolicy);
Linkify.addLinks(legalDescription, privacyPolicyMatcher, "privacy:");
Run Code Online (Sandbox Code Playgroud)

然后你可以使用该方案来启动一个活动,例如在AndroidManifest中添加方案:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="terms" />
    <data android:scheme="privacy" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)

如果要执行自定义操作,可以将intent-filter设置为当前活动,该活动将具有singleTop启动模式.

这将导致onNewIntent被触发,可以进行自定义操作:

@Override
protected void onNewIntent(final Intent intent) {
 ...
  if (intent.getScheme().equals(..)) {
    ..
  }
}
Run Code Online (Sandbox Code Playgroud)


Sal*_*han 7

最好的方法是使用字符串文件

在 string.xml 中

<string name="agree_to_terms">I agree to the %1$s and %2$s</string>
<string name="terms_of_service">Terms of Service</string>
<string name="privacy_policy">Privacy Policy</string>
Run Code Online (Sandbox Code Playgroud)

在onCreateView中调用下面的方法

private void setTermsAndCondition() {
    String termsOfServicee = getString(R.string.terms_of_service);
    String privacyPolicy = getString(R.string.privacy_policy);
    String completeString = getString(R.string.agree_to_terms, termsOfServicee,privacyPolicy);
    int startIndex = completeString.indexOf(termsOfServicee);
    int endIndex = startIndex + termsOfServicee.length();
    int startIndex2 = completeString.indexOf(privacyPolicy);
    int endIndex2 = startIndex2 + privacyPolicy.length();
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(completeString);
    ClickableSpan clickOnTerms = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(this, "click on terms of service", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(ContextCompat.getColor(this, R.color.blue));

        }
    };
    ClickableSpan clickOnPrivacy = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(this, "click on privacy policy", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(ContextCompat.getColor(this, R.color.blue));

        }
    };
    spannableStringBuilder.setSpan(clickOnTerms, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableStringBuilder.setSpan(clickOnPrivacy, startIndex2, endIndex2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    yourTextView.setText(spannableStringBuilder);
    yourTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
Run Code Online (Sandbox Code Playgroud)


Ahm*_*aka 6

这是我的解决方案:

首先,我们需要在 TextView 中有可点击的链接:

  1. 这是我在 xml 布局中的 TextView,不添加任何链接处理参数。

    <TextView
            android:id="@+id/sign_up_privacy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/terms_and_privacy"/>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在字符串文件中,我添加了带有 html 标签的资源文本

    <string name="terms_and_privacy">By signing up you agree to our <a href="terms:">Terms of Service</a> and <a href="privacy:">Privacy Policy.</a></string>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在 onCreateView 中将 LinkMovementMethod 设置为 TextView

    TextView privacyTextView = (TextView) root.findViewById(R.id.sign_up_privacy);
    privacyTextView.setMovementMethod(LinkMovementMethod.getInstance());
    
    Run Code Online (Sandbox Code Playgroud)

现在 TextView 链接是可点击的。

其次,我们需要处理这些点击:

  1. 在我的清单文件中,我为“条款”和“隐私”以及单实例启动模式添加了意图过滤器

    <activity
                android:name=".MyActivity"
                android:launchMode="singleInstance">
                <intent-filter>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <action android:name="android.intent.action.VIEW"/>
    
                    <data android:scheme="terms"/>
                    <data android:scheme="privacy"/>
                </intent-filter>
            </activity>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在 MyActivity 中,覆盖 onNewIntent 以捕获隐私和条款意图

    @Override
        protected void onNewIntent(Intent intent)
        {
            if (intent.getScheme().equalsIgnoreCase(getString("terms")))
            {
                //handle terms clicked
            }
            else if (intent.getScheme().equalsIgnoreCase(getString("privacy")))
            {
                //handle privacy clicked
            }
            else
            {
                super.onNewIntent(intent);
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

  • 无论如何,我建议使用 SpannableString 作为更好的解决方案:http://stackoverflow.com/a/30365618/1729952 (2认同)