How can i make a custom shaped clickable view or button in Android?
When I click , I want to avoid touching on an empty area .
please help. Thank you.
We can set custom shapes on our button using the xml tag <shape> . These xml files are created in the drawable folder too. shape can be used inside selectors . The shape can be set to rectangle (default), oval , ring , line .
To add a button, that has an Android style all you need to do is to drag and drop a button from the Palette to your layout. For most versions that would mean a grey button with all corners at 2dp roundness. Check our blog, if you need to learn more about using Android Studio Layout Editor.
To customize individual buttons with a different background, specify the android:background attribute with a drawable or color resource. Alternatively, you can apply a style for the button, which works in a manner similar to HTML styles to define multiple style properties such as the background, font, size, and others.
Interesting question. I tried some solutions and this is what I found that has the same result of what you are trying to achieve. The solution below resolves 2 problems:
So this is the solution in 3 steps:
Create two shapes.
First simple rectangle shape for the button: 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>
Second shape is used as mask for the top right side of the button: shape_button_beer_mask.xml. It is simple circle with black solid color.
<?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>
In your main layout add the button by next approach:
android:soundEffectsEnabled="false"
- such that user will not feel that he pressed on something.The 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 -->
In your main activity you define on click events for both: button and the mask as follow:
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 } });
That's it. I know that is not a perfect solution but in your described use case it could help. I have tested it on my mobile and this is how it looks when you click on the blue area and nothing will happen on other areas:
Hope it helped somehow :)
Use OnTouch instead of OnClick and check the alpha value of image you have used in the button.If its not equal to zero, do whatever you want. Check the followig 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(); 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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With