焦点上的EditText选择不起作用

时间:2014-05-30 09:29:55

标签: android android-edittext

由于我对Android正在进行十进制输入的方式感到非常失望,所以我决定编写自己继承自EditText的EditDecimal控件。我希望它在点击时选择全部并将光标放在焦点上的第一个位置。我不希望光标显示,因为它在大多数Android手机上都没用(你大多数都不能把它放在正确的地方,这让我非常紧张)

当您点击控件时出现问题 - 调用FocusChanged但它没有将(隐藏)光标的位置设置在第一个位置,而是设置在用户点击的位置。我找不到问题......在FocusChange移动光标后会发生一些其他事件吗?

public class EditDecimal : EditText
{
    // Every constructor is calling Initialize ...

    private void Initialize()
    {

        FocusChange += OnFocusChanged;
        Click += OnClicked;
        SetCursorVisible(false);
    }

    private void OnFocusChanged(object sender, FocusChangeEventArgs e)
    {
        if (IsFocused)
            SetSelection(1);
    }

    private void OnClicked(object sender, EventArgs e)
    {
        SelectAll();
    }
}

2 个答案:

答案 0 :(得分:0)

Grepcode是你的朋友。它显示TextView的onFocusChanged方法检查是否为View定义了一个Editor对象(EditText就是这种情况),并查看Editor code在第889行显示的内容: / p>

// If a tap was used to give focus to that view, move cursor at tap position.
// Has to be done before onTakeFocus, which can be overloaded.
final int lastTapPosition = getLastTapPosition();
if (lastTapPosition >= 0) {
    Selection.setSelection((Spannable) mTextView.getText(), lastTapPosition);
}

所以也许最好的方法是编写自己的编辑器实现。虽然如果现在不知道如何将它附加到TextView resp。 EditText上。类。

或者您只需将选择设置回第一个位置即可。

答案 1 :(得分:0)

我终于解决了它。我必须订阅OnTouch事件并从那里更改光标位置。

public class EditDecimal : EditText
{
    // Every constructor is calling Initialize ...

    private InputMethodManager _imm ;
    public int DecimalSpaces { get; set; }
    readonly DecimalFormatSymbols _dfs = new DecimalFormatSymbols(); 

    private void Initialize(Context context, IAttributeSet attrs)
    {
        AfterTextChanged += OnAfterTextChanged; 
        SetSelectAllOnFocus(true);
        SetCursorVisible(false);            
        Touch += OnTouch;

        _imm = (InputMethodManager)context.GetSystemService(Context.InputMethodService);

        var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.EditDecimal);
        try
        {
            DecimalSpaces = a.GetInteger(Resource.Styleable.EditDecimal_decimalSpaces, 2);
        }
        finally
        {
            a.Recycle();
        }
    }

    private void OnTouch(object sender, TouchEventArgs e)
    {
        base.OnTouchEvent(e.Event);


        if (e.Event.Action == MotionEventActions.Up)
        {
            SelectAll();
        }
    }

    protected override void OnFocusChanged(bool gainFocus, FocusSearchDirection direction, Rect previouslyFocusedRect)
    {
        base.OnFocusChanged(gainFocus, direction, previouslyFocusedRect);
        SelectAll();
    }

    private void OnAfterTextChanged(object sender, AfterTextChangedEventArgs e)
    {
        const char ch1 = '.';
        const char ch2 = ',';

        switch (_dfs.DecimalSeparator)
        {
            case ch2:
            {
                if (Text.Contains(ch1.ToString()))
                {
                    var position = Text.IndexOf(ch1);

                    if (Text.Contains(ch2.ToString()))
                        e.Editable.Delete(position, position + 1);
                    else
                        e.Editable.Replace(position, position + 1, ch2.ToString()); 
                }

                // we have to prevent showing two commas in number 
                var firstCommaPosition = Text.IndexOf(ch2);
                var lastCommaPosition = Text.LastIndexOf(ch2);

                if (firstCommaPosition > 0 && lastCommaPosition > 0 && firstCommaPosition != lastCommaPosition)
                    e.Editable.Delete(lastCommaPosition, lastCommaPosition+1);
            }
                break;
            case ch1:
            {
                if (Text.Contains(ch2.ToString()))
                {
                    var position = Text.IndexOf(ch2);
                    e.Editable.Delete(position, position + 1);
                }

                // we have to prevent showing two points in number 
                var firstPointPosition = Text.IndexOf(ch1);
                var lastPointPosition = Text.LastIndexOf(ch1);

                if (firstPointPosition > 0 && lastPointPosition > 0 && firstPointPosition != lastPointPosition)
                    e.Editable.Delete(lastPointPosition, lastPointPosition + 1);
            }
                break;
        }


        //thnx to http://stackoverflow.com/users/2240673/tom
        var length = e.Editable.Length();

        if (length <= 0) return;

        if (NrOfDecimal(e.Editable.ToString()) > DecimalSpaces)
            e.Editable.Delete(length - 1, length);
    }

    private int NrOfDecimal(string nr)
    {
        if (nr == null) return 0;

        var nrCharArray = nr.ToCharArray();

        var len = nr.Length;
        var pos = len;
        for (var i = 0; i < len; i++)
        {
            if (nrCharArray[i] != '.') continue;

            pos = i + 1;
            break;
        }
        return len - pos;
    }
}

对我来说,如果SetCursorVisible设置为true而设置为false,则EditText选择的行为会有所不同。我以为这只是能见度属性。