Android 上的 Xamarin 编辑器控制 CursorPosition [英] Xamarin Editor Control CursorPosition on Android

查看:27
本文介绍了Android 上的 Xamarin 编辑器控制 CursorPosition的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在处理一个需要大量文本操作的项目,我正在尝试创建一个可以在当前 CursorPosition 处插入文本的函数.我使用编辑器作为我的文本控件,我注意到 Xamarin 尚未提供 CursorPosition 的实现.

我发现 Xamarin 开发人员在他们的

I'm currently working on a project that requires alot of text manipulation and i'm trying to create a function that can insert text at the current CursorPosition. I'm using a Editor as my Text Control and i noticed that Xamarin does not provide an implementation for CursorPosition yet.

I found out that the Xamarin developers have this on their backlog but I can't wait for this as I am on a deadline.

I made my own CustomRenderer for the Editor control and i got CursorPosition working for UWP. When i tried to do the same thing for Android however I noticed that I need to use an the event EventHandler SelectionChanged; in the IFormsEditText interface that is not available to me as they marked the interface internal.

Little snippit of code to display progress:

internal class EditorRenderer : Xamarin.Forms.Platform.Android.EditorRenderer
{
    bool _cursorPositionChangePending;
    bool _nativeSelectionIsUpdating;

    IElementController ElementController => Element as IElementController;

    public EditorRenderer(Context context) : base(context) { }

    private Editor _editor;

    protected override void OnElementChanged(ElementChangedEventArgs<XamarinForms.Editor> e)
    {
        base.OnElementChanged(e);

        _editor = (Editor)Element;

        _cursorPositionChangePending = Element.IsSet(Editor.CursorPositionProperty);

        // I wanted to do something along the lines of this
        //if (Control is IFormsEditText editText)
        //{
        //    editText.SelectionChanged += SelectionChanged;
        //}

        if (_cursorPositionChangePending)
            UpdateCursorSelection();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == Editor.CursorPositionProperty.PropertyName)
        {
            UpdateCursorSelection();
        }
    }
    void SelectionChanged(object sender, XamarinFormsDroid.SelectionChangedEventArgs e)
    {
        if (_nativeSelectionIsUpdating || Control == null || Element == null)
            return;

        int cursorPosition = _editor.CursorPosition;
        int selectionStart = EditText.SelectionStart;

        if (!_cursorPositionChangePending)
        {
            var start = cursorPosition;

            if (selectionStart != start)
                SetCursorPositionFromRenderer(selectionStart);
        }

        if (!_selectionLengthChangePending)
        {
            int elementSelectionLength = Math.Min(EditText.Text.Length - cursorPosition, _editor.SelectionLength);

            var controlSelectionLength = EditText.SelectionEnd - selectionStart;
            if (controlSelectionLength != elementSelectionLength)
                SetSelectionLengthFromRenderer(controlSelectionLength);
        }
    }

Has anyone tried making their own renderer for android with a working implementation for CursorPosition ? Or does anyone have any idea on how this could be realized ? Please let me know.

解决方案

Editor do not support CursorPosition Changed event. You could create a custom control EditText. EditText provides OnSelectionChanged event. And add this custom EditText in EditorRenderer.

MyEditor.cs: Create Editor custom control. And binding the OnSelectionChanged event.

public class MyEditor : Editor
{
    public static readonly BindableProperty SelectionChangedProperty =
    BindableProperty.Create("SelectionChanged", typeof(EventHandler), typeof(MyEditor), null);

    public event EventHandler SelectionChanged;

   public void SelectionChange(int preIndex,int currentIndex)
    {
        EventHandler eventHandler = this.SelectionChanged;
        SelectionEventArgs selectionEventArgs = new SelectionEventArgs() { lastPos = preIndex, curPos = currentIndex };
        eventHandler?.Invoke((object)this, selectionEventArgs);
    }

   public class SelectionEventArgs : EventArgs
    {
       public int lastPos { get; set; }
        public int curPos { get; set; }
    }
}

EditorRenderer.cs:

[assembly: ExportRenderer(typeof(MyEditor), typeof(XamarinDemo.Droid.EditorRenderer))]
namespace XamarinDemo.Droid
{
class EditorRenderer : Xamarin.Forms.Platform.Android.EditorRenderer, MyEditText.EditTextSelectChange
{
    Context _context;
    public EditorRenderer(Context context) : base(context)
    {
        _context = context;
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
    {
        base.OnElementChanged(e);

        MyEditText myEditText = new MyEditText(_context);
        myEditText.Text = Element.Text;
        myEditText.setEditTextSelectChange(this);
        SetNativeControl(myEditText);
    }


    public void change(int lastPos, int curPos)
    {
        //Console.WriteLine("lastPos ===" + lastPos + "curPos ====" + curPos);
        ((MyEditor)Element).SelectionChange(lastPos, curPos);
    }

}
}

MyEditText.cs: In Xamarin.Forms Android spefic project, create a EditTextSelectChange for EditorRenderer to inherit.

 class MyEditText :FormsEditText
{

    private int mLastPos = 0;
    private int mCurPos = 0;

    private EditTextSelectChange editTextSelectChange;

    public void setEditTextSelectChange(EditTextSelectChange editTextSelectChange)
    {
        this.editTextSelectChange = editTextSelectChange;
    }

    public MyEditText(Context context):base(context)
    {
    }


    protected override void OnSelectionChanged(int selStart, int selEnd)
    {
        base.OnSelectionChanged(selStart, selEnd);
        if (this.editTextSelectChange != null)
        {
            mCurPos = selEnd;
            editTextSelectChange.change(mLastPos, mCurPos);
            mLastPos = mCurPos;
        }

    }

    public interface EditTextSelectChange
    {
        void change(int lastPos, int curPos);
    }
}

Usage:

        <local:MyEditor SelectionChanged="SelectionChange" Text="hakssksksssfsvdsv" />

Code Behind:

 public partial class Page13 : ContentPage
{
    public Page13()
    {
        InitializeComponent();
    }

    private void SelectionChange(object sender, EventArgs e)
    {
        Console.WriteLine("lastpos =="+ ((SelectionEventArgs)e).lastPos +"curpos =="+ ((SelectionEventArgs)e).curPos);
    }
}

Screenshot:

这篇关于Android 上的 Xamarin 编辑器控制 CursorPosition的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆