Android onClick méthode ne fonctionne pas sur un affichage personnalisé
J'ai commencé à travailler sur une application. - Je construire le menu d'hier, mais la onClick méthode ne fonctionne pas!
J'ai créé une classe qui étend la Vue et l'appelait MainMenuObject - cette catégorie est pour n'importe quel objet dans le menu principal (boutons, logos, etc.). J'ai créé une classe spéciale pour eux parce que je suis en train de faire une animation lorsque le menu de démarrage. Après j'ai construit le MainMenuObject classe j'ai construit une autre classe (OpeningTimesView) qui s'étend de la Vue et aura tous les boutons du menu principal, et sera fonction de l'activité principale de la mise en page.
Tout était bon, l'animation est très bien passé et je voulais mettre les auditeurs sur mes boutons, j'ai donc ajouté une mise en œuvre de l'onClickListener à la OpeningTimesView classe, et surdéfini la méthode onClick. Puis j'ai ajouté de l'auditeur sur les touches avec setOnClickListener(this) et setClickable(vrai), mais ça ne fonctionne pas! J'ai tout essayé! Merci de m'aider à comprendre ce que je fais mal. J'ai ajouté un toast à la méthode onClick qui ne s'appuie pas sur des "si", mais il ne l'affiche pas non plus.
(BTW est-il possible de définir la largeur de l'écran et de hauteur variable que toutes les classes peuvent accéder? il ne peut pas être statique, parce que vous obtenez la hauteur et la largeur d'un objet d'affichage, mais il doit y avoir une autre façon)
c'est le code:
public class OpeningTimesView extends View implements OnClickListener{
private MainMenuObjectView searchButton;
private MainMenuObjectView supportButton;
private MainMenuObjectView aboutButton;
private int screenWidth;
private int screenHeight;
public OpeningTimesView(Context context, Display dis) {
super(context);
this.screenWidth = dis.getWidth();
this.screenHeight = dis.getHeight();
searchButton = new MainMenuObjectView(context, 200, MovingMode.RIGHT, R.drawable.search, dis);
supportButton = new MainMenuObjectView(context, 400, MovingMode.LEFT, R.drawable.support, dis);
aboutButton = new MainMenuObjectView(context, 600, MovingMode.RIGHT, R.drawable.about, dis);
searchButton.setClickable(true);
supportButton.setClickable(true);
aboutButton.setClickable(true);
searchButton.setOnClickListener(this);
supportButton.setOnClickListener(this);
aboutButton.setOnClickListener(this);
}
@Override
public void onClick(View view){
Toast.makeText(getContext(), "Search button pressed", Toast.LENGTH_SHORT).show();
if(view == searchButton){
Toast.makeText(getContext(), "Search button pressed", Toast.LENGTH_SHORT).show();
}
else if(view == supportButton){
Toast.makeText(getContext(), "Support button pressed", Toast.LENGTH_SHORT).show();
}
else Toast.makeText(getContext(), "About button pressed", Toast.LENGTH_SHORT).show();
}
@Override
public void onDraw(Canvas canvas)
{
//Drawing the buttons
this.searchButton.onDraw(canvas);
this.aboutButton.onDraw(canvas);
this.supportButton.onDraw(canvas);
}
Merci d'avance, Elad!
- Veuillez consulter ce lien , je suis venu avec une solution de stackoverflow.com/questions/2826576/...
Vous devez vous connecter pour publier un commentaire.
J'ai juste eu le même Problème - j'ai créé une vue personnalisée et quand j'ai enregistré un nouveau port d'écoute dans l'activité en appelant
v.setOnClickListener(new OnClickListener() {...});
l'auditeur n'a tout simplement pas appelé.Dans mon affichage personnalisé j'ai aussi a remplacé le
public boolean onTouchEvent(MotionEvent event) {...}
méthode. Le problème était que je ne suis pas d'appeler la méthode de la classe de la Vue -super.onTouchEvent(event)
. Qui a résolu le problème. Donc, si vous vous demandez pourquoi votre auditeur n'est pas appelé, vous avez probablement oublié d'appeler la superclasse esonTouchEvent
méthodeLa création de contrôles personnalisés dans Android peut être difficile si vous n'êtes pas à l'aise avec le Framework d'INTERFACE fonctionne. Si vous ne l'avez pas déjà, je vous recommande la lecture de ces:
http://developer.android.com/guide/topics/ui/declaring-layout.html
http://developer.android.com/guide/topics/ui/custom-components.html
http://developer.android.com/guide/topics/ui/layout-objects.html
Avis que, lorsque les dispositions sont déclarées dans le fichier XML, les éléments sont imbriqués. Cela crée une mise en page de la hiérarchie que vous devez créer votre auto lors de la personnalisation d'un composant en utilisant uniquement du code Java.
Plus vous avez de chances d'être pris dans Android tactile de la hiérarchie. Contrairement à certaines autres plates-formes mobiles, Android offre les événements tactiles à partir du haut de la Vue de la hiérarchie et travaille son chemin vers le bas. Les classes qui occupent traditionnellement les niveaux supérieurs de la hiérarchie (Activité et modèles) logique dans leur vers l'avant, touche ils n'ont pas eux-mêmes consomment.
Donc, ce que je recommande de faire est de changer votre
OpeningTimesView
pour étendre unViewGroup
(la super-classe de toutes Android mises en page) ou une mise en page particulière (LinearLayout
,RelativeLayout
, etc.) et d'ajouter vos boutons comme des enfants. Maintenant, il ne me semble pas être une hiérarchie définie (les boutons ne sont pas vraiment des "contenus" dans le conteneur, ils sont tout les membres) qui peuvent être source de confusion sur la question de l'endroit où les événements sont vraiment.Choisissez une mise en page de la classe pour commencer, qui vous aidera à placer vos boutons dans leur FINAL endroits. Vous pouvez utiliser le cadre de l'animation dans Android ou code de dessin personnalisé (comme vous avez maintenant), afin de les animer, de toute façon vous le souhaitez jusqu'à ce point. L'emplacement d'un bouton et lorsque ce bouton est actuellement tiré sont autorisés à être très différente si nécessaire, et c'est ainsi que l'Animation en cours Framework fonctionne sous Android (antérieures à la version 3.0)...mais c'est une question distincte. Vous avez également
AbsoluteLayout
, qui vous permet de placer et à remplacer les objets n'importe où vous le souhaitez...mais attention à la façon dont votre application a l'air sur tous les appareils Android avec celui-ci (étant donné les différentes tailles d'écran).Quant à votre deuxième point à propos de l'affichage info.
La méthode la plus simple est probablement d'utiliser
Context.getResources().getDisplayMetrics()
partout où vous en avez besoin.Activity
hérite deContext
, de sorte qu'ils peuvent appeler cette méthode directement. Vues de toujours avoir unContext
vous pouvez accéder à lagetContext()
. Toutes les autres classes, vous pouvez simplement transmettre leContext
en tant que paramètre dans la construction (c'est un modèle courant dans Android, vous pourrez voir beaucoup d'objets nécessitent unContext
, principalement pour avoir accès àResources
).Voici un squelette exemple, pour relancer les choses. Cette juste des lignes de trois jusqu'à l'horizontale une fois, comme d'un emplacement final:
Vous pouvez la personnaliser à partir de là. Commençant peut-être les boutons de la visibilité de l'ensemble de la Vue.INVISIBLE jusqu'à ce que vous animez avec votre code de dessin ou une Animation personnalisée objet, puis de les rendre visible dans leur lieu de repos final.
La clé ici, c'est la mise en page est assez intelligent pour savoir que lorsqu'il reçoit un événement tactile il est censé transmettre à l'enfant correspondant. Vous pouvez créer une vue personnalisée sans cela, mais vous aurez à intercepter toutes les touches sur le récipient et faire le calcul pour déterminer la sous-vue manuellement avant l'événement. Si vous avez réellement ne peux pas faire de mise en page du gestionnaire de travail, c'est votre recours.
Espère que ça Aide!
Vous pouvez les appeler performClick() dans onTouchEvent de votre vue personnalisée.
D'utiliser ce que vous vue personnalisée:
Je le fais donc:
Vous devez appeler
setOnClickListener(this)
dans le constructeur(s) et de mettre en œuvreView.OnClickListener
sur de soi.De cette façon:
Mettre en œuvre les
onClickListener
dans leMainMenuObjectView
de la classe, puisque ce sont les objets qui permettront de répondre aux clics.Une autre alternative serait d'étendre
Button
au lieu deView
, parce que vous utilisez seulement les boutons làMise à jour: exemple Complet
C'est l'idée de l'implanter directement dans le cliquables points de vue. Il y a un
TestView
classe qui étend la classeView
et remplaceonDraw
, comme vous en avez besoin, et répond aussi aux clics. J'ai laissé de côté tout l'animation de la mise en œuvre que vous avez de la partie, et il n'est pas pertinent pour laClickListener
discussion.Je l'ai testé dans un Eclair de l'émulateur et il fonctionne comme prévu (un Toast message après un clic).
fichier: Test.java
fichier: TestView.java
Si vous avez besoin de quelques cliquable et certains pas cliquable, vous pouvez ajouter un constructeur avec un
argument booléen pour déterminer si le ClickListener est attaché ou non à la Vue:
MainMenuObjectView
de classe ou de prolongerButton
au lieu deView
. Mais, je n'ai pas d'Éclipse et un émulateur ici, alors je vais faire le test formel plus tard ce soir.J'ai une solution!
Ce n'est pas vraiment une solution pour ce problème spécifique, mais une toute nouvelle approche.
J'ai envoyé ce fil à quelqu'un que je connais et il m'a dit d'utiliser l'Animation SDK android a (sans Fil Dessins mentionnés), donc au lieu de faire la page du menu principal avec 4 classes, je le fais uniquement avec une classe qui étend la classe de l'Activité, et l'Animation de classe offre de nombreuses options d'animation.
Je tiens à vous remercier à la fois pour m'aider, vous êtes grand.
Je suis en ajoutant le code, si quelqu'un rencontre ce fil avec le même problème ou quelque chose:
J'ai eu le même problème. Dans mon cas, j'ai eu un LinearLayout comme un élément racine de ma vue personnalisée, avec
clickable
etfocusable
défini à true, et la vue personnalisée de la balise elle-même (utilisée dans un fragment de la mise en page) a aussi été mis àclickable
etfocusable
. S'avère que la seule chose que j'avais à faire pour obtenir ce travail était de supprimer tous lesclickable
etfocusable
attributs dans le document XML 🙂 Contre-intuitif, mais cela a fonctionné.juste ajouter
callOnClick()
à votreonTouchEvent()
méthodeDans mon cas, j'ai eu un RelativeLayout en tant que parent dans mon affichage personnalisé et la seule façon de faire ce travail était de mettre en
focusable
etclickable
àtrue
dans le RelativeLayout et dans le constructeur de la vue personnalisée, après avoir gonflé la mise en page, ajoutez ceci: