Intereting Posts
CreateNewFile – open failed: ENOENT (Нет такого файла или каталога) Android – Как передать HashMap <String, String> между действиями? Android: в чем разница между разрешением и плотностью? Обходной путь для операций с файлами Nitex для SQL-файлов Nexus 9 на внешних серверах? Android EditText, минус, преобразованный в точечное событие, но inputType = "number | numberSigned | numberDecimal" О «init: untracked pid xxxx exited» в Genymotion Как обновить град в студии Android Android: получите текущее местоположение от лучшего поставщика Определение текущего приложения переднего плана из фоновой задачи или службы Как я могу расширить CardViews, чтобы показать больше деталей, таких как карты Google Keep? Много GC при прокрутке ListView (с шаблоном держателя) Импорт Facebook SDK на Android Studio 0.5.1 Почему GoogleMap.animateCamera () падает после onGlobalLayout ()? Вложенный внутренний класс активности в android Как создать приложение Extjs, которое работает на iPhone, iPad и Android?

Поместить постоянный текст внутри EditText, который должен быть не редактируемый – Android

Я хочу иметь постоянный текст внутри 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) : ""; } } }); 

Но я не знаю, ограничивает ли он пользователя не удалять символы с начала до конца . Я также не мог понять использование Spanned class.

Один из способов был бы хорошим выбором, если мы можем поместить TextView внутри EditText но я не думаю, что это возможно в Android, так как оба являются Views, возможно ли это?

Solutions Collecting From Web of "Поместить постоянный текст внутри EditText, который должен быть не редактируемый – Android"

Вы пробовали этот метод?

 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().contains("http://")){ edt.setText("http://"); Selection.setSelection(edt.getText(), edt.getText().length()); } } }); 

Проблема с ответом @ 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()); } } 

Примечание: это не относится к случаю, когда пользователь пытается отредактировать сам префикс только до и после.

Вот как вы можете это сделать с помощью 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); 

У вас это было почти правильно, попробуйте

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

Используйте этот пользовательский 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(); } } 

Это менее эффективное решение, которое должно обрабатывать все случаи, когда символы ИЛИ слова удаляются / вставлены в OR вокруг префикса.

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

Я знаю, что обновляю старый пост, но хочу поделиться с сообществом тем, что в эти дни я боролся с этой темой, и я обнаружил, что размещение 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 свойства android:paddingStart для EditText , чтобы текст начинался сразу после TextView , в то время как android:layout_centerVertical="true" и android:layout_marginStart="3dp" TextView гарантировали, что его Текст правильно выровнен с введенным текстом и с началом базовой строки EditText (или, по крайней мере, это происходит при использовании тематического материала Material).