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

f87krz0w  于 2022-12-28  发布在  Android
关注(0)|答案(8)|浏览(233)

我尝试在文本视图中添加多个链接,类似于Google & Flipboard所做的如下所示的条款和条件以及隐私政策
到目前为止,我偶然使用了这种方法
设置文本(Html.从Html(myHtml);设置移动方法(链接移动方法.获取示例());
其中myHtml是一个href。
但是它不能给予我所需要的控制,例如发射一个碎片等。
在下面的两个例子中,你知道他们是如何做到这一点的吗?

rks48beu

rks48beu1#

我想我分享这一点有点晚了,但是我已经使用SpannableStringBuilder实现了同样的效果。
只需初始化要添加2个或更多侦听器的TextView,然后将其传递给我创建的以下方法:

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

在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

看起来像这样:

r7knjye2

r7knjye22#

您可以使用Linkify(* 安卓.文本.可扩展 *,*java.util.正则表达式.模式 *,*java.lang.字符串 *)

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:");

然后,您可以使用该方案启动活动,例如通过将该方案添加到 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>

如果您想执行自定义操作,可以将intent过滤器设置为当前Activity,它将具有singleTop启动模式。
这将导致onNewIntent被激发,其中可以使您的自定义操作:

@Override
protected void onNewIntent(final Intent intent) {
 ...
  if (intent.getScheme().equals(..)) {
    ..
  }
}
bwntbbo3

bwntbbo33#

我的解决方案是:

    • 首先,我们需要在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"/>

1.在字符串文件中,我添加了带有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>

1.在onCreateView中,将链接移动方法设置为文本视图

TextView privacyTextView = (TextView) root.findViewById(R.id.sign_up_privacy);
privacyTextView.setMovementMethod(LinkMovementMethod.getInstance());

现在,TextView链接是可单击的。

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

1.在清单文件中,我添加了针对"terms"和"privacy"的意图过滤器以及单示例启动模式

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

1.在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);
        }
    }
thtygnil

thtygnil4#

最好的方法是使用字符串文件
在字符串. 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>

在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());
}
cx6n0qe3

cx6n0qe35#

使用Textoo,可以像这样实现:
资源/值/字符串.xml:

<resources>
     <string name="str_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>
</resources>

资源/布局/我的活动.xml:

<TextView
    android:id="@+id/view_terms_and_privacy"
    android:text="@string/str_terms_and_privacy"
    />

java/我的包/MyActivity.java:

public class MyActivity extends Activity {
    ...
    protected void onCreate(Bundle savedInstanceState) {
        ...
        TextView termsAndPrivacy = Textoo
            .config((TextView) findViewById(R.id.view_terms_and_privacy))
            .addLinksHandler(new LinksHandler() {
                @Override
                public boolean onClick(View view, String url) {
                    if ("terms:".equals(url)) {
                        // Handle terms click
                        return true;  // event handled
                    } else if ("privacy:".equals(url)) {
                        // Handle privacy click
                        return true;  // event handled
                    } else {
                        return false;  // event not handled.  continue default processing i.e. launch web browser and display the link
                    }
                }
            })
            .apply();
        ...
    }
    ...
}

这种方法具有以下优点:

  • 保持文本外部化为字符串资源。使应用更容易本地化。
  • 可直接使用LinksHandler处理click事件,无需定义其他Intent过滤器
  • 代码更简单、可读性更强
fruv7luv

fruv7luv6#

这对我很有效:
在xml中:

<TextView
    android:id="@+id/tv_by_continuing_str"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:textSize="15sp"
    tools:text="Test msg 1 2, 3"
    android:textColor="@color/translucent_less_white3"
    android:textColorLink="@color/white"
    android:gravity="center|bottom"
    android:layout_above="@+id/btn_privacy_continue" />

在字符串. xml中

< string name="by_continuing_str2">< ! [ CDATA[By continuing to use this app, you agree to our <a href="https://go.test.com" style="color:gray"/> Privacy Statement </a> and <a href="https://go.test.com" style="color:gray"/>Services Agreement.]]>< / string>

在活动中:

TextView tv_by_continuing = (TextView) findViewById(R.id.tv_by_continuing);
tv_by_continuing.setText(Html.fromHtml(getString(R.string.by_continuing_str2)));
tv_by_continuing.setMovementMethod(LinkMovementMethod.getInstance());
vpfxa7rd

vpfxa7rd7#

private fun customTextView(view: TextView) {

        //I agree to the Terms of service & Privacy Policy,
        val spanTxt = SpannableStringBuilder(
            "I agree to the ")
        spanTxt.append("Terms of service")
        spanTxt.setSpan(object : ClickableSpan() {
            override fun onClick(widget: View) {
             
                toast("Terms of service link clicked")

            }
        }, spanTxt.length - "Term of services".length, spanTxt.length, 0)
        spanTxt.append(" and")
        spanTxt.append(" Privacy Policy")
        spanTxt.setSpan(object : ClickableSpan() {
            override fun onClick(widget: View) {

                toast("Privacy Policy link clicked")

            }
        }, spanTxt.length - " Privacy Policy".length, spanTxt.length, 0)
        view.movementMethod = LinkMovementMethod.getInstance()
        view.setText(spanTxt, TextView.BufferType.SPANNABLE)
    }
bzzcjhmw

bzzcjhmw8#

一个简单的解决办法是使用多个标签,一个标签对应一个链接,另一个标签对应文本。

[TermsOfServiceLabel][andLabel][PrivacyPolicy]

或者你有必要只用一个标签吗?

相关问题