7

我想允许用户在我的 Android 应用程序中只编辑一行文本的一部分。我看到一个名为 EasyEditSpan 的类,但是当我将它粘贴到 TextView 中时,什么也没有发生。我尝试使 TextView 可编辑,但它仍然没有任何效果。如果切换到 EditText,那么整行文本都是可编辑的,这也是不正确的。这是我的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    TextView testView = (TextView)findViewById(R.id.text_view);
    testView.setText(buildMiddleEditSpannable("Please enter your ", "Name", " here."));
}

public static Spannable buildMiddleEditSpannable(CharSequence beginning, CharSequence middle, CharSequence end) {
    int spanMidStart = beginning.length();
    int spanMidEnd = spanMidStart + middle.length();

    SpannableString span = new SpannableString(new StringBuilder(middle).insert(0, beginning).append(end));
    span.setSpan(new EasyEditSpan(), spanMidStart, spanMidEnd, 0);
    return span;
}
4

2 回答 2

5

在查看引用EasyEditSpanEasyEditSpanTextViewTextUtils)的框架代码后,很明显,即使它在描述中说:

提供一种编辑部分文本的简单方法。

当前可用的功能仅限于描述的第二部分,如下所示:

TextView 使用这个跨度允许用户一键删除一段文本。文本。一旦文本被编辑或光标移动,TextView 就会删除这个跨度。

这是一些演示其用法的快速示例代码:

public class EasyEditSpanActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final EditText editText = new EditText(this);
        setContentView(editText);

        showToast("Longclick to set EasyEditSpan for the line on cursor");

        editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
        editText.setSingleLine(false);
        editText.setText("####\n#######\n###\n######\n####".replace("#", "text "));
        editText.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                final Layout layout = editText.getLayout();
                final int line = layout.getLineForOffset(editText.getSelectionStart());
                final int start = layout.getLineStart(line);
                final int end = layout.getLineEnd(line);
                editText.getEditableText().setSpan(new EasyEditSpan(), start, end,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                showToast("Edit line to show EasyEdit window");
                return true;
            }
        });
    }

    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

}

所以不幸的是,如果您需要一种方法来允许用户在您的应用程序中只编辑一行文本的一部分,EasyEditSpan似乎并没有多大帮助。您可能需要使用ClickableSpan自定义对话框来实现一些代码。

于 2012-07-22T04:46:33.343 回答
3

您最好使用 ClickableSpan 并弹出一个对话框来编辑内容。但是,我尝试实现部分可编辑的文本视图。这并不完整,可能有一些粗糙的边缘。它使用三个跨度并覆盖 onSelectionChanged(int selStart, int selEnd) 和 onKeyDown(int keyCode, KeyEvent event) 方法以在目标为 part1 或 part3 时禁用编辑。希望能帮助到你。

//activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.sensei.partialedit.EditTextSelectable
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        android:background="#00000000"
        tools:context=".MainActivity" />
</RelativeLayout>

//MainActivity.java

package com.sensei.partialedit;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EditTextSelectable testView = (EditTextSelectable) findViewById(R.id.text_view);
        testView.setText("Please enter your ", " Name ", " here.");
    }
}

//EditTextSelectable.java

package com.sensei.partialedit;

import android.content.Context;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.method.KeyListener;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.EditText;

public class EditTextSelectable extends EditText {

    private String part1;
    private String part2;
    private String part3;
    private ForegroundColorSpan span1;
    private CharacterStyle span2;
    private ForegroundColorSpan span3;

    public EditTextSelectable(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setTag(getKeyListener());
    }

    public EditTextSelectable(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTag(getKeyListener());
    }

    public EditTextSelectable(Context context) {
        super(context);
        setTag(getKeyListener());
    }

    public void setText(String part1, String part2, String part3) {
        setText(buildMiddleEditSpannable(part1, part2, part3));
        setSelection(part1.length() + part2.length() - 1);
    }

    private Spannable buildMiddleEditSpannable(String part1, String part2,
            String part3) {
        this.part1 = part1;
        this.part2 = part2;
        this.part3 = part3;
        SpannableStringBuilder spannable = new SpannableStringBuilder(part1
                + part2 + part3);
        span1 = new ForegroundColorSpan(Color.GRAY);
        spannable.setSpan(span1, 0, part1.length() - 1,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        span2 = new UnderlineSpan();
        spannable.setSpan(span2, part1.length(),
                part1.length() + part2.length(),
                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        span3 = new ForegroundColorSpan(Color.GRAY);
        spannable.setSpan(span3, (part1 + part2).length(),
                (part1 + part2 + part3).length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannable;
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        if (part1 == null)
            return;
        if (selStart >= getText().getSpanStart(span2)
                && selEnd <= getText().getSpanEnd(span2)) {
            setKeyListener((KeyListener) getTag());
            setCursorVisible(true);
        } else {
            setKeyListener(null);
            setCursorVisible(false);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode==KeyEvent.KEYCODE_ENTER) {
            // Just ignore the [Enter] key
            return true;
        }
        int selectionStart = getSelectionStart();
        int selectionEnd = getSelectionEnd();
        Log.d("partialedit", "OnKeyDown:" + selectionStart + ":" + selectionEnd + ":" + getText().getSpanStart(span2) + ":" + getText().getSpanEnd(span2));
        if (selectionStart < part1.length() + 1
            || selectionStart >= getText().length() - part3.length()) {
            return true;
        }

        // Handle all other keys in the default way
        return super.onKeyDown(keyCode, event);
    }
}
于 2012-07-24T06:10:10.720 回答