Relayout of Text field that is being editted scrambles text in simulator

两盒软妹~` 提交于 2019-12-08 03:59:53

问题


I want the user to enter an artbitrary number of keywords (or keyphrases). To this end, I have a row of TextFields, one for each keyword. I add a new TextField to the row when all existing ones have text in them, so the user can enter another keyword.

The addition of a new TextField happens when a character is added to the last empty TextField; i.e. that TextField is being editted when a new TextField is added. Furthermore, the existing TextFields will be moved and resized when adding a new TextField (to make space).

This works fine on Android, but in the simulator it does not. In the similator, the TextField being editted is being moved, but the text being editted is not.

The issue can be replicated using the form below.

Kind regards, Frans.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.codename1.ui.Container;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.TextArea;
import com.codename1.ui.TextField;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.GridLayout;

public class TextFieldRelayoutForm extends Form
{
    public TextFieldRelayoutForm()
    {
        super("TextField relayout", BoxLayout.y());
        add(new Label("Type into the last text field below"));
        Strings strings = new Strings("blabla");
        strings.setStrings(Arrays.asList("one", "two"));
        add(strings);
    }

    public class Strings extends Container
    {
        private final String hint;
        private final Runnable listener;

        public Strings(String hint)
        {
            this(hint, null);
        }

        public Strings(String hint, Runnable listener)
        {
            //TextField.setUseNativeTextInput(false);
            this.hint = hint;
            this.listener = listener;
            addEmptyField();
        }

        public void setStrings(List<String> strings)
        {
            removeAll();
            for (String string : strings)
            {
                addComponent(getTextField(string));
            }
            addEmptyField();
        }

        private TextField getTextField(String text)
        {
            TextField field = new TextField("", hint, 20, TextArea.ANY);
            field.setText(text);
            field.addDataChangedListener((t,i) -> textFieldDataChanged(field));
            return field;
        }

        private void textFieldDataChanged(TextField field)
        {
            if (!hasEmptyField())
            {
                addEmptyField();
            }
            if (listener != null)
            {
                listener.run();
            }
        }

        private boolean hasEmptyField()
        {
            for (int i = getComponentCount() - 1; i >= 0; i--)
            {
                String string = ((TextField)getComponentAt(i)).getText();
                if (string.length() == 0)
                {
                    return true;
                }
            }
            return false;
        }

        private void addEmptyField()
        {
            addComponent(getTextField(""));
            setLayout(new GridLayout(getComponentCount()));
            revalidate();
        }

        public List<String> getStrings()
        {
            List<String> strings = new ArrayList<>();
            for (int i = 0; i < getComponentCount(); i++)
            {
                String string = ((TextField)getComponentAt(i)).getText();
                if (string.length() != 0)
                {
                    strings.add(string);
                }
            }
            return strings;
        }
    }
}

回答1:


Editing happens in native code so when you edit we "seamlessly" layout a native text field on top of the lightweight text field and let you edit. I quoted seamlessly as this abstraction leaks on some cases and this is one of them. That's why it's a best practice to use stopEdit/startEditAsync when changing layouts or text field information.

You can read about similar issues in this post https://www.codenameone.com/blog/tip-stop-editing.html

Another possibly better alternative would be to use the action listener. This happens only when editing finished. This means fewer events and when you make changes you won't need to hack. The downside is that a user will need to abandon editing so the new field appears.



来源:https://stackoverflow.com/questions/53593553/relayout-of-text-field-that-is-being-editted-scrambles-text-in-simulator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!