2010-03-01 8 views
55

Je veux un EditText qui crée un DatePicker quand on appuie dessus. Alors j'écris le code suivant:Android EditText onClickListener

mEditInit = (EditText) findViewById(R.id.date_init); 
    mEditInit.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      showDialog(DATEINIT_DIALOG); 
     } 

    }); 

Mais quand je presse la EditText l'action est typique: un curseur d'attente pour la saisie de texte plutôt montrer la boîte de dialogue que je veux.

Une idée?

Merci

+0

Vous devez utiliser une fileuse au lieu d'un dialogue EditText. –

Répondre

14

Voici la solution que je mis en œuvre

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

    } 
}); 

Voir les différences par vous-même. Le problème est depuis (comme RickNotFred dit) TextView pour afficher la date & éditer via le DatePicker. TextEdit n'est pas utilisé pour son objectif principal. Si vous souhaitez que le DatePicker s'affiche à nouveau, vous devez entrer la suppression (1er cas) ou la mise au point (2ème cas).

Ray

+1

sauf si vous ajoutez un onClickListener que je viens de faire avec un onFocusChangeListener. Cela fonctionnera :-) – neteinstein

8

à mon humble avis, je suis en désaccord avec la déclaration de RickNotFred:

Popping une boîte de dialogue lorsqu'une EditText se accent semble être une interface non standard .

Affichage d'une boîte de dialogue pour modifier la date à laquelle l'utilisation d'un appuie sur la EditText est très similaire à la valeur par défaut, ce qui est d'afficher un clavier ou un pavé numérique. Le fait que la date s'affiche avec EditText signale à l'utilisateur que la date peut être modifiée. L'affichage de la date en tant que TextView non modifiable signale à l'utilisateur que la date ne peut pas être modifiée.

106

Le clavier semble apparaître lorsque l'EditText est activé. Pour éviter cela, réglez focusable false:

<EditText 
    ... 
    android:focusable="false" 
    ... /> 

Ce comportement peut varier en fonction des différentes saveurs OS Android du fabricant, mais sur les appareils j'ai testé je l'ai trouvé que cela soit suffisant. Si le clavier apparaît toujours en place, à l'aide des notes plutôt que du texte semble aider aussi:

myEditText.setText("My text"); // instead of this... 
myEditText.setHint("My text"); // try this 

Une fois que vous avez fait cela, votre clic sur l'auditeur devrait fonctionner comme vous le souhaitez:

myEditText.setOnClickListener(new OnClickListener() {...}); 
+0

Cela semble fonctionner, mais lorsque vous tapez un champ, et cliquez sur Suivant sur le clavier, il passe le champ avec focusable sur false. –

2

Comme Dillon Kearns a suggéré de mettre l'accent sur les fausses œuvres. Mais si votre objectif est d'annuler le clavier lorsque EditText est cliqué, vous voudrez peut-être utiliser:

mEditText.setInputType(0); 
6

Les œuvres suivantes parfaitement pour moi.

d'abord définir l'entrée de votre widget sélecteur de date « none » pour empêcher le clavier mou de sauter vers le haut:

<EditText android:inputType="none" ... ></EditText> 

ajouter ensuite ces écouteurs d'événements pour afficher la boîte de dialogue contenant le sélecteur de date:

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

Une dernière chose. Pour vous assurer que les dates, mois ou années saisis sont correctement copiés à partir du sélecteur de date, appelez le datePicker.clearFocus() avant d'extraire les valeurs, par exemple via getMonth().

+0

C'est sympa, mais parfois j'ai des dialogues en double. – Maxrunner

+0

Correctif simple: Ne rejette pasDialog avant chaque showDialog, juste pour être sûr. –

30

J'ai eu le même problème. Le code est correct mais assurez-vous que vous modifiez la valeur focusable de EditText à false. J'espère que ceci aide n'importe qui qui a eu un problème semblable!

+0

Ceci est une très belle une solution facile :) – Warpzit

+0

un beau Yusuf, un up vote pour vous;) –

+4

Aussi ne pas définir enabled = "false", qui va désactiver onClickListener – OatsMantou

3

Voici ce qui a fonctionné pour moi

Set modifiable false

<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" 

/>

Ensuite, ajoutez un écouteur d'événement pour OnFocusChange

private View.OnFocusChangeListener onFocusChangeDOB= new View.OnFocusChangeListener() { 

@Override 
public void onFocusChange(View v, boolean hasFocus) { 
    if (hasFocus){ 
    showDialog(DATE_DIALOG_ID); 
    } 
} 
}; 
+3

Méfiez-vous des téléphones Motorola en cours d'exécution Android 2.3.x. Si EditText se trouve quelque part dans une zone de défilement, Motorola déplacera automatiquement la mise au point lorsque vous faites défiler la page. Cela signifie que vous pouvez faire défiler vers le bas et lorsque l'EditText gagne en focus, votre boîte de dialogue date, ce qui est surprenant et mauvais. –

37

Normalement, vous voulez un maximum compatibilité avec le comportement normal de EditText.

Donc vous devriez pas utiliser android:focusable="false" comme, oui, la vue ne sera plus focalisable ce qui semble mauvais. L'arrière-plan dessinable ne montrera plus son état "pressé", par exemple.

Ce que vous devez faire à la place est la suivante:

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

En définissant le type d'entrée à TYPE_NULL, vous empêchez le clavier logiciel de sauter vers le haut.

En définissant la OnClickListener et OnFocusChangeListener, vous assurez-vous que votre boîte de dialogue sera toujours ouvert lorsque l'utilisateur clique dans le champ EditText, aussi bien quand il obtient le focus (premier clic) et sur les clics suivants.

Le simple réglage android:inputType="none" ou setInputType(InputType.TYPE_NULL) n'est pas toujours suffisant. Pour certains périphériques, vous devez également définir android:editable="false" en XML, même s'il est obsolète. Si cela ne fonctionne plus, il sera simplement ignoré (comme tous les attributs XML qui ne sont pas supportés).

+3

solution parfaite, devrait être la réponse acceptée – leoderprofi

+0

Lorsque je fais cela, la boîte de dialogue se rouvre après la fermeture parce que l'edittext gagne à nouveau le focus. De toute façon autour de cela? – AdamMc331

+0

@ McAdam331 Ce composant 'EditText' est-il le seul widget de votre mise en page, peut-être? Pouvez-vous essayer d'ajouter 'android: focusable =" true "' à votre mise en page parente? – caw

5

Beau sujet. Eh bien, je l'ai fait. Dans le fichier XML:

<EditText 
    ... 
    android:editable="false" 
    android:inputType="none" /> 

En Java code:

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

Pourquoi personne ne mentionne setOnTouchListener? L'utilisation de setOnTouchListener est facile et correcte, et renvoie simplement true si l'écouteur a consommé l'événement, false dans le cas contraire.

1

Cela fonctionne pour moi:

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

}); 
+1

Ça marche aussi pour moi! Je vous remercie. –

6

travail par défaut de EditText: Au premier clic, il se concentre et second clic il gère onClickListener de sorte que vous devez désactiver le focus. Puis, au premier clic, le onClickListener va gérer. Pour cela, vous devez ajouter cet attribut android:focusableInTouchMode="false" à votre EditText. C'est tout!

Quelque chose comme ceci:

<EditText 
     android:id="@+id/editText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:focusableInTouchMode="false" 
     android:inputType="text" />