简体   繁体   中英

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.

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. 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. The blinking cursor appears in the field to the far right, but I cannot scan (or type) into this field. Once I touch the field, the cursor jumps to the far left and I am able to scan or type into the field again.

I have tried inserting sleep(100) just before calls to requestFocus(). I have also tried using repaint(). The only thing that helps is to remove the call to 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.

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.

What you want to use is startEditingAsync() to and possibly a stopEditing() if the wrong field might be edited.

As a sidenote You shouldn't issue repaint() calls unless you're building a custom component. You should NEVER invoke sleep on the EDT. This is a serious bug!

Thanks, Shai. Obviously I'm a newbie at CNO and mobile GUI development.

In addition to wrapping textedit edits in startEditingAsync() and startEditingAsync(), I had to handle these edits outside of the datachanged event handler.

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();
        }
    }
};        

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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