Bouton de forme personnalisée Android

Comment puis-je créer une vue ou un bouton cliquable de forme personnalisée dans Android?

Lorsque je clique, je veux éviter de toucher une zone vide.

entrer la description de l'image ici

s’il vous plaît aider. Je vous remercie.

Question interessante. J’ai essayé des solutions et c’est ce que j’ai trouvé qui a le même résultat que ce que vous essayez de réaliser. La solution ci-dessous résout 2 problèmes:

  1. Forme personnalisée telle que vous l’avez présentée
  2. Le côté supérieur droit du bouton ne doit pas être cliquable

Voici donc la solution en 3 étapes:

Étape 1

Créez deux formes.

  • Première forme de rectangle simple pour le bouton: shape_button_beer.xml

          
  • La deuxième forme est utilisée comme masque pour la partie supérieure droite du bouton: shape_button_beer_mask.xml . C’est un cercle simple avec une couleur unie noire.

         

Étape 2

Dans votre mise en page principale, ajoutez le bouton par l’approche suivante:

  • RelativeLayout est le conteneur de ce bouton personnalisé
  • Le premier LinearLayout est le bouton bleu avec l’icône de la bière et le texte à l’intérieur
  • Deuxième ImageView est le masque au-dessus du bouton bleu. Et voici le sale tour:
    1. Les marges sont négatives pour placer le masque au bon endroit
    2. Nous définissons id pour pouvoir remplacer le clic (voir étape 3)
    3. android:soundEffectsEnabled="false" – tel que l’utilisateur ne sentira pas qu’il a appuyé sur quelque chose.

Le XML:

            

Étape 3

Dans votre activité principale, vous définissez les événements click pour les deux: button et le masque comme suit:

 LinearLayout customButton = (LinearLayout) findViewById(R.id.custom_buttom); customButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getApplicationContext(), "Clicked", Toast.LENGTH_SHORT).show(); } }); // Mask on click will do nothing ImageView doNothing = (ImageView) findViewById(R.id.do_nothing); doNothing.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // DO NOTHING } }); 

C’est tout. Je sais que ce n’est pas une solution parfaite, mais dans votre cas d’utilisation décrit, cela pourrait aider. Je l’ai testé sur mon mobile et c’est comme ça que vous cliquez lorsque vous cliquez sur la zone bleue et que rien ne se passe sur d’autres zones:

  • entrer la description de l'image ici

J’espère que ça a aidé en quelque sorte 🙂

Utilisez OnTouch au lieu d’OnClick et vérifiez la valeur alpha de l’image que vous avez utilisée dans le bouton. Si ce n’est pas égal à zéro, faites ce que vous voulez. Vérifiez le code suivant,

 final Bitmap bitmap; //Declare bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.TheImage); public boolean onTouch(View v, MotionEvent event) { int eventPadTouch = event.getAction(); float iX=event.getX(); float iY=event.getY(); switch (eventPadTouch) { case MotionEvent.ACTION_DOWN: if (iX>=0 & iY>=0 & iX 

Vous pouvez essayer celui-ci:

   

et créer un fichier round.xml dans un dossier pouvant être dessiné:

        

utiliser la couche-liste, vous pouvez concevoir n’importe quelle forme tous les boutons de dégradé ici est exemple

                  

utiliser les valeurs de rayon -ve pour créer la forme du bouton comme indiqué

J’ai eu un problème similaire mais je ne voulais pas dépendre du code pour examiner la valeur du pixel. Je voulais un moyen simple (pas de surcharge de classe) pour contraindre un événement tactile à une sous-partie d’un dessinable. Ci-dessous j’utilise un LinearLayout pour le dessinable et ensuite à l’intérieur que je mets un bouton transparent (avec du texte). Je peux ajuster la marge du bouton pour positionner la zone cliquable.

     

La solution la meilleure et la plus simple (as4me) que j’ai trouvée ici – elle est sous- classée Button et supporte donc le sélecteur. Donc, tout ce que vous devez faire est de dessiner / append des pngs correspondants pour chaque état du bouton pour utiliser le sélecteur et déclarer onClick dans xml ou append OnClickListener dans le code et vous êtes prêt à partir.

Plutôt que de faire toutes ces modifications, vous devez utiliser la disposition des frameworks dans la partie entourant le bouton et masquer la partie supérieure droite avec un élément (circulaire, comme un bouton arrondi) et atsortingbuer un écouteur sans clic à cette partie. Cela masque en effet le cadre inférieur (c.-à-d. Votre bouton d’origine) et le masque avec la partie non active.

J’ai essayé la réponse par @Basim Sherif ( lien ) et cela fonctionne très bien seulement si la taille du bouton est la même que l’image originale. Si le bouton était tendu, la région cliquable serait plus petite et si la taille du bouton était inférieure, la région cliquable serait plus grande que le bouton actuel.

La solution est simple: mettre à l’échelle les valeurs iX et iY pour qu’elles correspondent à l’image bitmap d’origine.

Et voici ma version modifiée du code:

 final Bitmap bitmap; //Declare bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.TheImage); public boolean onTouch(View v, MotionEvent event) { int eventPadTouch = event.getAction(); float iX=event.getX(); float iY=event.getY(); // Get the dimensions used in the view int realW = this.getWidth(); int realH = this.getHeight(); // Get the dimensions of the actual image int bitmapW = bitmap.getWidth(); int bitmapH = bitmap.getHeight(); // Scale the coordinates from the view to match the actual image float scaledX = iX * bitmapW / realW; float scaledY = iY * bitmapH / realH; switch (eventPadTouch) { case MotionEvent.ACTION_DOWN: if (scaledX >= 0 & scaledY >= 0 & scaledX < bitmap.getWidth() & scaledY < bitmap.getHeight()) { //Makes sure that X and Y are not less than 0, and no more than the height and width of the image. if (bitmap.getPixel((int) scaledX, (int) scaledY)!=0) { // actual image area is clicked(alpha not equal to 0), do something } } return true; } return false; }