codenameone - 正在编辑的文本字段的重新布局会扰乱模拟器中的文本
问题描述
我希望用户输入任意数量的关键字(或关键词)。为此,我有一排 TextFields,每个关键字一个。当所有现有的文本字段中都有文本时,我会在行中添加一个新的文本字段,以便用户可以输入另一个关键字。
当一个字符添加到最后一个空的 TextField 时,会添加一个新的 TextField;即添加新的 TextField 时正在编辑 TextField。此外,在添加新的 TextField(以腾出空间)时,将移动现有的 TextField 并调整其大小。
这在 Android 上运行良好,但在模拟器中却不行。在模拟器中,正在编辑的 TextField 正在移动,但正在编辑的文本没有。
可以使用下面的表格复制该问题。
亲切的问候,弗兰斯。
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 是最佳实践的原因。
您可以在这篇文章https://www.codenameone.com/blog/tip-stop-editing.html中了解类似问题
另一个可能更好的选择是使用动作监听器。这仅在编辑完成时发生。这意味着更少的事件,并且当您进行更改时,您将不需要破解。缺点是用户需要放弃编辑才能出现新字段。
推荐阅读
- android - 片段内部的底部工作表对话框
- ios - 我们如何在 IOS swift 4 中编辑 PDFPage 文本?
- python - 获取 DEM 栅格文件的垂直 (z) 分辨率(使用 gdal 和 python)?
- python - 如何使用python创建HTML文件的json
- visual-studio-code - 如何从 Visual Studio 代码中的悬停中过滤掉自定义 JSDoc 标记?
- php - Woocommerce中基于时间和日期的有条件交货通知
- python - 使用循环创建变量
- delphi - 如何使 Delphi 表单上的所有控件不可编辑/可更改但仍允许用户复制内容
- azure - 如何使用 Graph Api 使用正则表达式在 Azure AD B2C 中查找用户?
- reactjs - 无法使用 express 访问 nginx 上的路由