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