Bouton De Forme Personnalisé Pour Android
Comment puis-je faire une vue ou un bouton personnalisé cliquable sur Android?
Quand je clique , je veux éviter de toucher sur une zone vide .
s'il vous plaît aider. Remercier.
8 réponses
question intéressante. J'ai essayé quelques solutions et c'est ce que j'ai trouvé qui a le même résultat de ce que vous essayez d'atteindre. La solution ci-dessous résout 2 problèmes:
- forme Personnalisée comme vous l'avez présenté
- le côté droit supérieur du bouton ne doit pas être cliquable
ainsi c'est la solution en 3 étapes:
Étape 1
crée deux formes.
-
première forme rectangulaire simple pour le bouton: shape_button_beer.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:angle="90" android:endColor="#C5D9F4" android:startColor="#DCE5FD" /> <corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" > </corners> </shape>
-
deuxième forme est utilisée comme masque pour le côté supérieur droit du bouton: shape_button_beer_mask.xml . C'est cercle simple avec la couleur noire solide.
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#000000" /> </shape>
l'Étape 2
dans votre ajouter le bouton par l'approche suivante:
- RelativeLayout est le conteneur de ce bouton personnalisé
- premier affichage en ligne 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 sale truc:
- les marges sont négatives pour placer le masque au bon endroit
- nous définissons id pour pouvoir Outrepasser le clic (voir étape 3)
-
android:soundEffectsEnabled="false"
- tel que l'utilisateur ne sentira pas qu'il a appuyé sur quelque chose.
XML:
<!-- Custom Button -->
<RelativeLayout
android:layout_width="120dp"
android:layout_height="80dp" >
<LinearLayout
android:id="@+id/custom_buttom"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/shape_button_beer" >
<!-- Beer icon and all other stuff -->
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:src="@drawable/beer_icon" />
</LinearLayout>
<ImageView
android:id="@+id/do_nothing"
android:layout_width="120dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="-50dp"
android:layout_marginTop="-50dp"
android:background="@drawable/shape_button_beer_mask"
android:soundEffectsEnabled="false" >
</ImageView>
</RelativeLayout>
<!-- End Custom Button -->
Étape 3
dans votre activité principale vous définissez sur les événements de clic à la fois: bouton 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 ça. Je sais que ce n'est pas une solution parfaite, mais dans le cas d'utilisation décrit, cela pourrait aider. J'ai testé sur mon mobile et c'est à quoi il ressemble quand vous cliquez sur la zone bleue et rien ne se passera sur d'autres zones:
Espérons qu'il a aidé en quelque sorte :)
utilisez OnTouch au lieu de 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<bitmap.getWidth() & iY<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) iX, (int) iY)!=0) {
// actual image area is clicked(alpha not equal to 0), do something
}
}
return true;
}
return false;
}
u peut essayer celui-ci:
<Button
android:id="@+id/logout"
android:layout_width="240dp"
android:layout_height="28dp"
android:layout_weight="1"
android:gravity="center"
android:text="ContactsDetails"
android:textColor="#ffffff" android:layout_marginLeft="50dp" android:background="@drawable/round"/>
et créer rond.fichier xml dans le dossier dessiner:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="0dp" android:useLevel = "false">
<!-- you can use any color you want I used here gray color-->
<solid android:color="#ABABAB"/>
<corners
android:bottomRightRadius="0dp"
android:bottomLeftRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="70dp"/>
</shape>
utiliser layer-list, Vous pouvez concevoir n'importe quelle forme n'importe quel sommet de bouton de pente voici l'exemple
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="2dp"
android:bottomRightRadius="15dp"
/>
<!-- The border color -->
<solid android:color="#ffffff" />
</shape>
</item>
<item android:right="2dp"
android:left="2dp"
android:bottom="2dp">
<shape>
<gradient
android:startColor="#002a36"
android:centerColor="#457c8e"
android:endColor="#e6ffff"
android:angle="90"
android:centerY="1"
android:centerX="0.5"
/>
<corners
android:topLeftRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="2dp"
android:bottomRightRadius="15dp"
/>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
/>
</shape>
</item>
</layer-list>
valeurs du rayon d'utilisation pour obtenir la forme du bouton comme indiqué par u
j'ai eu un problème similaire mais je ne voulais pas dépendre du code derrière pour examiner la valeur du pixel. Je voulais un moyen simple (pas de surcharge de classe) pour limiter un événement touch à une sous-portion d'un drawable. Ci-dessous, j'utilise une sortie linéaire pour le drawable et puis à l'intérieur que j'ai mis un bouton transparent (avec du texte). Je peux ajuster la marge du bouton pour positionner la zone cliquable.
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/circle">
<Button
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/btnTimer1"
android:text="0:00"
android:textColor="#ffffff"
android:textSize="22dp"
android:layout_margin="20dp"
android:background="@android:color/transparent"/>
</LinearLayout>
meilleure solution et plus facile (as4me) j'ai trouvé ici - il est sous-classé bouton et donc il soutient le sélecteur. Donc, tout ce que vous devez faire est de dessiner/ajouter pngs correspondants pour chaque État de bouton pour utiliser le sélecteur et déclarer onClick en xml ou ajouter OnClickListener en code et vous êtes prêt à aller.
plutôt que de faire tous ces changements, vous devriez utiliser la disposition du cadre à la partie qui entoure le bouton, et masquer la partie supérieure droite avec un peu de chose(circulaire, comme un bouton arrondi) et assigner aucun auditeur de clic sur cette partie. Cela cache en effet le cadre inférieur(c.-à-d. votre bouton original) et le masque avec la partie non active.
j'ai essayé la réponse de @Basim Sherif ( lien ) et cela fonctionne bien cependant seulement si la taille du bouton est la même que l'image originale. Si le bouton a été étiré jusqu'alors cliquable région sera plus petit et si le bouton a été mis à une plus petite taille de la cliquables région sera plus grand que le bouton.
la solution est simple qui consiste à mettre à l'échelle les valeurs iX et iY pour correspondre au bitmap original.
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;
}