正在编辑的“文本”字段的重传扰乱模拟器中的文本 [英] Relayout of Text field that is being editted scrambles text in simulator

查看:54
本文介绍了正在编辑的“文本”字段的重传扰乱模拟器中的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望用户输入任意数量的关键字(或关键词)。为此,我有一排TextField,每个关键字一个。当所有现有的文本字段中都包含文本时,我将新的TextField添加到该行中,以便用户可以输入另一个关键字。

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.

当一个字符出现时,将添加一个新的TextField。添加到最后一个空的TextField;即添加新的TextField时正在编辑TextField。此外,添加新的TextField(以腾出空间)时,将移动现有TextField并调整其大小(以留出空间)。

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).

这在Android上工作正常,但在模拟器中却没有。在模拟器中,正在编辑的TextField会被移动,但是正在编辑的文本不会被移动。

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.

亲切的问候,弗朗斯。

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


推荐答案

编辑是在本机代码中进行的,因此当您进行编辑时,我们无缝将本机文本字段布置在轻量级文本字段之上,然后进行编辑。我无缝引用了这种抽象,在某些情况下会泄漏,这就是其中一种。这就是为什么在更改布局或文本字段信息时最好使用stopEdit / startEditAsync的原因。

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.

您可以在这篇文章中了解类似的问题 https://www.codenameone.com/blog/tip-stop-editing.html

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.

这篇关于正在编辑的“文本”字段的重传扰乱模拟器中的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆