title: How do I implement Android.Text.ISpannable on a Android.Widget.EditText inside of Xamarin.Forms?
body: <p>How do I implement <strong>Android.Text.ISpannable</strong> on a <strong>Android.Widget.EditText</strong> inside of Xamarin.Forms?</p>
  <p>I've looked into <a href="https://stackoverflow.com/questions/6117485/android-edittext-how-to-start-cursor-pointer-at-the-end-of-all-characters-not-e">Previous Post</a> but the native java implementation is very different compared to Xamarin. And I don't know how to code it correctly. I found the <a href="https://stackoverflow.com/questions/34922331/getting-and-setting-cursor-position-of-uitextfield-and-uitextview-in-swift">solution for iOS</a> but haven't found one for Android.</p>
  <p><strong>The Goal:</strong> On tap of the text entry control: I want to do any of the following:</p>
  <ul>
  <li>Nothing</li>
  <li>move the cursor to start or end (move the cursor)</li>
  <li>Select all text.   If you tap the cell and start typing, you erase the contents and replace it with the new text.</li>
  </ul>
  <p>Is this possible?</p>
  <p>Also, the link for the <a href="https://github.com/Jakar510/Jakar.SettingsView" rel="nofollow noreferrer">repository</a> in question. See &quot;EntryCellRender&quot; on android and iOS.</p>
  <pre><code>public class EntryCell :  : CellBaseView, Android.Text.ITextWatcher, Android.Widget.TextView.IOnFocusChangeListener, Android.Widget.TextView.IOnEditorActionListener
  {
      AiEditText _EditText;
      ...
      void EntryCell_Focused( object sender, EventArgs e )
      {
          _EditText.RequestFocus();
  
          // https://stackoverflow.com/questions/20838227/set-cursor-position-in-android-edit-text/20838295
          switch ( _EntryCell.OnSelectAction )
          {
              case AiEntryCell.SelectAction.None:
                  break;
  
              case AiEntryCell.SelectAction.Start:
                  Selection.SetSelection(_EditText, 0); // Xamarin requires Android.Text.ISpannable implementation.
  
                  break;
  
              case AiEntryCell.SelectAction.End:
                  int position = _EditText.Length();
                  Selection.SetSelection(_EditText, position); // Xamarin requires Android.Text.ISpannable implementation.
  
                  break;
  
              case AiEntryCell.SelectAction.All:
                  _EditText.SelectAll();
  
                  break;
  
              default: throw new ArgumentOutOfRangeException();
          }
  
          ShowKeyboard(_EditText);
      }
  
      ...
  }
  </code></pre>
  <p>The implementation of AiEditText.</p>
  <pre><code>[Android.Runtime.Preserve(AllMembers = true)]
  internal class AiEditText : Android.Widget.EditText, Android.Text.ISpannable
  {
      public System.Action ClearFocusAction { get; set; }
  
      public AiEditText( Context context ) : base(context) { }
  
      public override bool OnKeyPreIme( Keycode keyCode, KeyEvent e )
      {
          if ( keyCode != Keycode.Back ||
               e.Action != KeyEventActions.Up ) return base.OnKeyPreIme(keyCode, e);
  
          ClearFocus();
          ClearFocusAction?.Invoke();
  
          return base.OnKeyPreIme(keyCode, e);
      }
  
      public void RemoveSpan( Java.Lang.Object what )
      {
          throw new NotImplementedException();
      }
      public void SetSpan( Java.Lang.Object what,
                           int start,
                           int end,
                           [GeneratedEnum] Android.Text.SpanTypes flags )
      {
          switch ( flags )
          {
              case SpanTypes.Composing: break;
  
              case SpanTypes.ExclusiveExclusive: break;
  
              case SpanTypes.ExclusiveInclusive: break;
  
              case SpanTypes.InclusiveExclusive: break;
  
              case SpanTypes.InclusiveInclusive: break;
  
              case SpanTypes.Intermediate: break;
  
              case SpanTypes.Paragraph: break;
  
              case SpanTypes.Priority: break;
  
              case SpanTypes.PriorityShift: break;
  
              case SpanTypes.User: break;
  
              case SpanTypes.UserShift: break;
  
              default: throw new ArgumentOutOfRangeException(nameof(flags), flags, null);
          }
      }
      public int GetSpanEnd( Java.Lang.Object tag )
      {
          throw new NotImplementedException();
      }
      [return: GeneratedEnum]
      public SpanTypes GetSpanFlags( Java.Lang.Object tag )
      {
          throw new NotImplementedException();
      }
      public Java.Lang.Object[] GetSpans( int start, int end, Class type )
      {
          throw new NotImplementedException();
      }
      public int GetSpanStart( Java.Lang.Object tag )
      {
          throw new NotImplementedException();
      }
      public int NextSpanTransition( int start, int limit, Class type )
      {
          throw new NotImplementedException();
      }
      public char CharAt( int index ) =&gt; Text[index];
      public ICharSequence SubSequenceFormatted( int start, int end )
      {
          throw new NotImplementedException();
      }
      public IEnumerator&lt;char&gt; GetEnumerator() { return Text.GetEnumerator(); }
      IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
  }
  </code></pre>