Question

I am new to android programing. I added a context menu to edittext. I wish to get the word under the cursor on long press.

I can get selected text by following code.

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    EditText edittext = (EditText)findViewById(R.id.editText1);
    menu.setHeaderTitle(edittext.getText().toString().substring(edittext.getSelectionStart(), edittext.getSelectionEnd()));
    menu.add("Copy");
}

edittext has some text e.g "Some text. Some more text". When the user clicks on "more", the cursor will be in some where in the word "more". When the user long presses the word I want to get the word "more" and other words under the cursor.

Was it helpful?

Solution 2

EditText et = (EditText) findViewById(R.id.xx);

int startSelection = et.getSelectionStart();

String selectedWord = "";
int length = 0;

for(String currentWord : et.getText().toString().split(" ")) {
    System.out.println(currentWord);
    length = length + currentWord.length() + 1;
    if(length > startSelection) {
        selectedWord = currentWord;
        break;
    }
}

System.out.println("Selected word is: " + selectedWord);

OTHER TIPS

There is better and simpler solution : using pattern in android

public String getCurrentWord(EditText editText) {
    Spannable textSpan = editText.getText();
    final int selection = editText.getSelectionStart();
    final Pattern pattern = Pattern.compile("\\w+");
    final Matcher matcher = pattern.matcher(textSpan);
    int start = 0;
    int end = 0;

    String currentWord = "";
    while (matcher.find()) {
        start = matcher.start();
        end = matcher.end();
        if (start <= selection && selection <= end) {
            currentWord = textSpan.subSequence(start, end).toString();
            break;
        }
    }

    return currentWord; // This is current word
}

Please try following code as it is optimized. Let me know if you has more specification.

//String str = editTextView.getText().toString(); //suppose edittext has "Hello World!" 
int selectionStart = editTextView.getSelectionStart(); // Suppose cursor is at 2 position
int lastSpaceIndex = str.lastIndexOf(" ", selectionStart - 1);
int indexOf = str.indexOf(" ", lastSpaceIndex + 1);
String searchToken = str.substring(lastSpaceIndex + 1, indexOf == -1 ? str.length() : indexOf);

Toast.makeText(this, "Current word is :" + searchToken, Toast.LENGTH_SHORT).show();

I believe that a BreakIterator is the superior solution here. It avoids having to loop over the entire string and do the pattern matching yourself. It also finds word boundaries besides just a simple space character (commas, periods, etc.).

// assuming that only the cursor is showing, no selected range
int cursorPosition = editText.getSelectionStart();

// initialize the BreakIterator
BreakIterator iterator = BreakIterator.getWordInstance();
iterator.setText(editText.getText().toString());

// find the word boundaries before and after the cursor position
int wordStart;
if (iterator.isBoundary(cursorPosition)) {
    wordStart = cursorPosition;
} else {
    wordStart = iterator.preceding(cursorPosition);
}
int wordEnd = iterator.following(cursorPosition);

// get the word
CharSequence word = editText.getText().subSequence(wordStart, wordEnd);

If you want to get it on a long press then just put this in the onLongPress method of your GestureDetector.

See also

@Ali Thank you for providing your solution.

Here is an optimized variant, which does break if the word has been found.

This solution does not create a Spannable, because it is not needed to find the word.

@NonNull
public static String getWordAtIndex(@NonNull String text, @IntRange(from = 0) int index) {
    String wordAtIndex = "";

    // w = word character: [a-zA-Z_0-9]
    final Pattern pattern = Pattern.compile("\\w+");
    final Matcher matcher = pattern.matcher(text);

    int startIndex;
    int endIndex;

    while (matcher.find()) {
        startIndex = matcher.start();
        endIndex = matcher.end();

        if ((startIndex <= index) && (index <= endIndex)) {
            wordAtIndex = text.subSequence(startIndex, endIndex).toString();
            break;
        }
    }
    return wordAtIndex;
}

Example: Get the word at the current cursor position:

String text = editText.getText().toString();
int cursorPosition = editText.getSelectionStart();

String wordAtCursorPosition = getWordAtIndex(text, cursorPosition);

Use this instead if you want to find all connected characters (including punctuation):

// S = non-whitespace character: [^\s]
final Pattern pattern = Pattern.compile("\\S+");

Java regex documentation (regular-expression): https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top