I have a TextView and I can search some words, so that they're marked.
The TextView is named textView and it shows the text, I have an EditText Etxt to get the searched word and a Button to start the search. The code above is the code of the search. The app marks all found words big and italic. And I have a TextView text_total which shows the number of found words.
The problem: But if there is a searched word in the text below the shown screen, you must scroll and find the marked word:
int total = 0;
String word_search = Etxt.getText().toString().trim().toLowerCase();
String fullTxt = textView.getText().toString();
String[] array = fullTxt.split("\n");
String word;
StringBuilder st = new StringBuilder();
for (int i = 0; i < array.length; i++) {
word = array[i];
if (word.toLowerCase().contains(word_search)) {
String abc = word.trim();
st.append("<b><i>" + abc + "</i></b>");
total++;
} else {
st.append(word);
}
st.append("<br>");
}
textView.setText(Html.fromHtml("" + st));
text_total.setText("Ergebnisse: " + total);
Now, I have a problem because the text is too long to see all search results. I want that I have a 'back' and a 'next' button and the view goes to the next result if I click the next button and that the the found word goes automatically to the shown screen.
Does anyone know how to code this?
That's very important. Thanks for help!
Try this.
Put all the finded words in a list
List words= new ArrayList();
Add the words to the list
words.add(word_search);
Finally in next and previous buttons, you need to check the positions of the words in the list
words.get(position)
See how in this link
Related
How to get a text from a multi line EditText line by line as it displayed on the screen?
For example, if you insert long text in EditText (without \n) it will be displayed in few lines. How to know where system insert line wrap?
It is possible if using EditText.getLayout():
String text = editText.getText().toString();
List<String> lines = new ArrayList<>();
for (int i = 0; i< editText.getLayout().getLinesCount(); i++) {
lines.add(text.substring(editText.getLayout().getLineStart(i),
editText.getLayout().getLineEnd(i));
}
Also EditText.getLayout() has methods for returning size of line:
getLineWidth()
getLineBounds()
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 using breakIterator to get each word from a sentence and there is problem when a sentence like "my mother-in-law is coming for a visit" where i am not able to get mother-in-law as a single word.
BreakIterator iterator = BreakIterator.getWordInstance(Locale.ENGLISH);
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next())
{
String possibleWord = sentence.substring(start, end);
if (Character.isLetterOrDigit(possibleWord.charAt(0)))
{
// grab the word
}
}
As I'm seeing in your code what are you trying to do is to check if the first character in every word are a character or a digit. Every time you use the BreakIterator.getWordInstance() you will always get all the words depending on the boundary rules of the Locale and it is a little hard to accomplish what you want to do with the use of this class until I know, so my advice is this:
String text = "my mother-in-law is coming for a visit";
String[] words = text.split(" ");
for (String word : words){
if (Character.isLetterOrDigit(word.charAt(0))){
// grab the word
}
}
I have a List of Strings and i want to compare every i write in an EditText with that list. If there is a match then i have to add a "-" character as a prefix for that word.
I am using a TextWatcher and this is my code so far:
#Override
public void afterTextChanged(Editable s) {
String tmp = s.toString();
words = tmp.split(" ");
for (int i = 0; i < words.length; i++) {
for (Iterator iterator = myList.iterator(); iterator
.hasNext();) {
String str = (String) iterator.next();
if (str.equalsIgnoreCase(words[i])) {
if (!words[i].contains("-")) {
tmp = tmp.replace(words[i], "-" + words[i]);
}
editMain.setText(tmp);
editMain.setSelection(tmp.length());
}
}
}
}
It works but if i type the same word twice in my EditText, the first ocurrence gets two "--".
For example:
hello this is -android (works ok)
hello this is --android -android (does not work ok)
And the desired result should be:
hello this is -android android (because the repeated word already exists)
Any help? thanks in advance
Your question is not very clear. Maybe you mean android word has already been found and then it should not be prefixed by a -.
If that's the case, just remove a mathcing word from mylist. For that use a listIterator.
try to set a counter. If the counter is bigger than 1, then don't write the -
I'm using AutoCompleteTextView that the user can see the opportunities.
So when I tap on two characters e.g. "ba" I will see "Bahamas", "Bahrain","Azerbaijan" etc - this works!
But if I don't have a country starting with the letter "z" I will hide the z on the keyboard. And if I tap the two characters "ba", I will only see "h" on my keyboard.
How can I do that? And how can I realize it if I still want to tap "ba" and will get "bahamas" AND "azerbaijan"?
Thanks everyone!
as Cata pointed out, you won't be able to hide the keys on the softkeyboard unless you write your own keyboard - you do have a couple of other options however:
you could put a text watcher on the the edit text, and if they key they type isn't in any of the words, you could delete it
you could use setKeyListener http://developer.android.com/reference/android/widget/TextView.html#setKeyListener%28android.text.method.KeyListener%29 to and validate their entries.
Both of these will not hide keys from the keyboard but you could use them to prevent the user from typing an invalid key.
As for your second question about matching the user input to the middle of a string, this is not in the code of the autocomplete:
Relevant code form the android source:
for (int i = 0; i < count; i++) {
final T value = values.get(i);
final String valueText = value.toString().toLowerCase();
// First match against the whole, non-splitted value
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
break;
}
}
}
}
you can see it will only match the first characters of any individual word in an item. So to achieve your second goal, you would have to write your own adapter that implements filterable.
here is a tutorial that might get you started on that: http://thinkandroid.wordpress.com/2010/02/08/writing-your-own-autocompletetextview/