2009-03-18 2 views
39

В макете вы можете установить виджет EditText, чтобы он был недоступен для редактирования через android:editable attribute.Как реплицировать android: editable = "false" в коде?

Как это сделать в коде? Мне нужно сделать виджет EditText доступным для редактирования в зависимости от условий.

ответ

12

Я думаю, InputFilter, что отвергает все изменения является хорошим решением:

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

Edit: dlazar предложил (ниже), чтобы изменить return к dst.subSequence(dstart, dend) в преодолевать поведение, которое удаляет слова.

+1

Это не работает должным образом. В этом решении, когда вы нажимаете на правильное предложение слова, выбранное слово удаляется. – Augiwan

+0

не удалось проверить это atm, но похоже, что @dlazar уже распознал эту проблему и предложил решение - добавлено это к ответу –

+0

Можно ли сделать наоборот? (Сделайте editText EDITABLE) –

3

Я не вижу связанного метода для этого атрибута в классе EditText . Тем не менее, есть и другие подобные вещи, которые вы могли бы использовать, например android:focus/setFocusable(boolean) или создать еще один TextView, android:editable="false" и использовать setVisiblilty() для переключения между редактируемые и доступные для редактирования виды. Если вы используете View.GONE, пользователь будет никогда не знать, что есть два EditTexts.

Если вы чувствуете амбициозность, вы, вероятно, можете что-то сделать с прослушивателем onTextChanged EditText, как с его реакцией на setText.

+0

Учитывая слоеный характер KeyListeners (относительно мягкой клавиатуры), я был обескуражен от баловаться с теми или редактировать свойства текста. Я считаю это самым надежным ответом. – stephen

3

Вы пытались setText(java.lang.CharSequence, android.widget.TextView.BufferType)? Он описывается как:

Устанавливает текст, который этот TextView должен показать (см SetText (CharSequence)), а также устанавливает, является ли она хранится в styleable/spannable буфера и будет ли он доступен для редактирования.

(курсив мой)

+0

Спасибо за усилия, но я просто попробовал, и это не имеет никакого значения. Кроме того, нет никакой документации о том, что означает значения перечисления. – AngryHacker

3

[Публикация нового ответа, так как я не могу прокомментировать ответ Иосифа.]

Входной фильтр работает нормально, но она имеет тонкую ошибку в нем: набрав над выбором будет удалить весь текст.

Например, у вас есть текст "foo" в EditText. Если вы выберете все (например, дважды щелкнув по нему) и введите 'a', текст исчезнет. Это происходит потому, что InputFilter будет называться:

filter("a", 0, 1, "foo", 0, 3); 

Предлагаемый входной фильтр возвращает пустую строку в этом случае (поскольку src.length() < 1 является false), что объясняет недостающий текст.

Решение состоит в том, чтобы просто вернуть dst.subSequence(dstart, dend) в функцию фильтра. Это будет нормально работать даже для удаления.

37
editText.setFocusable(false); 
editText.setClickable(false); 

это обеспечить контроль EditText не может быть выбран и сосредоточенный, поэтому он не может быть изменен.

+10

Но его также нельзя выбрать и скопировать. –

-1

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

mEditView.setText("my text", BufferType.NORMAL); 

Если вы хотите, чтобы переключаться между редактируемым и не редактируемыми вы можете сделать следующее:

// Switch to non-editable 
mEditView.setText(mEditView.getText(), BufferType.NORMAL); 

// Switch back to editable 
mEditView.setText(mEditView.getText(), BufferType.EDITABLE); 
+0

это вообще не работает – JediPotPie

+0

Попробуйте вместо этого заменить mEditView.getText() на toString() и посмотреть, работает ли это. Я думаю, что это может сработать для вас. – kcoppock

+0

Я думаю, что это влияет только на буфер, и это не делает поле в ui неизменным, так как я предполагаю, что он просто будет содержать неизменяемый буфер, который будет отброшен, если будут какие-либо изменения. – Timo

15

Лучшим способом для этого используется одна единственная строка кода:

textView.setKeyListener(null); 

Документы говорят по этому методу:

Устанавливает прослушиватель клавиш, который будет использоваться с этот TextView. Это может быть от нуля до . Запретить ввод пользователя.

+1

Это может сработать, но что, если вам нужно переключаться между редактируемыми и нередактируемыми из-за некоторых критериев? Вам нужно будет создать свой собственный KeyListener, чтобы вернуть его в редактируемое, что кажется неправильным. – John

+0

Имеет другие побочные эффекты, например, убийство для копирования. –

+0

Предлагаемый Кристофер должен работать. Это позволяет вам выбирать и копировать текст из поля точно так же, как если бы вы определили поле, не редактируемое из xml (я не знаю, о чем говорит Джеймс, но он отлично работает, по крайней мере, на Android 2.2). Глядя на исходный код, это в значительной степени то, что сделано, когда атрибут xml enabled установлен в false для любого TextView. В соответствии с документацией вам может потребоваться вызвать setFocusable (true) после вызова setKeyListener (null). – Timo

1

Я хотел бы также указать альтернативное решение, которое прекрасно работает, если вы создаете новые экземпляры EditView. Вы можете переопределить метод getDefaultEditable(), предложенный документами для возврата false. Например.

EditText view = new EditText(DiscountCalculator.this) { 
    public boolean getDefaultEditable() { 
     return false; 
    } 
}; 
23

Я просто попытался это сам,

Чтобы отключить редактирования текста:

.setFocusable(false); 

это также устанавливает setFocusableInTouchMode ложь!

Для включения редактирования текста:

setFocusableInTouchMode(true); 

это также устанавливает setFocusable истина;

+0

Это сработало. Благодаря! – Mauker

+0

Это лучший ответ по мне. Благодарю . –

6
android:editable="false" 
android:inputType="none" 

в вашем XML или

EditText mEdit = (EditText) findViewById(R.id.yourid); 
mEdit.setEnabled(false); 

или

EditText mEdit = (EditText) findViewById(R.id.yourid); 
mEdit.setKeyListener(null); 
0

Единственное решение, которое я нашел для этого сценария является создание 2 макетов. Один из них доступен для редактирования, а другой нет. Возможно, вам придется создать более 2 макетов на основе различных условий. Сохраните условия в SharedPreferences или других средствах и загрузите соответствующий макет на основе условий после перезапуска Activity. Вот пример:

в OnCreate() деятельности:

configuration = new Configuration(this.getSharedPreferences(Configuration.SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE)); 
    manualSettingsMode = configuration.isManualSettingsMode(); 
    if(manualSettingsMode){ 
     setContentView(R.layout.editableconfigurationsettings); 
    }else { 
     setContentView(R.layout.configurationsettings); 
    } 

Активность может быть перезапущена на основе тестирования состояния и вызов функций, как:

private void setManualEditing(){ 
    configuration.set_isManualSettingsMode(true); 
    this.recreate(); 
} 

private void setAutoEditing(){ 
    configuration.set_isManualSettingsMode(false); 
    this.recreate(); 
} 

Надеется, что это помогает. Там действительно должно быть лучшее решение, но это то, что я делал. В идеале можно было бы сделать это на отдельных полях и не перезагружать активность/макеты.-bobby

4

Вы можете попробовать это:

 mEditText.setFocusable(false); 
     mEditText.setClickable(false); 
     mEditText.setFocusableInTouchMode(false); 
     mEditText.setLongClickable(false); 
     mEditText.setInputType(InputType.TYPE_NULL); 

Это будет полностью отключить EditText, отключить длительное нажатие, если вы не хотите пользователю открыть изменить параметры текста.

1

Я думаю

Edittext.setEnabled(false); 

через код

и

android:enabled="false" 

через xml.Also проверить этот пост на SO.

Они должны работать, и вы можете снова включить программно Edittext.setEnabled(true);

+0

Я не хочу брать на себя ответственность за этот ответ, я просто сделал исправление, которое было необходимо, чтобы заставить его работать, хорошо. В rails в моем коде идентификатор текста и выпадающего автоматически генерируется, и они одинаковы, поэтому мне нужно добавлять классы и сравнивать с помощью класса, ума, его ... даже если я новичок, мне не нужны кредиты другие .... Я комментирую здесь, поскольку у меня нет другого способа связаться с вами, спасибо вам. http://stackoverflow.com/a/34760933/5239247 –

-1

попробовать это:

mEditText.setFilters(new InputFilter[]{new InputFilter() { 
     @Override 
     public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
      if (XXX) { 
       return ""; 
      } else { 
       return null; 
      } 
     } 
    }}); 
+3

Не могли бы вы добавить некоторые детали? – mrun

Смежные вопросы