Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Custom Shape Button

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 .

enter image description here

please help. Thank you.

like image 940
Erhan Demirci Avatar asked Dec 13 '12 14:12

Erhan Demirci


People also ask

How to set shape for a Button in Android?

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 .

How to style a Button Android?

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.

How to make Button style in Android studio?

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.


2 Answers

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:

  1. Custom shape as you presented it
  2. The top right side of the button shouldn't be clickable

So this is the solution in 3 steps:

Step 1

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> 

Step 2

In your main layout add the button by next approach:

  • RelativeLayout is the container of this custom button
  • First LinearLayout is the blue button with beer icon and text inside
  • Second ImageView is the mask above the blue button. And here comes dirty trick:
    1. Margins are negative to set the mask in the right place
    2. We define id to be able override on click (see step 3)
    3. 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 --> 

Step 3

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:

  • enter image description here

Hope it helped somehow :)

like image 183
sromku Avatar answered Oct 02 '22 17:10

sromku


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; } 
like image 40
Basim Sherif Avatar answered Oct 02 '22 15:10

Basim Sherif