Eu quero um EditText que cria um DatePicker quando é pressionado. Então, escrevo o seguinte código:
mEditInit = (EditText) findViewById(R.id.date_init);
mEditInit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(DATEINIT_DIALOG);
}
});
Mas quando pressiono EditText, a ação é a típica: um cursor aguardando a digitação do texto mostra a caixa de diálogo que desejo.
android
android-edittext
onclicklistener
xger86x
fonte
fonte
Respostas:
O teclado parece abrir quando o EditText ganha foco. Para evitar isso, defina focalizável como falso:
<EditText ... android:focusable="false" ... />
Esse comportamento pode variar nos diferentes tipos de sistema operacional Android dos fabricantes, mas nos dispositivos que testei descobri que isso é suficiente. Se o teclado ainda aparecer, usar dicas em vez de texto também parece ajudar:
myEditText.setText("My text"); // instead of this... myEditText.setHint("My text"); // try this
Depois de fazer isso, seu ouvinte ao clicar deve funcionar conforme desejado:
myEditText.setOnClickListener(new OnClickListener() {...});
fonte
Normalmente, você deseja compatibilidade máxima com
EditText
o comportamento normal de.Portanto, você não deve usar
android:focusable="false"
porque, sim, a visualização simplesmente não será mais focalizável, o que parece ruim. O drawable de fundo não mostrará mais seu estado "pressionado", por exemplo.O que você deve fazer é o seguinte:
myEditText.setInputType(InputType.TYPE_NULL); myEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // showMyDialog(); } }); myEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { // showMyDialog(); } } });
Ao definir o tipo de entrada para
TYPE_NULL
, você evita que o teclado do software apareça.Ao definir o
OnClickListener
eOnFocusChangeListener
, você garante que sua caixa de diálogo sempre será aberta quando o usuário clicar noEditText
campo, tanto quando ele ganha o foco (primeiro clique) quanto nos cliques subsequentes.Apenas definir
android:inputType="none"
ousetInputType(InputType.TYPE_NULL)
nem sempre é suficiente. Para alguns dispositivos, você também deve definirandroid:editable="false"
em XML, embora esteja obsoleto. Se não funcionar mais, será simplesmente ignorado (como todos os atributos XML que não são suportados).fonte
EditText
componente é o único widget em seu layout, talvez? Você pode tentar adicionarandroid:focusable="true"
ao seu layout pai?Eu tenho esse mesmo problema. O código é bom, mas certifique-se de alterar o valor focalizável do EditText para false.
<EditText android:id="@+id/date" android:focusable="false"/>
Espero que isso ajude qualquer pessoa que já teve um problema semelhante!
fonte
Funcionamento padrão de
EditText
: no primeiro clique, ele foca e no segundo clique ele controla,onClickListener
então você precisa desativar o foco. Então, no primeiro clique, aonClickListener
alça será.Para fazer isso, você precisa adicionar este
android:focusableInTouchMode="false"
atributo ao seuEditText
. É isso aí!Algo assim:
<EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:focusableInTouchMode="false" android:inputType="text" />
fonte
EditText
torna-se não editável e o cursor não aparece.Aqui está a solução que implementei
mPickDate.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { showDialog(DATE_DIALOG_ID); return false; } });
OU
mPickDate.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { showDialog(DATE_DIALOG_ID); } });
Veja as diferenças por si mesmo. O problema é desde (como disse RickNotFred) TextView para exibir a data e editar através do DatePicker. O TextEdit não é usado para seu propósito principal. Se você quiser que o DatePicker reapareça, você precisa inserir delete (primeiro caso) ou desfocar (segundo caso).
Raio
fonte
Se você usar a ação OnClick em EditText como:
Java:
mEditInit = (EditText) findViewById(R.id.date_init); mEditInit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDialog(DATEINIT_DIALOG); } });
ou kotlin:
editTextChooseDate.setOnClickListener { showDialog(DATEINIT_DIALOG) }
Então, funcionará perfeitamente se você colocar em
xml
umaEditText
das seguintes linhas:Por exemplo:
<EditText android:id="@+id/date_init" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:hint="Select Date" android:inputType="none" android:focusable="false" android:cursorVisible="false"/>
ou para MaterialDesign
<com.google.android.material.textfield.TextInputLayout android:id="@+id/layoutEditTextChooseDate" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/date_init" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:hint="Select Date" android:inputType="none" android:focusable="false" android:cursorVisible="false"/> </com.google.android.material.textfield.TextInputLayout>
fonte
IMHO, discordo da declaração de RickNotFred:
Exibir uma caixa de diálogo para editar a data quando o usuário pressiona um EditText é muito semelhante ao padrão, que é exibir um teclado ou um teclado numérico. O fato de a data ser exibida com o EditText sinaliza ao usuário que a data pode ser alterada. Exibir a data como um TextView não editável sinaliza ao usuário que a data não pode ser alterada.
fonte
Bom tópico. Bem, eu fiz isso. No arquivo XML:
<EditText ... android:editable="false" android:inputType="none" />
Em código Java:
txtDay.setOnClickListener(onOnClickEvent); txtDay.setOnFocusChangeListener(onFocusChangeEvent); private View.OnClickListener onOnClickEvent = new View.OnClickListener() { @Override public void onClick(View view) { dpDialog.show(); } }; private View.OnFocusChangeListener onFocusChangeEvent = new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) dpDialog.show(); } };
fonte
O seguinte funciona perfeitamente para mim.
Primeiro, defina a entrada do widget selecionador de data como 'nenhum' para evitar que o teclado virtual seja exibido:
<EditText android:inputType="none" ... ></EditText>
Em seguida, adicione esses ouvintes de evento para mostrar a caixa de diálogo que contém o selecionador de data:
// Date picker EditText dateEdit = (EditText) findViewById(R.id.date); dateOfBirthEdit.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { showDialog(DIALOG_DATE_PICKER); } return false; } }); dateEdit.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { showDialog(DIALOG_DATE_PICKER); } else { dismissDialog(DIALOG_DATE_PICKER); } } });
Uma última coisa. Para garantir que os dias, meses ou anos digitados sejam copiados corretamente do selecionador de data, ligue
datePicker.clearFocus()
antes de recuperar os valores, por exemplo, viagetMonth()
.fonte
Isso funciona para mim:
mEditInit = (EditText) findViewById(R.id.date_init); mEditInit.setKeyListener(null); mEditInit.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus) { mEditInit.callOnClick(); } } }); mEditInit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDialog(DATEINIT_DIALOG); } });
fonte
Aqui está o que funcionou para mim
Definir editável como falso
<EditText android:id="@+id/dob" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="Date of Birth" android:inputType="none" android:editable="false"
/>
Em seguida, adicione um ouvinte de evento para OnFocusChange
private View.OnFocusChangeListener onFocusChangeDOB= new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus){ showDialog(DATE_DIALOG_ID); } } };
fonte
Como sugeriu Dillon Kearns, definir focalizável como falso funciona bem. Mas se o seu objetivo é cancelar o teclado quando EditText é clicado, você pode querer usar:
mEditText.setInputType(0);
fonte
Por que ninguém mencionou
setOnTouchListener
? UsarsetOnTouchListener
é fácil e correto, e apenas retornar verdadeiro se o ouvinte tiver consumido o evento, falso caso contrário.fonte
O problema com as soluções que usam OnFocusChangeListener é que elas interpretam qualquer ganho de foco como um clique. Isso não é 100% correto: seu EditText pode ganhar foco de outra coisa que não um clique.
Se você se preocupa estritamente com o clique e deseja detectá-lo de forma consistente (independentemente do foco), você pode usar
GestureDetector
:editText.setOnConsistentClickListener { /* do something */ } fun EditText.setOnConsistentClickListener(doOnClick: (View) -> Unit) { val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() { override fun onSingleTapUp(event: MotionEvent?): Boolean { doOnClick(this@setOnConsistentClickListener) return false } }) this.setOnTouchListener { _, motionEvent -> gestureDetector.onTouchEvent(motionEvent) } }
fonte