Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将“自定义可编辑”与EditText一起使用会使其在编辑时出现问题_Java_Android_Android Edittext_Textview_Spannablestring - Fatal编程技术网

Java 将“自定义可编辑”与EditText一起使用会使其在编辑时出现问题

Java 将“自定义可编辑”与EditText一起使用会使其在编辑时出现问题,java,android,android-edittext,textview,spannablestring,Java,Android,Android Edittext,Textview,Spannablestring,注意:我已经创建了一个GitHub repo,其中包含此bug的复制。请随意克隆并亲自试用该应用程序,以查看bug。相关的代码是:注释部分保留在注释中,工作正常,取消注释,您将体验到错误 我正在为Android构建一个源代码编辑器应用程序。我有一个自定义的可编辑的类型,它包装了SpannableStringBuilder(以后称为SSB)。代码如下: package com.bluejay.myapplication; import android.text.Editable; import

注意:我已经创建了一个GitHub repo,其中包含此bug的复制。请随意克隆并亲自试用该应用程序,以查看bug。相关的代码是:注释部分保留在注释中,工作正常,取消注释,您将体验到错误


我正在为Android构建一个源代码编辑器应用程序。我有一个自定义的
可编辑的
类型,它包装了
SpannableStringBuilder
(以后称为SSB)。代码如下:

package com.bluejay.myapplication;

import android.text.Editable;
import android.text.InputFilter;
import android.text.SpannableStringBuilder;

public class ColoredText implements Editable {
    private final SpannableStringBuilder builder;

    public ColoredText(String rawText) {
        assert rawText != null;
        this.builder = new SpannableStringBuilder(rawText);
    }

    @Override
    public Editable replace(int st, int en, CharSequence source, int start, int end) {
        this.builder.replace(st, en, source, start, end);
        return this;
    }

    @Override
    public Editable replace(int st, int en, CharSequence text) {
        this.builder.replace(st, en, text);
        return this;
    }

    @Override
    public Editable insert(int where, CharSequence text, int start, int end) {
        this.builder.insert(where, text, start, end);
        return this;
    }

    @Override
    public Editable insert(int where, CharSequence text) {
        this.builder.insert(where, text);
        return this;
    }

    @Override
    public Editable delete(int st, int en) {
        this.builder.delete(st, en);
        return this;
    }

    @Override
    public Editable append(CharSequence text) {
        this.builder.append(text);
        return this;
    }

    @Override
    public Editable append(CharSequence text, int start, int end) {
        this.builder.append(text, start, end);
        return this;
    }

    @Override
    public Editable append(char text) {
        this.builder.append(text);
        return this;
    }

    @Override
    public void clear() {
        this.builder.clear();
    }

    @Override
    public void clearSpans() {
        this.builder.clearSpans();
    }

    @Override
    public void setFilters(InputFilter[] filters) {
        this.builder.setFilters(filters);
    }

    @Override
    public InputFilter[] getFilters() {
        return this.builder.getFilters();
    }

    @Override
    public void getChars(int start, int end, char[] dest, int destoff) {
        this.builder.getChars(start, end, dest, destoff);
    }

    @Override
    public void setSpan(Object what, int start, int end, int flags) {
        this.builder.setSpan(what, start, end, flags);
    }

    @Override
    public void removeSpan(Object what) {
        this.builder.removeSpan(what);
    }

    @Override
    public <T> T[] getSpans(int start, int end, Class<T> type) {
        return this.builder.getSpans(start, end, type);
    }

    @Override
    public int getSpanStart(Object tag) {
        return this.builder.getSpanStart(tag);
    }

    @Override
    public int getSpanEnd(Object tag) {
        return this.builder.getSpanEnd(tag);
    }

    @Override
    public int getSpanFlags(Object tag) {
        return this.builder.getSpanFlags(tag);
    }

    @Override
    public int nextSpanTransition(int start, int limit, Class type) {
        return this.builder.nextSpanTransition(start, limit, type);
    }

    @Override
    public int length() {
        return this.builder.length();
    }

    @Override
    public char charAt(int index) {
        return this.builder.charAt(index);
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        return this.builder.subSequence(start, end);
    }
}
编辑文本时,
EditText
的行为会非常容易出错。在上面的示例中,使用
Hello world并开始键入随机字符。第二行将受到影响,并且不知何故(即使您没有触摸换行符或箭头键),光标最终将溢出到第二行。即使光标移动,您键入的某些字符也可能无法显示

现在,如果您注释掉
setEditableFactory
部分,那么文本将在
setText()
期间复制到SSB中,并且再次运行该应用程序,您将看到没有任何故障

如果将
setEditableFactory
部分保持不变,但将
text
的变量初始化替换为

SpannableStringBuilder text = new SpannableStringBuilder("Hello world!\nHello world again!");

显然,尽管
setText()
表示它将接受任何
可编辑的
,但它在处理SSB以外的任何东西时都不起作用。为什么会发生这种情况?我如何修复它?谢谢。

通过挖掘
SpannableStringBuilder
的源代码,我发现它不仅履行了界面
Editable
等定义的职责,而且还通过传递
this
调用
SpanWatcher.onSpanChanged()
来报告span更改
DynamicLayout
EditText
)的真正工作人员)通过检查传入引用与其成员(即实际的
ColoredSpan
实例)的相等性来响应
OnPanChanged()
。显然,他们是不同的,我怀疑这是一个问题


实际上,
SpannableStringBuilder
不仅是可编辑的,而且还不止于此。如果您需要自定义
可编辑的
子类化
SpannableStringBuilder
可能会起作用。

通过挖掘
SpannableStringBuilder
的源代码,我发现它不仅履行了接口
可编辑的
定义的职责,等等,但也可以通过调用
SpanWatcher.onPanChanged()
来报告span更改,方法是传递
this
DynamicLayout
EditText
)的真正工作人员)通过检查传入引用与其成员(即实际的
ColoredSpan
实例)的相等性来响应
OnPanChanged()
。显然,他们是不同的,我怀疑这是一个问题


实际上,
SpannableStringBuilder
不仅是可编辑的,而且还不止于此。如果您需要一个自定义的
可编辑的
子类化
SpannableStringBuilder
可能会起作用。

通过挖掘
SpannableStringBuilder
的源代码,我发现它不仅履行了接口
可编辑的
定义的职责,等等,但也可以通过调用
SpanWatcher.onPanChanged()
来报告span更改,方法是传递
this
DynamicLayout
EditText
)的真正工作人员)通过检查传入引用与其成员(即实际的
ColoredSpan
实例)的相等性来响应
OnPanChanged()
。显然,它们是不同的,我怀疑这是一个问题。实际上,
SpannableStringBuilder
不仅仅是可编辑的,而且还不止于此。如果您需要自定义的
可编辑的
子类化
SpannableStringBuilder
可以工作。然而,我对这些事情不是很确定,因此我将其作为评论发布。@Durgadass非常感谢您深入研究问题并提供解决方案。我试着扩展SSB,现在这个应用程序运行得很好。如果你发布一个答案,我很乐意接受。通过挖掘
SpannableStringBuilder
的源代码,我发现它不仅履行了界面
Editable
等定义的职责,而且还通过调用
SpanWatcher.onSpanChanged()
传递
this
来报告span更改
DynamicLayout
EditText
)的真正工作人员)通过检查传入引用与其成员(即实际的
ColoredSpan
实例)的相等性来响应
OnPanChanged()
。显然,它们是不同的,我怀疑这是一个问题。实际上,
SpannableStringBuilder
不仅仅是可编辑的,而且还不止于此。如果您需要自定义的
可编辑的
子类化
SpannableStringBuilder
可以工作。然而,我对这些事情不是很确定,因此我将其作为评论发布。@Durgadass非常感谢您深入研究问题并提供解决方案。我试着扩展SSB,现在这个应用程序运行得很好。如果你给我回信,我很乐意接受。
SpannableStringBuilder text = new SpannableStringBuilder("Hello world!\nHello world again!");