Несколько Clickable ссылок в TextView на Android
Я пытаюсь добавить несколько ссылок в текстовом виде, аналогичном тому, что сделал Google и Flipboard ниже со своими Условиями и условиями И Политика конфиденциальности, показанная на снимке экрана ниже:
До сих пор я наткнулся на использование этого подхода
textView.setText(Html.fromHtml(myHtml);
textView.setMovementMethod(LinkMovementMethod.getInstance());
где myHtml является href.
Но это не дает мне контроля. Мне нужно, например, запустить фрагмент и т.д.
Любая идея, как они достигают этого в двух примерах ниже?
![Flipboard terms and conditions view]()
![Google terms and conditions view]()
Ответы
Ответ 1
Вы можете использовать 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:");
а затем вы можете использовать схему для запуска действия, например, добавив эту схему в 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>
Если вы хотите выполнить настраиваемое действие, вы можете установить фильтр намерений на свою текущую активность, которая будет иметь одномоментный запуск.
Это приведет к срабатыванию onNewIntent, где вы можете выполнить свои собственные действия:
@Override
protected void onNewIntent(final Intent intent) {
...
if (intent.getScheme().equals(..)) {
..
}
}
Ответ 2
Я думаю, что немного опоздал, чтобы поделиться этим, но я добился того же, используя 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);
}
В вашем 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
И это выглядит так:
![enter image description here]()
Надеюсь, это поможет кому-то.:)
Ответ 3
Здесь мое решение:
Сначала нам нужно иметь интерактивные ссылки в нашем TextView:
-
Здесь мой TextView в макете xml, не добавляйте обработку ссылок
Параметры.
<TextView
android:id="@+id/sign_up_privacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/terms_and_privacy"/>
-
В файле строк я добавил текст ресурса с тегами 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>
-
В onCreateView установите LinkMovementMethod в TextView
TextView privacyTextView = (TextView) root.findViewById(R.id.sign_up_privacy);
privacyTextView.setMovementMethod(LinkMovementMethod.getInstance());
Теперь ссылки TextView можно щелкнуть.
Во-вторых, нам нужно обработать эти клики:
-
В моем файле манифеста я добавил фильтр намерений для "условий" и "конфиденциальности",
и режим запуска одного экземпляра
<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>
-
В 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);
}
}
Ответ 4
Это работает для меня:
в 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" />
В файле strings.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());
Ответ 5
Легким решением для этого было бы использование нескольких меток. Один для каждой ссылки и один для текста.
[TermsOfServiceLabel][andLabel][PrivacyPolicy]
Или необходимо, чтобы вы использовали только одну метку?
Ответ 6
С Textoo это может быть достигнуто, например:
RES/значения/strings.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>
Рез/макет/myActivity.xml:
<TextView
android:id="@+id/view_terms_and_privacy"
android:text="@string/str_terms_and_privacy"
/>
Java/MyPackage/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();
...
}
...
}
Этот подход имеет следующие преимущества:
- Сохранять текст в виде строкового ресурса. Упростите локализацию своего приложения.
- Может обрабатывать событие click напрямую с помощью
LinksHandler
и не нужно определять дополнительный фильтр намерения
- Упрощенный и читаемый код