I want to insert a constant string into an EditText by the press of a button. The string should be inserted at the current position in the EditText.
If I use EditText.append the text gets inserted at the end of the EditText.
How can I do that? I couldn't find a suitable method.
Cpt.Ohlund gave me the right hint. I solved it, now, partly with using EditText.getSelectionStart(), but I realized that you can also replace the selected text with the same expression and you don't need String.subString() for that.
int start = Math.max(myEditText.getSelectionStart(), 0);
int end = Math.max(myEditText.getSelectionEnd(), 0);
myEditText.getText().replace(Math.min(start, end), Math.max(start, end),
textToInsert, 0, textToInsert.length());
This works for both, inserting a text at the current position and replacing whatever text is selected by the user. The Math.max() is necessary in the first and second line because, if there is no selection or cursor in the EditText, getSelectionStart() and getSelectionEnd() will both return -1. The Math.min() and Math.max() in the third line is necessary because the user could have selected the text backwards and thus start would have a higher value than end which is not allowed for Editable.replace().
This seems simpler:
yourEditText.getText().insert(yourEditText.getSelectionStart(), "fizzbuzz");
However, Manuel's answer might be better if you want to replace any selected text with the inserted text.
Try using EditText.getSelectionStart() to get the current position of the cursor. Then you can use String.subString to get the text before and after the cursor and insert your text in the middle.
I think this function will help for you :
public void insertConstantStr(String insertStr) {
String oriContent = editText.getText().toString();
int index = editText.getSelectionStart() >= 0 ? editText.getSelectionStart() : 0;
StringBuilder sBuilder = new StringBuilder(oriContent);
sBuilder.insert(index, insertStr);
editText.setText(sBuilder.toString());
editText.setSelection(index + insertStr.length());
}
For Kotlin simply do that:
editText.text.insert(editText.selectionStart, "Your Text Here")
Editable editable = new SpannableStringBuilder("Pass a string here");
yourEditText.text = editable;
Related
I am selecting a part of the TextView and on click of a "highlight" button, I am sending the start and the end index of selection to the database. Then I am loading all the start and end indexes from db and changing the color of text between them.
The problem is after once or twice, the app is changing the color of text that is not in selection.. and the selected part remains unchanged.
MY CODE:
When user selects and presses the highlight button
int i=contentText.getSelectionStart();
int j=contentText.getSelectionEnd();
db.insertHiglightIndex(String.valueOf(i),String.valueOf(j));
setHighlightedText();
The setHighlightedText() method..
String fullText=contentText.getText().toString();
for(int i=0; i<db.getAllStartIndex().size();i++){
String a=fullText.substring(Integer.parseInt(db.getAllStartIndex().get(i)),Integer.parseInt(db.getAllEndIndex().get(i)));
fullText = fullText.replace(a, "<font color='red'>"+a+"</font>");
}
contentText.setText(Html.fromHtml(fullText), TextView.BufferType.SPANNABLE);
MY SCREENSHOTS.
The selection:
The Result:
Clearly the selected area is from "Garrick" to "Bart", and the result is from "entity" to "2012"
I am not able to understand why is this happening. I think there is some problem with this <font color='red'>"+a+"</font> line.
Thank you
It got wrong indexed because There is already added <font color='red'> in the beginning, So that in second time This tag is also counted as a part of string, So I suggest creating a new temporary String, assign same text to the String but after replacing the previous font tag it held. Use this syntax to remove previous font tag from originalString
String tempString = originalString.replaceAll("[<](/)?font[^>]*[>]", "");
After that work with only tempString. That means again add every previous font tag you have to tempString and set that text.
In next time again do the same first remove all font tag and again add all of them back in tempString as well as current selection using same loop you are using currently.
You have wrong indexes because you are modifying the fullText content within the loop.
Taking a look at this example you can figure it:
final TextView tv = (TextView) findViewById(R.id.textView);
tv.setText( "abcdefghijklmnopqrstuvwxyz0123456789");
String fullText= tv.getText().toString();
// your first iteration
String a = fullText.substring(1,3);
// a contains "ab"
fullText = fullText.replace(a, "<font color='red'>"+a+"</font>");
After the first iteration full text contains now
a<font color='red'>bc</font>defghijklmnopqrstuvwxyz0123456789"
Then the substring() in the second iteration won't returns the substring base on your initial content.
If you want to be able to have multiple substrings colored in red you can try this:
String fullText = contentText.getText().toString();
StringBuilder result = new StringBuilder();
for(int i=0; i < db.getAllStartIndex().size(); i++){
fullText = applyFont(result, fullText, Integer.parseInt(db.getAllStartIndex().get(i)), Integer.parseInt(db.getAllEndIndex().get(i)));
}
// Add here the remaining content
result.append(fullText);
contentText.setText(Html.fromHtml(result.toString()), TextView.BufferType.SPANNABLE);
private String applyFont(StringBuilder result, String source, int from, int to){
result.append(source.substring(0, from));
result.append("<font color='red'>");
result.append(source.substring(from, to));
result.append("</font>");
return source.substring(to, source.length());
}
I have a multi lines Edittext with a text (don't content "\n"), a font size (sp)
and the length of text > Edittext.width().
I want to get length of the first line in EditText.
How can I do it?
You can see the photo
One option could be to read the text and then get the index of the newline character, which is essentially the length of the string prior to it:
int firstLineLength = myEditText.getText().toString().indexOf("\n");
As an alternative, if you ever need to do this with other lines you can simply split the whole string based on the newline character:
String[] lines = myEditText.getText().toString().split("\n");
EDIT
Keep in mind that indexOf() will return -1 if an occurrence is not found. So if your EditText has one and only one string, you'll get a -1 line length so be prepared to check against that:
int lineEndIndex = myEditText.getText().toString().indexOf("\n");
int firstLineLength;
if(lineEndIndex == -1) {
firstLineLength = myEditText.getText().toString().length();
} else {
firstLineLength = lineEndIndex;
}
if (Global.DigsSinceLogin > 3) {
int a = Global.DigsSinceLogin;
noCoachingPoints.setText("Excellent Job! \n No Coaching Points Triggered in the Last "+ a +" Digs");}
Requirement:
Need to display value of "a" as 1)bold and 2)yellow color.
Is there a way i can display this value with the above changes and display in the same position
Try Below Code
if (Global.DigsSinceLogin > 3) {
int a = Global.DigsSinceLogin;
noCoachingPoints.setText(Html.fromHtml("Excellent Job!"+"<br>"+" No Coaching Points Triggered in the Last "+ "<font color=yellow><B>" + a + "</B></font>"+" Digs"));}
You can use a SpannableString or SpannableStringBuilder and apply both a StyleSpan and a ForegroundColorSpan to the text that needs special treatment. This much is pretty straightforward; I think the more difficult part will be finding the proper index of the character(s) in the string, especially when you start using localized string resources (which you should).
I'm trying to solve my problem for 2 days now but without any success.
The problem is: when I set BulletSpan to text and then display it in EditText everything works fine until I start typing in another text. When the text is wrapped at the end of the screen, the indentation works but the cursor is pointing off the actual position and also some characters from previous line are added after the cursor. To better illustrate this problem see the attached image.
Also is worth mentioning that this happen only when I type in text, when I'm setting the text in the source and the text is too long to be only on one line the wrapping works fine and no extra characters are added nor the cursor position is wrong.
Also I tried LeadingMarginSpan.Standart and the behaviour was the same.
In code I'm setting the start mark:
private void handleListStart(SpannableStringBuilder text) {
int len = text.length();
text.setSpan(new ListItem(), len, len, Spannable.SPAN_MARK_MARK);
}
Then setting the span:
private void handleListEnd(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, ListItem.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
text.setSpan(new BulletSpan(listIndent * 15), where, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
I'm getting the data from xml file.
Thanks for any help
EDIT:
I forget to add that I have tried this on Android 4.1 and 4.4 and both behaved the same
This issue happens when your bulletspan-style characters come to a new line.
You can listen when the lines increase, then you can clear the bulletspan and set a new bulletspan again.
The solutiion above works perfectly for me.
#QuinnChen 's answer worked for me. Let me elaborate it with code for convenience .
This issue happens when the text is automatically wrapped to the next line in BulletSpan and LeadingMargin span .
Solution is to remove the previous span and apply the same span again when the line increases .
first set int line_counter = editorEditText.getLineCount(); when you click the button to apply the span
then in the body of textwatcher write this:
if(line_count > editorEditText.getLineCount()){
LeadingMarginSpan[] leadingMarginSpans = editorEditText.getText().getSpans(0, editorEditText.getSelectionStart(),
LeadingMarginSpan.class);
int s , e;
for(LeadingMarginSpan ss: leadingMarginSpans){
s = editorEditText.getText().getSpanStart(ss);
e = editorEditText.getText().getSpanEnd(ss);
if(s<=editorEditText.getSelectionStart() && editorEditText.getSelectionStart()<=e){
editorEditText.getText().removeSpan(ss);
editorEditText.getText().setSpan(new LeadingMarginSpan.Standard(30), s,e,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line_count = editorEditText.getLineCount();
}
}
}
This code would execute when the text is automatically wrapped to the next line .
NOTE:
This is the code for LeadingMargin, the solution for bulletSpan goes the same, you just have to change replace LeadingMarginSpan with BulletSpan
I have deleted characters in edittext objects with this code
edit = etcalle.getEditableText();
if (edit.length() > 0)
edit.delete(edit.length() - 1, edit.length());
It has been working but when my string looks like this +81 901 it doesn't delete the space. It gets to it and stops deleting characters.
How can I remove the space in my text?
EDIT:
Just to be clear, I don't want to remove everything at once. Just one character at every time I hit my delete button
String original = etcalle.getText().toString();
then
etcalle.setText(original.substring(0,original.length-1));
of course be sure to check that the original is not null or length < 1
use this it will remove all the spaces
String str = "99 85263 9633";
str.replace(" ", ""); // Output is 99852639633
Then Its magic you can do this with this
String str = "99 85263 9633";
str.replaceFirst(" ",""); // Output is 9985263 9633