我想有恒定的文本中EDITTEXT喜欢:
http://<here_user_can_write>
用户应该能够从删除任何字符“ http://
”,我搜索了这件事,发现这一点:
editText.setFilters(new InputFilter[] {
new InputFilter() {
public CharSequence filter(CharSequence src, int start,
int end, Spanned dst, int dstart, int dend) {
return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
}
}
});
但我不知道是否会限制用户不删除任何字符从开始到结束的限制。 我也弄不明白使用跨区类。
一种方式是一个不错的选择,如果我们可以把一个TextView
内EditText
,但我不认为这是可能在Android中,因为两者都是意见,这可能吗?
Answer 1:
难道ü尝试这种方法吗?
final EditText edt = (EditText) findViewById(R.id.editText1);
edt.setText("http://");
Selection.setSelection(edt.getText(), edt.getText().length());
edt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
if(!s.toString().startsWith("http://")){
edt.setText("http://");
Selection.setSelection(edt.getText(), edt.getText().length());
}
}
});
Answer 2:
那怎么你其实可以用做InputFilter
:
final String prefix = "http://"
editText.setText(prefix);
editText.setFilters(new InputFilter[] {
new InputFilter() {
@Override
public CharSequence filter(final CharSequence source, final int start,
final int end, final Spanned dest, final int dstart, final int dend) {
final int newStart = Math.max(prefix.length(), dstart);
final int newEnd = Math.max(prefix.length(), dend);
if (newStart != dstart || newEnd != dend) {
final SpannableStringBuilder builder = new SpannableStringBuilder(dest);
builder.replace(newStart, newEnd, source);
if (source instanceof Spanned) {
TextUtils.copySpansFrom(
(Spanned) source, 0, source.length(), null, builder, newStart);
}
Selection.setSelection(builder, newStart + source.length());
return builder;
} else {
return null;
}
}
}
});
如果你也想前缀是不可选的,你可以添加以下代码。
final SpanWatcher watcher = new SpanWatcher() {
@Override
public void onSpanAdded(final Spannable text, final Object what,
final int start, final int end) {
// Nothing here.
}
@Override
public void onSpanRemoved(final Spannable text, final Object what,
final int start, final int end) {
// Nothing here.
}
@Override
public void onSpanChanged(final Spannable text, final Object what,
final int ostart, final int oend, final int nstart, final int nend) {
if (what == Selection.SELECTION_START) {
if (nstart < prefix.length()) {
final int end = Math.max(prefix.length(), Selection.getSelectionEnd(text));
Selection.setSelection(text, prefix.length(), end);
}
} else if (what == Selection.SELECTION_END) {
final int start = Math.max(prefix.length(), Selection.getSelectionEnd(text));
final int end = Math.max(start, nstart);
if (end != nstart) {
Selection.setSelection(text, start, end);
}
}
}
};
editText.getText().setSpan(watcher, 0, 0, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
Answer 3:
有与@Rajitha Siriwardena的回答一个小问题。 它假定除了后缀以外的整个字符串已被删除之前,如果您有字符串的后缀意思
http://stackoverflow.com/
并尝试删除的任何部分http://
你会删除stackoverflow.com/
导致只有http://
。
我还添加了检查柜面用户尝试输入前缀之前。
@Override
public void afterTextChanged(Editable s) {
String prefix = "http://";
if (!s.toString().startsWith(prefix)) {
String cleanString;
String deletedPrefix = prefix.substring(0, prefix.length() - 1);
if (s.toString().startsWith(deletedPrefix)) {
cleanString = s.toString().replaceAll(deletedPrefix, "");
} else {
cleanString = s.toString().replaceAll(prefix, "");
}
editText.setText(prefix + cleanString);
editText.setSelection(prefix.length());
}
}
注意:当用户试图只有前后编辑前缀这本身不处理的情况。
Answer 4:
代码中添加自定义前缀为您EDITTEXT(PREFIX不可编辑)
从阿里·穆扎法尔介质中的代码
public class PrefixEditText extends AppCompatEditText {
float originalLeftPadding = -1;
public PrefixEditText(Context context) {
super(context);
}
public PrefixEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PrefixEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
calculatePrefix();
}
private void calculatePrefix() {
if (originalLeftPadding == -1) {
String prefix = (String) getTag();
float[] widths = new float[prefix.length()];
getPaint().getTextWidths(prefix, widths);
float textWidth = 0;
for (float w : widths) {
textWidth += w;
}
originalLeftPadding = getCompoundPaddingLeft();
setPadding((int) (textWidth + originalLeftPadding),
getPaddingRight(), getPaddingTop(),
getPaddingBottom());
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String prefix = (String) getTag();
canvas.drawText(prefix, originalLeftPadding, getLineBounds(0, null), getPaint());
}
}
和XML
<com.yourClassPath.PrefixEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textSize="14sp"
android:tag="€ " />
Answer 5:
你有它差不多吧,试试
private final String PREFIX="http://";
editText.setFilters(new InputFilter[]{new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int
dend) {
return dstart<PREFIX.length()?dest.subSequence(dstart,dend):null;
}
}});
Answer 6:
从阿里·穆扎法尔的博客取,看到原来的岗位了解更多详情。
使用自定义EditText
查看根据前缀文字大小来绘制前缀文字并添加填充:
public class PrefixEditText extends EditText {
private String mPrefix = "$"; // add your prefix here for example $
private Rect mPrefixRect = new Rect(); // actual prefix size
public PrefixEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
getPaint().getTextBounds(mPrefix, 0, mPrefix.length(), mPrefixRect);
mPrefixRect.right += getPaint().measureText(" "); // add some offset
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(mPrefix, super.getCompoundPaddingLeft(), getBaseline(), getPaint());
}
@Override
public int getCompoundPaddingLeft() {
return super.getCompoundPaddingLeft() + mPrefixRect.width();
}
}
Answer 7:
我知道我恢复旧的文章,但我想,我已经跟这个话题这些天奋斗社会各界分享,我发现放置TextView
在EditText
,不仅完全可行的(对的第二部分回应问题),在这种情况下更加当需要在起始位置的恒定文本,但优选的,太。 此外,光标不会,即使在所有的“可变”的文字,这是一个优雅的效果之前移动。 我喜欢这种解决方案,因为它不会增加工作量和复杂性,以我的应用程序与听众和任何责任。
这里是我的解决方案的示例代码:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="3dp"
android:text="http://" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textUri"
android:paddingStart="choose an appropriate padding" />
</RelativeLayout>
通过封闭的意见RelativeLayout
,他们会重叠。 这里的技巧是玩的android:paddingStart
属性的EditText
,使文字开始只是右后TextView
,而android:layout_centerVertical="true"
和android:layout_marginStart="3dp"
的属性TextView
确保其文本被正确地输入的文本和与所述的基本行的开始对齐EditText
(使用材料主题之一,当或至少发生这种情况)。
Answer 8:
这一个是基本上前缀“+91”添加到的电话号码,您的编辑文本字段。
1.增加此代码的OnCreate()活性的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
// Write other things......//
etPhoneNumber.setFilters(new InputFilter[]{getPhoneFilter(),newInputFilter.LengthFilter(13)});
etPhoneNumber.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
if (etPhoneNumber.getText().toString().isEmpty()) {
etPhoneNumber.setText("+91");
Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length()); }
} else {
if (etPhoneNumber.getText().toString().equalsIgnoreCase("+91")) {
etPhoneNumber.setFilters(new InputFilter[]{});
etPhoneNumber.setText("");
etPhoneNumber.setFilters(new InputFilter[]{getPhoneFilter(),new InputFilter.LengthFilter(13)});
}
}
}
});
}
2.Declare被叫getPhoneFilter()的方法
private InputFilter getPhoneFilter() {
Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length());
etPhoneNumber.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
if(!s.toString().startsWith("+91")){
if (etPhoneNumber.getFilters() != null && etPhoneNumber.getFilters().length > 0) {
etPhoneNumber.setText("+91");
Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length());
}
}
}
});
// Input filter to restrict user to enter only digits..
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!String.valueOf(getString(R.string.digits_number)).contains(String.valueOf(source.charAt(i)))) {
return "";
}
}
return null;
}
};
return filter;
}
在你的价值观文件3.declare“digits_number”
<string name="digits_number">1234567890+</string>
Answer 9:
下面是应该处理所有情况下,当字符或单词被删除/插入或周围的前缀一个不太有效的解决方案。
prefix = "http://"
extra = "ahhttp://"
differencePrefix(prefix, extra) = "aht"
码:
public static String differencePrefix(String prefix, String extra) {
if (extra.length() < prefix.length()) return "";
StringBuilder sb = new StringBuilder();
StringBuilder eb = new StringBuilder();
int p = 0;
for (int i = 0; i < extra.length(); i++) {
if (i >= prefix.length()) {
while(p < extra.length()) {
eb.append(extra.charAt(p));
p++;
}
break;
}
if (p >= extra.length()) break;
char pchar = extra.charAt(p);
char ichar = prefix.charAt(i);
while(pchar != ichar) {
//check if char was deleted
int c = i + 1;
if (c < prefix.length()) {
char cchar = prefix.charAt(c);
if (cchar == pchar) {
break;
}
}
sb.append(pchar);
p++;
if (p >= extra.length()) break;
pchar = extra.charAt(p);
}
p++;
}
return eb.toString() + sb.toString();
}
您可以使用它像这样
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String input = s.toString();
if (!input.startsWith(prefix)) {
String extra = differencePrefix(prefix, input);
String newInput = prefix + extra;
editText.setText(newInput);
editText.setSelection(newInput.length());
}
}
});
Answer 10:
我只是找到了解决办法如何使前缀不是编辑,以及如何,如果你尝试删除前缀保存文本。 这是非常接近@Rajitha Siriwardena答案。 你错过了所有的应用进行任何更改之前保存的文本。 它将afterTextChanged(...)来恢复。
码:
final String prefix = "http://";
editText.setText(prefix);
Selection.setSelection(editText.getText(), editText.getText().length());
editText.addTextChangedListener(new TextWatcher() {
String text;
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
text = charSequence.toString();
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if (!editable.toString().startsWith(prefix)) {
editText.setText(text);
Selection.setSelection(editText.getText(), editText.getText().length());
}
}
});
Answer 11:
EditText msg=new EditText(getContext());
msg.setSingleLine(true);
msg.setSingleLine();
msg.setId(View.generateViewId());
msg.measure(0,0);
TextView count=new TextView(getContext());
count.setTextColor(Color.parseColor("#666666"));
count.setText("20");
count.setPadding(0,0,(int)Abstract.getDIP(getContext(),10),0);
count.measure(0,0);
float tenPIX =TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,getContext().getResources().getDisplayMetrics());
msg.setPadding((int)tenPIX,(int)tenPIX,(int)(int)tenPIX+count.getMeasuredWidth(),(int)tenPIX);
RelativeLayout ll1=new RelativeLayout(getContext());
ll1.addView(msg,new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
LayoutParams countlp=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
countlp.addRule(RelativeLayout.ALIGN_END,msg.getId());
countlp.addRule(RelativeLayout.ALIGN_BASELINE,msg.getId());
ll1.addView(count,countlp);
Answer 12:
下面的代码为我工作。 当用户编辑前缀,删除它,从缓冲区中插入文本,改变所选文本它处理的案件。 如果用户更改前缀,将焦点移到前缀的结束。
final String prefix = "http://";
final String[] aLastText = {prefix};
et.setText(prefix);
et.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable sNew) {
if (!sNew.toString().startsWith(prefix)) {
String sLast = aLastText[0];
boolean isRemoving = sNew.length() < sLast.length();
int start;
int end = sNew.length() - 1;
for (start = 0; start < sLast.length() && start < sNew.length(); start++) {
if (sLast.charAt(start) != sNew.charAt(start))
break;
}
int k = sLast.length() - 1;
for (; end >= start && k >= 0; end--, k--) {
if (sLast.charAt(k) != sNew.charAt(end))
break;
}
String sEdited = sNew.toString().substring(start, ++end);
k += isRemoving ? 1 : 0;
k = k < prefix.length() ? prefix.length() : k;
String sSuffix = sLast.substring(k, sLast.length());
et.setText(prefix + sEdited + sSuffix);
et.setSelection(et.getText().length() - sSuffix.length());
}
aLastText[0] = et.getText().toString();
}
});
例子:
ht5tp://本地主机,5http://本地主机,HTTP:/ 5 /本地主机- > 的http:// 5localhost
HTTP:本地主机- > HTTP://本地主机
文章来源: Put constant text inside EditText which should be non-editable - Android