Search code examples
java-melwuitnokia-s40lwuit-formlwuit-textfield

How to remove focus from LWUIT Textfield and resize Form correctly when Virtual Keyboard hides?


I'm facing a problem with the LWUIT's Textfield.

In some of my Forms I display a CategoryBar, while in others I hide it.

In some of the Forms I have Textfields, the problem presents itself when I focus on one and make the Virtual Keyboard (VKB) to appear. When the VKB appears, the screen components resize themselves to adjust to the Textfield to be visible while text is entered, but when I hide the VKB, either through the back button or the return key on the VKB, the Textfield remains with the focus, not only that, when the screen components resize themselves, the current visible Form resizes itself as if there was no CategoryBar present, so any components that are at the bottom of the Form are hidden by the CategoryBar.

This is fixed by displaying another Form (this includes PopupChoiceGroup and DatePicker) and then going back to the Form that is covered by the CategoryBar.

In other Forms where no CategoryBar is visible, sometimes the resizing when the VKB is shown causes the Forms to resize themselves as if the CategoryBar was visible, making it possible to interact with it when it shouldn't be available.

How can I make sure the focus is completely lost on the Textfield? Also, how to make sure a Form is resized correctly whether a CategoryBar is visible or not?

EDIT

I've been digging through the class reference for TextField, Form and VKB, in the later I found a method called autoAdjust which according to documentation:

Auto adjust size of the dialog. This method is triggered from a sizeChanged event.

The method sizeChanged sounded like something I should check and in the Form's reference the description for this method is:

This method is only invoked when the underlying canvas for the form gets a size changed event. This method will trigger a relayout of the Form. This method will get the callback only if this Form is the Current Form

This method seemed like the callback for resizing I was looking for, so I overrode it and placed a NotificatioBar to be displayed with the width and height values sent when the method was called.

What I found after testing this on my device was that when the Form was being resized after the VKB was shown or hidden, the height value sometimes instead of being 270 (the height for the Form when the CategoryBar is being displayed) it was sent as 320 (the full screen height, as if no CategoryBar was being displayed).

So far I haven't been able to understand why would the Form ignores the fact that the CategoryBar is being displayed or not when resizing the itself.

I tried to change the Form height inside its sizeChanged method but the Form wasn't affected by it. It seems to me what I have to modify is the canvas where the Form is being drawn, but I don't really know for sure since the canvas is hidden in LWUIT.

Could it be the canvas where my Form is being drawn is the one at fault? What is provoking this behaviour?


Solution

  • At the moment I found a workaround to avoid having my Components hidden by the CategoyBar because the Form resized wrongly after the VKB hid, for the scenario in which the Form resizes wrongly and displays the CategoryBar (which I don't know why is visible if I'm calling to its setVisibility method and passing false).

    First I overrode the sizeChanged method:

    protected void sizeChanged(int w, int h){
        if(h > 270){
            mainContainer.getStyle().setMargin(Component.BOTTOM, 50);
        }
        else{
            mainContainer.getStyle().setMargin(Component.BOTTOM, 0);
        }
    }
    

    I check the height value, if the value is greater than the expected height when the CategoryBar is being displayed then I set the bottom of my Container to 50, so it'll be visible.

    But this wasn't enough because if I show again the same form and it resizes correctly then the Container will remain with a bottom of 50. So I overrode the onShow method too:

    protected void onShow(){
        int containerBottom = mainContainer.getStyle().getMargin(Component.BOTTOM);
        if(this.getHeight() == 270 && containerBottom == 50){
            mainContainer.getStyle().setMargin(Component.BOTTOM, 0);
        }
    }
    

    I had to make sure if the height was 270 and my Container's bottom was 50 then the Container's bottom should be 0.

    Since I haven't found a way to avoid having my Form to resize and show the CategoryBar when it shouldn't be displayed at all, I don't consider myself with a full answer. Will update if I find a workaround for this.

    EDIT

    I tried with explicitly setting the shown/hidden status by calling the setVisibility method inside the onShow method of every Form I have. So far I've been able to avoid the visual problems I experienced previously. I'm not sure if this problem was due to LWUIT or due to J2ME restrictions but this is how I worked around it.