简体   繁体   English

CodenameOne 文本字段关注 Android

[英]CodenameOne Text Field Focus on Android

I have a textfield 'Barcode' and a textarea 'BarcodeList'.我有一个文本字段“条形码”和一个文本区域“条形码列表”。

At startup I want to set focus on the 'Barcode' field.在启动时,我想将焦点放在“条形码”字段上。 My Android scanner works just like a keyboard and successfully scans into this field.我的 Android 扫描仪就像键盘一样工作,并成功扫描到该字段。

When the 'Barcode' textfield changes I want to add the contents to the 'BarcodeList' textarea and then set focus back to the 'Barcode' field to get ready for the next scan.当“条形码”文本字段更改时,我想将内容添加到“条形码列表”文本区域,然后将焦点设置回“条形码”字段以准备下一次扫描。

The problem is that this works in the simulator but not on the Android device.问题是这在模拟器中有效,但在 Android 设备上无效。 On the device (Unitech HT730), the scanned data is added to the 'Barcode' field and then is copied to the 'BarcodeList', however the focus is not returned to the 'Barcode' field.在设备 (Unitech HT730) 上,扫描的数据被添加到“条形码”字段,然后复制到“条形码列表”,但焦点不会返回到“条形码”字段。 The blinking cursor appears in the field to the far right, but I cannot scan (or type) into this field.闪烁的 cursor 出现在最右侧的字段中,但我无法扫描(或输入)到该字段中。 Once I touch the field, the cursor jumps to the far left and I am able to scan or type into the field again.一旦我触摸该字段,cursor 就会跳到最左边,我可以再次扫描或输入该字段。

I have tried inserting sleep(100) just before calls to requestFocus().我试过在调用 requestFocus() 之前插入 sleep(100)。 I have also tried using repaint().我也尝试过使用 repaint()。 The only thing that helps is to remove the call to clear().唯一有帮助的是删除对 clear() 的调用。 Its seems that clear() must mess with something other than just the 'Barcode' text contents, but I cannot find any alternative way to clear the Barcode contents: even setText("") does not work.似乎 clear() 必须弄乱除“条形码”文本内容以外的其他内容,但我找不到任何其他方法来清除条形码内容:即使 setText("") 也不起作用。

Below is the code snippet that I am using:下面是我正在使用的代码片段:

gui_Barcode_t.addDataChangeListener((i1, i2) -> {           
    String s1 = gui_Barcode_t.getText();
    
    // A DataChange event will fire after the field is cleared, so test to see if this has occurred.
    if (s1.length()> 0) {           
        List_s += s1 + "\n";

        gui_BarcodeList_ta.requestFocus();
        gui_BarcodeList_ta.setText(List_s);
        sleep(100);            
        gui_BarcodeList_ta.repaint();
    } else {
        // This works in sim: repaint(), sleep(100), requestFocus()
        gui_Barcode_t.repaint();
        sleep(100);            
        gui_Barcode_t.requestFocus();
        return;
    }

    // Note that a DataChange event will fire after the field is cleared.
    // This works in sim: clear(), sleep(100), repaint(), sleep(100), requestFocus().
    // This works on Android device if clear() is removed, but the text field is not cleared.
    gui_Barcode_t.clear();
    sleep(100);
    gui_Barcode_t.repaint();
    sleep(100);            
    gui_Barcode_t.requestFocus();
});

requestFocus() is great for focus but it might collide with native editing which is a different process. requestFocus()非常适合焦点,但它可能会与本机编辑发生冲突,这是一个不同的过程。

What you want to use is startEditingAsync() to and possibly a stopEditing() if the wrong field might be edited.您要使用的是startEditingAsync()stopEditing()如果可能编辑了错误的字段。

As a sidenote You shouldn't issue repaint() calls unless you're building a custom component.作为旁注,除非您正在构建自定义组件,否则不应发出repaint()调用。 You should NEVER invoke sleep on the EDT.你不应该在EDT上调用睡眠。 This is a serious bug!这是一个严重的错误!

Thanks, Shai.谢谢,夏伊。 Obviously I'm a newbie at CNO and mobile GUI development.显然我是 CNO 和移动 GUI 开发的新手。

In addition to wrapping textedit edits in startEditingAsync() and startEditingAsync(), I had to handle these edits outside of the datachanged event handler.除了在 startEditingAsync() 和 startEditingAsync() 中包装 textedit 编辑之外,我还必须在 datachanged 事件处理程序之外处理这些编辑。

public void onBarcode_tDataChangeEvent(com.codename1.ui.Component cmp, int type, int index) {
    BarcodeDataChangedFired = true;
}

task = new TimerTask() {        
    // run() method to carry out the action of the task
    public void run() {          
    if (BarcodeDataChangedFired) {
            BarcodeDataChangedFired = false;
            
            String s1 = gui_Barcode_t.getText();

            // If this event was fired because of the gui_Barcode_ta.setText(" ")..
            if (s1.length() < 1) { 
                // Set focus back to the barcode field.
                gui_Barcode_t.startEditingAsync();
                //gui_BarcodeList_ta.stopEditing(); // THIS PREVENTS THE TEXTCHANGE FROM FIRING!
                return;
            }

            // Play a sound to indicate that the barcode was read.
            PlayMP3("bell4.wav");

            // Copy the new barcode into the barcode list.
            gui_BarcodeList_ta.startEditingAsync();
            gui_BarcodeList_ta.setText(s1);
            gui_BarcodeList_ta.stopEditing();

            // Clear the barcode field.
            gui_Barcode_t.startEditingAsync();
            // This is the only way to clear the TextArea, and it will fire the DataChanged event.
            gui_Barcode_t.clear();
            gui_BarcodeList_ta.stopEditing();
        }
    }
};        

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM