如何实现类似WhatsApp的效果:将EditText输入的**包裹文本在TextView中加粗
Got it, implementing WhatsApp-style bold formatting where text wrapped in ** gets converted to bold in a TextView is straightforward with Android's SpannableString and regex parsing. Let me break this down for you:
Step 1: Create a Helper Method to Parse Bold Syntax
First, we'll write a utility function that takes the input string from your EditText, identifies all segments wrapped in **, applies the bold style to those parts, and removes the ** markers from the final output.
import android.text.SpannableString; import android.text.Spanned; import android.text.style.StyleSpan; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TextFormattingUtils { public static SpannableString convertMarkdownBoldToSpannable(String inputText) { SpannableString mutableSpannable = new SpannableString(inputText); Pattern boldPattern = Pattern.compile("\\*\\*(.*?)\\*\\*"); Matcher matcher = boldPattern.matcher(inputText); int offset = 0; while (matcher.find()) { int originalStart = matcher.start(); int originalEnd = matcher.end(); // Apply bold style to the content inside the ** markers mutableSpannable.setSpan( new StyleSpan(android.graphics.Typeface.BOLD), originalStart + 2 - offset, originalEnd - 2 - offset, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); // Remove the ** markers from the text mutableSpannable.delete(originalEnd - 2 - offset, originalEnd - offset); mutableSpannable.delete(originalStart - offset, originalStart + 2 - offset); // Update offset to account for removed characters (4 total per match) offset += 4; // Reset matcher with the modified string to find next matches matcher = boldPattern.matcher(mutableSpannable.toString()); } return mutableSpannable; } }
Step 2: Connect EditText and TextView for Real-Time Updates
To make the TextView update instantly as the user types, add a TextWatcher to your EditText:
import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private EditText inputEditText; private TextView outputTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inputEditText = findViewById(R.id.input_edit_text); outputTextView = findViewById(R.id.output_text_view); inputEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { SpannableString formattedText = TextFormattingUtils.convertMarkdownBoldToSpannable(s.toString()); outputTextView.setText(formattedText); } }); } }
Step 3: Layout File (activity_main.xml)
Here's a simple layout with an input EditText and a formatted output TextView:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/input_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Type text with **bold** here..." /> <TextView android:id="@+id/output_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textSize="18sp" /> </LinearLayout>
Handling Edge Cases
- Unclosed
**: The regex uses non-greedy matching, so any unclosed**will stay as plain text instead of breaking the formatting. - Empty
**: Segments like****or** **won't be processed (since we look for content between the markers) and will remain visible as plain text. - Multiple Bold Segments: The method handles multiple bold parts in a single string (e.g., "Hello world! This is another test") seamlessly.
That's all! This setup replicates WhatsApp's bold text behavior perfectly—users type text wrapped in **, and the TextView displays that content in bold without the ** markers.
内容的提问来源于stack exchange,提问作者Mirza Asad

