Android在edittext字段中输入之前捕获扫描数据

时间:2017-08-28 18:36:44

标签: android xamarin android-edittext visual-studio-2017 barcode-scanner

实际发生的是设备根据是否设置为发送标签或输入,在扫描后发送2个输入或标签。

我使用xamarin Android命名空间构建

我已经尝试了所有可能,我已将我的片段设置为textwatcher

public class SearchFragment : BaseFragment, IDialogInterfaceOnDismissListener, ITextWatcher

并设置一个监听器

this._theEditText.AddTextChangedListener(this);

并在BeforeTextChanged事件中进行设置,但是无法从char序列中获取值,尽管在测试用例中扫描有8个字符,+ 2表示2个输入键,但它是8。

    public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
    {
        this._scanCount = _scanCount + (after - start);
        if (this._scanCount > 4)
        {
            string text = s.ToString();
            //need remove carriage returns and line feeds here if exist
            //then add single carriage return or advance to next field
        }

        if (this._scanTimer != null) this._scanTimer.Dispose();
        this._scanTimer = new Timer(delegate (object state)
        {
            this._scanCount = 0;
            this._scanTimer = null;
        }, false, 100, 0);
    }

我使用的下一个方法是捕获按键并使用在beforetext事件处理程序中内置的editText(我已经分别使用了所有这些不同的方法,而不是一起使用)

this._theEditText.KeyPress += EditText_KeyPress;
this._theEditText.BeforeTextChanged += EditText_BeforeTextChanged;

使用keypressed事件我只是得到了一堆标签和f4(我可能会添加这些标签并没有奇怪地推进这个领域)

再次使用BeforeTextChanged事件我无法获得字符序列,尽管8之前和之后存在差异(再次输入结束时没有计算)尽管实际文本中存在8的差异e.Text是“”

    private void EditText_BeforeTextChanged(object sender, TextChangedEventArgs e)
    {
        this._scanCount = _scanCount + (e.AfterCount - e.BeforeCount);
        if (this._scanCount > 4)
        {
            SpannableStringBuilder stringBuilder = (SpannableStringBuilder)e.Text;

            ((SpannableStringBuilder)e.Text).ToString();
        }

        if (this._scanTimer != null) this._scanTimer.Dispose();
        this._scanTimer = new Timer(delegate (object state)
        {
            this._scanCount = 0;
            this._scanTimer = null;
        }, false, 100, 0);
    }

2 个答案:

答案 0 :(得分:1)

是的,键盘扫描仪和Android相当混乱。我不得不处理的扫描仪用于发送Down + Enter作为他们完成扫描的标志。这是有效的Java代码(我相信你将它转换为C#并将Down / Enter更改为你的两个键没有问题)

public class ScannerView extends View implements View.OnKeyListener {
    private StringBuilder scannedCode = new StringBuilder();
    private Callback scanCallback;


    public void setCallback(Callback scanCallback) {
        this.scanCallback = scanCallback;
    }

    public ScannerView(Context context) {
        super(context);
        init();
    }

    public ScannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ScannerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ScannerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        setFocusable(true);
        setFocusableInTouchMode(true);
        requestFocus();
        setOnKeyListener(this);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        boolean consumed = false;
        if (event.getAction() != KeyEvent.ACTION_UP) {
            return consumed;
        }

        switch (keyCode) {
            case KeyEvent.KEYCODE_0:
            case KeyEvent.KEYCODE_1:
            case KeyEvent.KEYCODE_2:
            case KeyEvent.KEYCODE_3:
            case KeyEvent.KEYCODE_4:
            case KeyEvent.KEYCODE_5:
            case KeyEvent.KEYCODE_6:
            case KeyEvent.KEYCODE_7:
            case KeyEvent.KEYCODE_8:
            case KeyEvent.KEYCODE_9:
                scannedCode.append(keyCode - 7);
                consumed = true;
                break;
            case KeyEvent.KEYCODE_ENTER:
                if (scanCallback != null) {
                    scanCallback.onBarcodeScanned(scannedCode.toString());
                }
                scannedCode = new StringBuilder();
                consumed = true;
                break;

            case KeyEvent.KEYCODE_DPAD_DOWN:
                consumed = true;
                break;
        }

        return consumed;
    }

    interface Callback {
        void onBarcodeScanned(String barCode);
    }
}
从我学到的东西来看,这就像你可以通过扫描仪获得良好的零售体验一样接近。然后,您可以使用回调并将文本设置为您需要的任何编辑或处理它。只需记住始终将焦点设置到您的扫描视图:父生命周期事件,自己的焦点更改回调等等,您将在测试时找出其余部分。

答案 1 :(得分:0)

我了解到没有条形码扫描仪以相同的方式发送数据。正如尼克的回答所指出的那样,有一些发送密钥代码,但是我处理过的代码发送标签,换行符,回车符,甚至是前缀/后缀条形码字符串的空格,你可以一次性获得整个字符串。 / p>

文本观察者可以干净利落地处理这些问题。

对Java对象进行子类化并实现ITextWatcher:

public class StripperTextWatcher : Java.Lang.Object, ITextWatcher
{
    char[] stripThese = new char[] { '\n', '\t', '\r', ' ' };

    public void AfterTextChanged(IEditable s)
    {
        for (int i = 0; i < s.Length(); i++)
        {
            if (stripThese.Contains(s.ElementAt(i)))
            {
                s.Replace(i, i + 1, "");
                return; // AfterTextChanged is called recursively for each change.... 
            }
        }

    }

    public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
    {
    }

    public void OnTextChanged(ICharSequence s, int start, int before, int count)
    {
    }
}

用法:

var editText = FindViewById<EditText>(Resource.Id.editText1);
editText.AddTextChangedListener(new StripperTextWatcher());