title: How to find which word is clicked on a textview Android
body: <p>I have a list of tokens and the user needs to create a list of a subset of these quickly.  I now have keyboard entry and a display of the list but the keyboard covers up the list.  My user wants to click on the tokens rather than type them in.  There might be 500 tokens so a listview seems unworkable.  They can be different lengths from one character to 20 so a gridview doesn't seem like a good idea.  All I can think of is to keep the list in a textview and have the user click on one and pop up a alert asking if he wants to enter that token.  The list is scrollable.</p>
  
  <p>Basically, I want the user to click on a word in a textview and have the java know what word that was.  All words are separated by commas.</p>
  
  <p>For example, here is one set that might be displayed</p>
  
  <p>7W, 4F, 2R, 5K, 73, 3J, 6F, 2F, 7M, 21, 5D, 1H, 5C, 24, 7Y, 4D, 70, 1E, 3P, 2C, 4B, 3E, 5A, 4G, 5E, 6H, 6N, 7J, 7S, 2B, 41, 4H, 3H, 2A, 3B, 3F, 40, 4N, 2J, 3C, 22, 5M, 44, 7Z, 3U, 3L, 3Q, 7A, 72, 4V, 7X, 26, 1D, 4M, 6D, 5R, 6B, 6K, 7U, 7V, 7T, 7P, 7L, 4R, 7G, 7E, 7B, 3X, 7F, 5J, 5L, 3T, 7R, 3K, 2T, 43, 71, 5N, 1C, 7H, 5B, 3M, 6J, 6M, 6R, 5H, 1F, 1L, 7Q, 6P, 7C, 6A, 4T, 3R, 46, 1N, 1K, 4Y, 5F, 7K, 6S, 5Q, 2H, 42, 4X, 1A, 1B, 33, 3N, 2K, 3G, 4A, 5G, 30, 4E, 7N, 4S, 3S, 5S, 3D, 20, 4K, 1J, 32, 2X, 31, 4Q, 45, 4Z, 1G, 74, 6G, 4C, 4U, 3Z, 4W, 5P, 25, 1M, 6C, 3V, 3Y, 3A, 6E, 4P, 7D, 4J, 4L, 3W, 6L, 6Q, Thorn Knoll, North Thorn, Hook, Black Jack, Castle Point, Calshot Spit, Bourne Gap, </p>
  
  <p>The user needs to be able to select the desired 10 items in under 30 seconds (he gets the list just a few minutes before the start of a race).</p>
  
  <p>The text entry that he needs to enter might look like this:</p>
  
  <p>Route Name, 30,24,4R, 3E, 6Q, 3N, Thorn Knoll, 5G</p>
  
  <p>What is the best way to do this?</p>
  
  <p>Here is what I have now
  <img src="https://i.stack.imgur.com/bIYug.png" alt="enter image description here"></p>
  
  <p>What he wants is to just click on the tokens.
  <img src="https://i.stack.imgur.com/Lqju4.png" alt="enter image description here"></p>
  
  <p>Here is some text code to prove the concept.  Thanks to  Vaghela M.R - Mobile Devloper for the link.</p>
  
  <pre><code>public class MainActivity extends Activity {
  String waypoint = "";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      init();
  }
  private void init() {
      String definition = "1A, 1B, 1C, 1D, 1E, 1F, 1G, 1H, 1J, 1K, 1L, 1M, 1N, 20, 21, 22, 24, 25, 26, 2A, 2B, 2C, 2F, 2H, 2J, 2K, 2R, 2T, 2X, 30, 31, 32, 33, 3A, 3B, 3C, 3D, 3E, 3F, 3G, 3H, 3J, 3K, 3L, 3M, 3N, 3P, 3Q, 3R, 3S, 3T, 3U, 3V, 3W, 3X, 3Y, 3Z, 40, 41, 42, 43, 44, 45, 46, 4A, 4B, 4C, 4D, 4E, 4F, 4G, 4H, 4J, 4K, 4L, 4M, 4N, 4P, 4Q, 4R, 4S, 4T, 4U, 4V, 4W, 4X, 4Y, 4Z, 5A, 5B, 5C, 5D, 5E, 5F, 5G, 5H, 5J, 5K, 5L, 5M, 5N, 5P, 5Q, 5R, 5S, 6A, 6B, 6C, 6D, 6E, 6F, 6G, 6H, 6J, 6K, 6L, 6M, 6N, 6P, 6Q, 6R, 6S, 70, 71, 72, 73, 74, 7A, 7B, 7C, 7D, 7E, 7F, 7G, 7H, 7J, 7K, 7L, 7M, 7N, 7P, 7Q, 7R, 7S, 7T, 7U, 7V, 7W, 7X, 7Y, 7Z, Black_Jack, Bourne_Gap, Calshot_Spit, Castle_Point, Hook, North_Thorn, Thorn_Knoll".trim();
      TextView definitionView = (TextView) findViewById(R.id.text);
      definitionView.setMovementMethod(LinkMovementMethod.getInstance());
      definitionView.setText(definition, BufferType.SPANNABLE);
      Spannable spans = (Spannable) definitionView.getText();
      BreakIterator iterator = BreakIterator.getWordInstance(Locale.US);
      iterator.setText(definition);
      int start = iterator.first();
      for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
              .next()) {
          String possibleWord = definition.substring(start, end);
          if (Character.isLetterOrDigit(possibleWord.charAt(0))) 
          {
              ClickableSpan clickSpan = getClickableSpan(possibleWord);
              spans.setSpan(clickSpan, start, end,
                      Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          }
      }
  }
  private ClickableSpan getClickableSpan(final String word) {
      return new ClickableSpan() {
          final String mWord;
          {
              mWord = word;
          }
          @Override
          public void onClick(View widget) {
              TextView textView1 = (TextView) findViewById(R.id.textView1);
              Log.d("tapped on:", mWord);
              Toast.makeText(widget.getContext(), mWord, Toast.LENGTH_SHORT)
                      .show();
              checkWord(mWord);
          }
          public void updateDrawState(TextPaint ds) {
              super.updateDrawState(ds);
          }
      };
  }
  public void doSomething(){
      TextView textView1 = (TextView) findViewById(R.id.textView1);
      StringBuilder sb = new StringBuilder();
      sb.append(textView1.getText());
      sb.append(", ").append(waypoint);
      textView1.setText(sb);
  }
  public void checkWord(String word) {
      waypoint = word;
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setMessage("Enter "+ word + "?")
             .setCancelable(false)
             .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                      // fire an intent go to your next activity
                     doSomething();
                 }
             })
             .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                      dialog.cancel();
                 }
             });
      AlertDialog alert = builder.create();
      alert.show();
  }
  }
  </code></pre>