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

EasyEditSpan( EasyEditSpanTextView、およびTextUtils )を参照するフレームワーク コードを見ると、その説明には次のように記載されているにもかかわらず、次のことが明らかになります。

テキストの一部を編集する簡単な方法を提供します。

現在利用可能な機能は、次の説明の 2 番目の部分に限定されています。

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 を使用し、ダイアログをポップアップしてコンテンツを編集する方がよい場合があります。ただし、部分的に編集可能なテキストビューを実装しようとしました。これは完全ではなく、荒削りな部分があるかもしれません。3 つのスパンを使用し、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 に答える