Botón de forma personalizada de Android

¿Cómo puedo crear una vista o botón con forma personalizada en Android?

Cuando hago clic, quiero evitar tocar un área vacía.

enter image description here

por favor ayuda. Gracias.

Interesante pregunta. Intenté algunas soluciones y esto es lo que encontré que tiene el mismo resultado de lo que estás tratando de lograr. La solución a continuación resuelve 2 problemas:

  1. Forma personalizada como la presentaste
  2. No se puede hacer clic en el lado superior derecho del botón

Entonces esta es la solución en 3 pasos:

Paso 1

Crea dos formas.

  • Primera forma de rectángulo simple para el botón: shape_button_beer.xml

          
  • La segunda forma se usa como máscara para el lado superior derecho del botón: shape_button_beer_mask.xml . Es un círculo simple con un color sólido negro.

         

Paso 2

En su diseño principal, agregue el botón a continuación:

  • RelativeLayout es el contenedor de este botón personalizado
  • First LinearLayout es el botón azul con icono de cerveza y texto dentro
  • Second ImageView es la máscara sobre el botón azul. Y aquí viene el truco sucio:
    1. Los márgenes son negativos para establecer la máscara en el lugar correcto
    2. Definimos id para poder sobrescribir al hacer clic (ver paso 3)
    3. android:soundEffectsEnabled="false" – de modo que el usuario no sienta que presionó algo.

El XML:

            

Paso 3

En su actividad principal, defina eventos de clic para ambos botones y la máscara de la siguiente manera:

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

Eso es. Sé que no es una solución perfecta, pero en el caso de uso descrito podría ser útil. Lo probé en mi móvil y así es como se ve al hacer clic en el área azul y no pasará nada en otras áreas:

  • enter image description here

Espero que haya ayudado de alguna manera 🙂

Utilice OnTouch en lugar de OnClick y compruebe el valor alfa de la imagen que ha utilizado en el botón. Si no es igual a cero, haga lo que desee. Verifique el código de seguimiento,

 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 

puedes probar este:

   

y crea el archivo round.xml en la carpeta dibujable:

        

use layer-list, puede diseñar cualquier forma que cualquier botón de degradado encabece aquí es un ejemplo

                  

use -ve valores de radio para hacer la forma del botón como mencionó

Tuve un problema similar, pero no quería depender del código para examinar el valor del píxel. Quería una manera simple (no sobrecarga de clases) para restringir un evento táctil a solo una parte secundaria de un dibujable. A continuación uso un LinearLayout para el dibujable y luego dentro de él pongo un botón transparente (con texto). Puedo ajustar el margen del botón para colocar el área en la que se puede hacer clic.

     

La mejor y más fácil solución (as4me) que encontré aquí: es un botón subclasificado y, por lo tanto, admite el selector. Entonces todo lo que tiene que hacer es dibujar / agregar pngs correspondientes para cada estado de botón para usar el selector y declarar onClick en xml o agregar OnClickListener en el código y ya está listo para comenzar.

En lugar de hacer todos esos cambios, debe usar el diseño del marco en la parte que rodea el botón y enmascarar la parte superior derecha con algo (circular, como un botón redondeado) y no asignar ningún oyente clic en esa parte. De hecho, esto oculta el cuadro inferior (es decir, el botón original) y lo enmascara con la parte no activa.

Probé la respuesta por @Basim Sherif ( enlace ) y funciona muy bien, pero solo si el tamaño del botón es el mismo que el de la imagen original. Si el botón se estiró, la región en la que se puede hacer clic será más pequeña y si el botón se ajustó a un tamaño más pequeño, la región en la que se puede hacer clic será más grande que el botón real.

La solución es simple, que es escalar los valores iX e iY para que coincidan con el bitmap original.

Y aquí está mi versión modificada del código:

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