How do I implement Android.Text.ISpannable on a Android.Widget.EditText inside of Xamarin.Forms?
I've looked into Previous Post but the native java implementation is very different compared to Xamarin. And I don't know how to code it correctly. I found the solution for iOS but haven't found one for Android.
The Goal: On tap of the text entry control: I want to do any of the following:
- Nothing
- move the cursor to start or end (move the cursor)
- Select all text. If you tap the cell and start typing, you erase the contents and replace it with the new text.
Is this possible?
Also, the link for the repository in question. See "EntryCellRender" on android and iOS.
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);
}
...
}
The implementation of AiEditText.
[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 ) => Text[index];
public ICharSequence SubSequenceFormatted( int start, int end )
{
throw new NotImplementedException();
}
public IEnumerator<char> GetEnumerator() { return Text.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}