EditText:允许滚动但禁止选择
EditText: allow scrolling but disable selecting
我正在尝试创建一个 EditText
,其中无法选择任何文本,但用户仍然可以浏览。
为了归档第一个函数,a 创建了一个自定义 OnTouchListener
并且只响应 ACTION_DOWN
事件,如下所示:
View.OnTouchListener otl = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
scroll_down_x = event.getX();
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + mText.getScrollX();
int offset = layout.getOffsetForHorizontal(0, x);
if(offset>0)
if(x>layout.getLineMax(0))
mText.setSelection(offset); // touch was at end of text
else
mText.setSelection(offset - 1);
break;
}
return true;
}
};
mText.setOnTouchListener(otl);
但这也会禁用滚动。然后我尝试 reimplement
ACTION_MOVE
事件
case MotionEvent.ACTION_MOVE:
String input = ((EditText)v).getText().toString();
float width = ((EditText) v).getPaint().measureText(input);
float cwidth = ((EditText)v).getWidth();
//only scroll when the text is too long for the control
if (width >cwidth )
{
layout = ((EditText) v).getLayout();
x = event.getX() - scroll_down_x;
offset = layout.getOffsetForHorizontal(0, x);
mText.scrollBy((int) x, mText.getScrollY());
}
return true;
但这根本不起作用 - 滚动不是很流畅,也很不准确。
那么,我该如何改进此 "scrolling" 代码或解决无法选择文本但用户仍可以滚动的 EditText
问题?
编辑:此外,用户应该仍然能够更改光标位置。
如果你想在不编辑的情况下显示任何信息,你可以使用 TextView(参见 post )而不是 Edittext,但如果你想要 EditText,请尝试使用下面的代码:
<EditText
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cursorVisible="false"
android:focusable="false"
android:inputType="textMultiLine"
android:scrollbars="vertical"
android:text="Long Text here" />
如果您想启用用户版,请使用此代码:
EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
});
}
经过更多的试验,我终于想到了一些可行的方法。
final EditText mText = (EditText) findViewById(R.id.input);
View.OnTouchListener otl = new View.OnTouchListener() {
private float scroll_down_x;
final static int right_border = 20;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
scroll_down_x = event.getX();
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + mText.getScrollX();
int offset = layout.getOffsetForHorizontal(0, x);
if(offset>0)
if(x>layout.getLineMax(0))
mText.setSelection(offset); // touch was at end of text
else
mText.setSelection(offset - 1);
break;
case MotionEvent.ACTION_MOVE:
String input = ((EditText)v).getText().toString();
float width = ((EditText) v).getPaint().measureText(input);
float cwidth = ((EditText)v).getWidth();
//only scroll when the text is too long for the control
if (width >= cwidth) {
layout = ((EditText) v).getLayout();
x = event.getX() - scroll_down_x;
scroll_down_x = event.getX();
//do not scroll over the left border
if (((EditText) v).getScrollX() + (int)x >= 0) {
//do not scroll over the right border
if ((int)cwidth+((EditText) v).getScrollX()-right_border + x <= (int)width)
{
offset = layout.getOffsetForHorizontal(0, x);
mText.scrollBy((int) x, 0);
}
else
{
mText.scrollTo((int)(width-cwidth+right_border), 0);
}
}
else
{
mText.scrollTo(0, 0);
}
}
}
return true;
}
};
此代码允许用户设置光标并滚动一行 EditText
并且它会隐藏系统键盘。
我希望它能帮助别人。如果没有更方便的方法来存档此行为,我仍然很感兴趣。
我正在尝试创建一个 EditText
,其中无法选择任何文本,但用户仍然可以浏览。
为了归档第一个函数,a 创建了一个自定义 OnTouchListener
并且只响应 ACTION_DOWN
事件,如下所示:
View.OnTouchListener otl = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
scroll_down_x = event.getX();
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + mText.getScrollX();
int offset = layout.getOffsetForHorizontal(0, x);
if(offset>0)
if(x>layout.getLineMax(0))
mText.setSelection(offset); // touch was at end of text
else
mText.setSelection(offset - 1);
break;
}
return true;
}
};
mText.setOnTouchListener(otl);
但这也会禁用滚动。然后我尝试 reimplement
ACTION_MOVE
事件
case MotionEvent.ACTION_MOVE:
String input = ((EditText)v).getText().toString();
float width = ((EditText) v).getPaint().measureText(input);
float cwidth = ((EditText)v).getWidth();
//only scroll when the text is too long for the control
if (width >cwidth )
{
layout = ((EditText) v).getLayout();
x = event.getX() - scroll_down_x;
offset = layout.getOffsetForHorizontal(0, x);
mText.scrollBy((int) x, mText.getScrollY());
}
return true;
但这根本不起作用 - 滚动不是很流畅,也很不准确。
那么,我该如何改进此 "scrolling" 代码或解决无法选择文本但用户仍可以滚动的 EditText
问题?
编辑:此外,用户应该仍然能够更改光标位置。
如果你想在不编辑的情况下显示任何信息,你可以使用 TextView(参见 post )而不是 Edittext,但如果你想要 EditText,请尝试使用下面的代码:
<EditText
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cursorVisible="false"
android:focusable="false"
android:inputType="textMultiLine"
android:scrollbars="vertical"
android:text="Long Text here" />
如果您想启用用户版,请使用此代码:
EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
});
}
经过更多的试验,我终于想到了一些可行的方法。
final EditText mText = (EditText) findViewById(R.id.input);
View.OnTouchListener otl = new View.OnTouchListener() {
private float scroll_down_x;
final static int right_border = 20;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
scroll_down_x = event.getX();
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + mText.getScrollX();
int offset = layout.getOffsetForHorizontal(0, x);
if(offset>0)
if(x>layout.getLineMax(0))
mText.setSelection(offset); // touch was at end of text
else
mText.setSelection(offset - 1);
break;
case MotionEvent.ACTION_MOVE:
String input = ((EditText)v).getText().toString();
float width = ((EditText) v).getPaint().measureText(input);
float cwidth = ((EditText)v).getWidth();
//only scroll when the text is too long for the control
if (width >= cwidth) {
layout = ((EditText) v).getLayout();
x = event.getX() - scroll_down_x;
scroll_down_x = event.getX();
//do not scroll over the left border
if (((EditText) v).getScrollX() + (int)x >= 0) {
//do not scroll over the right border
if ((int)cwidth+((EditText) v).getScrollX()-right_border + x <= (int)width)
{
offset = layout.getOffsetForHorizontal(0, x);
mText.scrollBy((int) x, 0);
}
else
{
mText.scrollTo((int)(width-cwidth+right_border), 0);
}
}
else
{
mText.scrollTo(0, 0);
}
}
}
return true;
}
};
此代码允许用户设置光标并滚动一行 EditText
并且它会隐藏系统键盘。
我希望它能帮助别人。如果没有更方便的方法来存档此行为,我仍然很感兴趣。