guys.
I need a little bit inspiration right here. I want to create an application that have a highlight feature, just like screenshot below. But, I don't have an idea how to do this. I think Spannable TextView only can't just help me. Do you have some idea?
Thank you.
Example of highlight menu in Medium App
You can use SpannableString
To highlight specific text use this method.
private void highlightString(String input) {
//Get the text from text view and create a spannable string
SpannableString spannableString = new SpannableString(mTextView.getText());
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = spannableString.toString().indexOf(input);
while (indexOfKeyword > 0) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), indexOfKeyword, indexOfKeyword + input.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = spannableString.toString().indexOf(input, indexOfKeyword + input.length());
}
//Set the final text on TextView
mTextView.setText(spannableString);}
Related
I'm trying to create a fill the gap game in Android Studio with Java, for that I'm taking a sentence, separating the keyword (to fill by the user) from the String, and adding the Strings as follow in a horizontal LinearLayout (within a vertical Layout):
TextView before keyword + TextView keyword + TextView after keyword
In a different LinearLayout below I have a following TextView (TextView Line3) making a second line with the same width as the horizontal LinearLayout above. -- Something like a line 2
As TextView after keyword is too long and makes a second line starting after the "TextView keyword", I want to take what goes to the second line of "TextView after keyword" and move it to "TextView Line3".
The problem is that it keeps saying there is only 1 line and "TextView after keyword" displays two
I defined them as such:
private TextView firstSentence, secondSentence, thirdSentence;
public TextView answerText;
private String sentence = "I do not like anyone in this world of idiots";
private boolean newLineBoolean = true;
private String keyword = "like";
private String[] sentenceDivision;
private String displayForKeyword = "";
private String thirdLine = "";
this in onCreate
answerText = findViewById(R.id.answerPlace);
firstSentence = findViewById(R.id.firstSentence);
secondSentence = findViewById(R.id.secondSentence);
thirdSentence = findViewById(R.id.thirdSentence);
sentenceDivision = sentence.split(keyword);
firstSentence.setText(sentenceDivision[0]);
secondSentence.setText(sentenceDivision[1]);
for(int i = 0; i<keyword.length();i++)
{
displayForKeyword = displayForKeyword + " ";
}
answerText.setText(displayForKeyword);
checkNumberOfLines();
And this method
private void checkNumberOfLines(){
String firstWords = sentenceDivision[1].substring(0, sentenceDivision[1].lastIndexOf(" "));
String lastWord = sentenceDivision[1].substring(sentenceDivision[1].lastIndexOf(" ") + 1);
sentenceDivision[1] = firstWords;
thirdLine = lastWord + " " + thirdLine;
secondSentence.setText(sentenceDivision[1]);
thirdSentence.setText(thirdLine);
secondSentence.post(new Runnable() {
#Override
public void run() {
int lineCount = secondSentence.getLineCount();
if (lineCount > 0) {
checkNumberOfLines();
}
else{ newLineBoolean = false;
}
}
});
}
But it displays as follows:
enter image description here
Does someone know why? Thanks in advance!
It might be because of the definition of TextView.getLineCount()
public int getLineCount() {
return mLayout != null ? mLayout.getLineCount() : 0;
}
if mLayout is a BoringLayout then getLineCount() always returns 1.
To use a different kind of text layout (DynamicLayout) that actually computes its line count, you could try either to make the text selectable by calling setTextIsSelectable or set a Spannable instead of a CharSequence in the TextView (see makeSingleLayout).
I agree with your sentence and this is not the best solution for your use case for which you might get less trouble by using something like a FlowLayout instead of the LinearLayouts and placing each word inside a separate TextView.
Edit to answer questions in comment
After adding the FlowLayout to the activity's layout xml you can create the TextViews for the words in the sentence dynamically:
// in onCreate()
FlowLayout flowLayout = findViewById(R.id.flow_id);
String[] words = sentence.split(" ");
TextView wordText;
for (int i = 0; i < words.length; i++) {
String word = words[i];
//if an edit text is needed for user input
if (i == keywordIndex) {
wordText = new EditText(this);
wordText.setHint("____");
} else {
wordText = new TextView(this);
wordText.setText(word);
}
wordText.setTextColor(getResources()
.getColor(R.color.your_color));
wordText.setBackgroundColor(getResources()
.getColor(android.R.color.white));
flowLayout.add(wordText);
}
Yes, you could use a RecyclerView with a GridLayoutManager or StaggeredGridLayoutManager to layout the views for the sentence words but it would require creating a RecyclerView.Adapter. But I think the RecyclerView would be more suitable for displaying a vertical set of
sentences (as FlowLayouts for example).
I'm looking for a library or optimized examples on using
Mark Down to create Rich Text.
For example, something to turn:
1 - *Bold* -> Bold
2 - _Italic_ -> Italic
Long example:
3 - _Hello_ *World* -> Hello World
And so on.
I've seen many apps use it, like Discord, Whatsapp, Skype.
I've done something similar, but I know it's not optimized and can lead to runtime errors.
You don't need any extra library...
Just have a look into android.text.SpannableStringBuilder...
This will allow you to get text features like:
Make it larger
Bold
Underline
Italicize
Strike-through
Colored
Highlighted
Show as superscript
Show as subscript
Show as a link
Make it clickable.
Here you have an example on how to apply a Bold style on a word in a TextView :
String text = "This is an example with a Bold word...";
// Initialize a new SpannableStringBuilder instance
SpannableStringBuilder strb = new SpannableStringBuilder(text);
// Initialize a new StyleSpan to display bold text
StyleSpan bSpan = new StyleSpan(Typeface.BOLD);
// The index where to start applying the Bold Span
int idx = text.indexOf("Bold");
strb.setSpan(
bSpan, // Span to add
idx, // Start of the span
idx + 4, // End of the span
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
// Display the spannable text to yourTextView
yourTextView.setText(ssBuilder);
SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text");
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start_int, end_int, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv=new TextView(context);
tv.setText(str);
I think you have to look for library that support mark down
https://github.com/tiagohm/MarkdownView
https://github.com/noties/Markwon
https://github.com/IonicaBizau/medium-editor-markdown
I am trying to build a feature where users can select a text in an Edit text and make the text italic or bold by clicking buttons in a small toolbar. I wrote some code in android studio but there is an issue.
public void bold(EditText text){
int start = text.getSelectionStart();
int end = text.getSelectionEnd();
CharacterStyle style = new StyleSpan(Typeface.BOLD);
SpannableStringBuilder sb = new SpannableStringBuilder(text.getText().toString());
sb.setSpan(style, start, end, 0);
text.setText(sb);
}
When user click bold button, it calls the bold() function and bolds the selected text.but if i change the selection and click italics, it italics the selected text but deletes the bold style i already applied to the edit text.
For example
exampleone exampletwo (bolds the text)
But if click select exampletwo and click italic
it becomes
exampleone exampletwo
I lost the style of the first word in the Edittext.
How can i fix this issue ?
SpannableStringBuilder ssb = newSpannableStringBuilder(bodyView.getText());
cs = new StyleSpan(Typeface.BOLD);
ssb.setSpan(cs, start, end, 1);
cs = new StyleSpan(Typeface.ITALIC);
ssb.setSpan(cs, start, end, 1);
I think you should use same Spannablestringbuilder for bold and italic.
It works for me.
Can you guys tell me how to write a java code inside a textview and i want it colored just like i'm writing a java code.
I found an example that is composed of 2 types of text and I think that both of them are TextView but the seconde one contain Highlight text and that green bar at left , can you guys tell how to do it .
( sorry i can't upload a picture )
Try this,
public static void setText(TextView textView, String text) {
Spannable spannable = new SpannableString(text);
// For Foreground Highlight
spannable.setSpan(new ForegroundColorSpan(fromColor(ColorCode)), highlight.start, highlight.end, 0);
// For Background Highlight
spannable.setSpan(new BackgroundColorSpan(fromColor(ColorCode)), highlight.start, highlight.end, 0);
textView.setText(spannable);
}
Try this,
TextView TV = (TextView)findViewById(R.id.mytextview01);
Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");
wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(wordtoSpan);
Original answer here
I want to change the text of selected text in JTextArea.
For example when i press button i want the selected text to be change (Original Text Selected - I want to replace like this when i press the button : Replace:Original Text Selected) this is what i am trying to do in my code,
String replacement = "Replace:" + messageBodyText.getSelectedText() ";
but i have no idea how to change only selected text i am trying to do something but i am changing entire text of JTextArea Hope you understood my question ?
Thanks to Hovercraft Full Of Eels he solved my problem this is my code for other people who are facing the same problem :
int start = messageBodyText.getSelectionStart();
int end = messageBodyText.getSelectionEnd();
StringBuilder strBuilder = new StringBuilder(messageBodyText.getText());
strBuilder.replace(start, end, "Replace:" + messageBodyText.getSelectedText() + ".");
messageBodyText.setText(strBuilder.toString());
textComponent.replaceSelection(newText);
JTextComponent (and thus JTextArea) has getSelectionStart() and getSelectionEnd() methods that will help you. Get your text from the JTextArea or its Document, and using these int values you can change your text and replace it into the text component.
For example,
int start = myTextField.getSelectionStart();
int end = myTextField.getSelectionEnd();
StringBuilder strBuilder = new StringBuilder(myTextField.getText());
strBuilder.replace(start, end, newText);
myTextField.setText(strBuilder.toString());