Android implements some text in TextView to implement click jump function
1. Project introduction
1.1 Project background and significance
In mobile applications, it is often necessary to have a click-and-jump function in a paragraph of text - such as the "Privacy Policy" in the user agreement, "See More" in rich text, "@User Name" in the chat interface, news summary with hyperlinks, etc. If you put the entire text in Button, Link or a separate View, it usually brings problems such as complex layout, difficult to uniform styles, and poor maintainability. With the help of Android native SpannableString and ClickableSpan, we can realize some text click interaction in a TextView, and the style is unified with ordinary text, which is simple to develop and extremely low performance consumption.
1.2 Project Objectives
In a single TextView, click responses to specific text and jump to the specified activity or web page;
Supports multiple regions to be clickable at the same time and can be configured with different callback logic;
The style can be customized: the colors, underlines, etc. before and after clicking the text can be controlled;
Demonstrate two mainstream methods:
SpannableString + ClickableSpan
with Jetpack Compose (optional extension);Provides complete source code with detailed comments for quick integration and secondary development.
2. Related knowledge and technical points
2.1 Android text display basics
- TextView: Android's most commonly used text display control, supports single-line, multi-line, Ellipsize, line spacing, Typeface and other properties.
- Spannable: Android text variable tag interface, allowing insertion of various styles or clickable areas into strings.
2.2 SpannableString and Spanned
- SpannableString: A text container that implements the CharSequence and Spannable interfaces, which can dynamically add Spans to the middle part of the string.
- Spanned: means that the text of the Span object has been attached; the Spanned interface is mainly used to query, add, and remove Spans.
2.3 ClickableSpan and MovementMethod
-
ClickableSpan: Inherited from
CharacterStyle
andUpdateAppearance
Span, used to intercept and process text click events. -
LinkMovementMethod: TextView does not support Span clicks by default, you need to pass
(())
Route the click event toClickableSpan
。
2.4 Style Span
ForegroundColorSpan: Change the color of the text;
UnderlineSpan: Add underline;
StyleSpan: Set bold, italic, etc.;
BackgroundColorSpan: Set text background color.
2.5 Touch feedback optimization
By setting
()
Or customSelection
Color, avoid default highlighting when clicked to affect vision.
Ideas for realization
Identify the location of the target text
In a complete text,String#indexOf()
、Pattern
Or manually split to get the start and end subscripts of each substring that needs to be clicked in the original text.Build SpannableString
Encapsulate the original string asSpannableString spannable = new SpannableString(fullText)
, various spans will be added to this object later.-
Add ClickableSpan to the target area
Create anonymous
ClickableSpan
, rewriteonClick(View widget)
Execute jump logic;At the same time, it can be
updateDrawState(TextPaint ds)
Controll the text style before and after clicking (color, whether there is underline, etc.).
-
Outer TextView Configuration
(spannable);
(());
();
// Cancel click to highlight
Jump logic
existonClick
, can be usedIntent
Jump to newActivity
, or useCustomTabsIntent
Open the web page, or notify the host through the callback interface.Multi-paragraph, multi-objective support
Loop the above steps and add an independent one for each substringClickableSpan
; It can also be packaged into tools and processed in batches.
4. Complete project code
// ==================== ==================== package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; /** * MainActivity: Demonstrate to implement click-to-jump in TextView */ public class MainActivity extends AppCompatActivity { private TextView tvRichText; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); // Loading layout tvRichText = findViewById(.tv_rich_text); // The original whole paragraph of text String fullText = "Welcome to use this app, view the User Agreement and Privacy Policy, or visit our official website to learn more."; // Need a clickable substring and corresponding jump target String policy = "User Agreement"; String privacy = "Privacy Policy"; String website = "Official Website"; // Call the encapsulated tool method to generate SpannableString SpannableString spannable = createClickableSpan( this, fullText, new ClickTarget(policy, ("#1E88E5"), widget -> { // Jump to the protocol page Intent intent = new Intent(this, ); ("title", "User Agreement"); startActivity(intent); }), new ClickTarget(privacy, ("#D81B60"), widget -> { // Jump to the Privacy Policy page Intent intent = new Intent(this, ); ("title", "Privacy Policy"); startActivity(intent); }), new ClickTarget(website, ("#43A047"), widget -> { // Open external link Intent intent = new Intent(Intent.ACTION_VIEW); (("")); startActivity(intent); }) ); // Set SpannableString to TextView and enable click (spannable); (()); (); } // ==================================================================== // ========== The following are tool methods and related data classes. You can directly integrate without putting them in a separate file ============ // ==================================================================== /** * ClickTarget: encapsulates information of a single clickable target */ public static class ClickTarget { public final String text; // Click the text to be matched public final int color; // Click on the foreground color of the text public final listener; // Click on the callback public ClickTarget(String text, int color, @NonNull listener) { = text; = color; = listener; } } /** * Build a SpannableString with multiple clickable text * * @param context context for starting Activity in callback * @param fullText Original text * @param targets Multiple ClickTargets containing click text, colors, and callbacks * @return SpannableString, can be set directly to TextView */ public static SpannableString createClickableSpan( Context context, String fullText, ClickTarget... targets ) { SpannableString spannable = new SpannableString(fullText); for (ClickTarget target : targets) { String key = ; int start = (key); if (start < 0) { // No substring found, skipped continue; } int end = start + (); // Set text color ( new ForegroundColorSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); // Click Span (new ClickableSpan() { @Override public void updateDrawState(TextPaint ds) { (ds); (); // The text color before and after click (true); // Display the underscore, if it needs to be removed, set to false } @Override public void onClick(@NonNull View widget) { (widget); } }, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return spannable; } } // ==================== ==================== package ; import ; import ; import ; /** * ProtocolActivity: A universal Activity used to demonstrate user agreements or privacy policies */ public class ProtocolActivity extends AppCompatActivity { private TextView tvTitle, tvContent; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_protocol); tvTitle = findViewById(.tv_title); tvContent = findViewById(.tv_content); // Get the title from Intent and display it String title = getIntent().getStringExtra("title"); (title); // Simulate loading protocol content (title + "The details of this are shown here..."); } }
<!-- ==================== activity_main.xml ==================== --> <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:andro android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <TextView android: android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:autoLink="none" android:lineSpacingExtra="4dp" android:textColor="#333333" /> </ScrollView> <!-- ==================== activity_protocol.xml ==================== --> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:orientation="vertical" android:padding="16dp" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android: android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" android:textStyle="bold" android:paddingBottom="8dp" /> <TextView android: android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="14sp" android:lineSpacingExtra="6dp" /> </LinearLayout>
5. Method interpretation
onCreate (MainActivity)
Initialize the interface, construct the original text and click the target list, and callcreateClickableSpan
Generate clickableSpannableString
And bind toTextView
, and enableLinkMovementMethod
In response to click.ClickTarget construction method
Encapsulate the three elements "text content", "display color", and "click callback" into one object for easy batch management.createClickableSpan
Traverse allClickTarget
,passFind the position of the substring to be clicked; set the text color for each interval first (
ForegroundColorSpan
), cover againClickableSpan
, realize click event and style definition.
Control the text style before and after clicking: set the color and whether to underline it; you can also modify the text thickness, background, etc. here.
When the user clicks on the text, it is called, triggering the corresponding, complete jump or other logic.
LinkMovementMethod
WillTextView
Set to handle link clicks, otherwiseClickableSpan
Will not respond.
6. Project Summary and Expansion
6.1 Review of the effect
Multiple texts in a single TextView can be clicked, no need to split multiple controls, simple layout;
The styles can be customized: colors, underlines, bolds, background colors, etc. Spans can be superimposed;
Logic is completely controlled on the code side, without hard-coded hyperlinks in XML;
The performance overhead is minimal and is suitable for long text scenarios.
6.2 Common pitfalls and precautions
IndexOf Not Found: When the text does not contain the target substring,
indexOf
Return -1, processing should be skipped;Chinese Emoji, multi-byte: If there are complex segmentation requirements, it is recommended to use the rules
Pattern
orMatcher
;Click conflict between lines: If TextView supports scrolling or has parent-layer intercepting events, it needs to be called
And make sure that the parent layout does not intercept touches;
Repeat substrings: If the same substring appears multiple times, you can loop to find all matching positions, or pass multiple groups into
ClickTarget
Specify the starting positions respectively.
6.3 Extensible direction
Rich text display: Combined
ImageSpan
Emoji and icons can be inserted into the text;Custom touch feedback: Rewrite
ClickableSpan
,existonTouchEvent
Change the text background to achieve the pressing effect;Regularly match global links: Automatically identify all URLs/mobile phone numbers/email addresses and generate clickable Span;
Jetpack Compose implementation:use
AnnotatedString
andClickableText
Implement the same function, which is more suitable for the Compose framework;Dynamic content: Combined with the rich text template returned by the background, the links and text styles are data- and configurable.
The above is the detailed content of some text in Android that implements click-to-jump function. For more information about click-to-jump text in Android TextView, please follow my other related articles!
Related Articles
Process steps for implementing dynamic Gaussian fuzzy based on Flutter
An App plus Gaussian Blur will form a high-level feeling. This article will introduce how to create a dynamic Gaussian Blur based on the background content. There are detailed code implementation steps in the article. The code examples are explained in detail and have a certain reference value. Friends who need it can refer to it.2023-11-11Analysis of Flutter LinearProgressIndicator User Guide
This article mainly introduces the Flutter LinearProgressIndicator usage guide analysis. Friends in need can refer to it for reference. I hope it can be helpful. I wish you more progress and get a promotion as soon as possible.2023-03-03How to use Android system simulation location
This article mainly introduces in detail how to use Android system simulation locations. It is of reference value. Interested friends can refer to it.2016-05-05Android Handler leak analysis and solutions detailed explanation
This article mainly introduces the relevant information about Android Handler leak analysis and detailed explanation of solutions. Friends who need it can refer to it.2017-03-03Solution to the multi-layer nested ghosting problem of Android Fragment
This article mainly introduces the solution to the multi-layer nested ghosting problem of Android Fragment. Find out the cause of the problem from the aspects of solving bugs, causing the cause, principle analysis, etc. The final solution is simple. Friends who are interested in multi-layer nested problems of fragment will learn through this article.2016-08-08Question about importing the source code of Androidstuio
The editor has recently been working on a small project exported from the system source code. I encountered some problems in the process of importing Android Studio. This article takes Schedule power on off as an example to give you a detailed introduction. For those who need it, please refer to it.2021-06-06Android implementation example code to change avatar pictures in APP
This article mainly introduces the example code for changing avatar pictures in the Android implementation APP. This article introduces you very detailed through the example code, which has certain reference value. Friends who need it can refer to it.2019-07-07Android implements sliding tab pages
This article mainly introduces the Android sliding tab page in detail. The sample code in the article is introduced in detail and has a certain reference value. Interested friends can refer to it.2021-04-04Android custom countdown control example
This article mainly introduces the Android flash sale countdown custom TextView example, please refer to it2014-01-01Android ViewDragHelper implements the drag and drop details function of JD and Taobao
This article mainly introduces the details of Android ViewDragHelper to implement drag and drop in JD and Taobao. There are roughly three ways to achieve this effect. You can learn about which three methods are used in this article.2018-04-04