Android自定义形状按钮

Erh*_*rci 41 android android-widget android-custom-view android-layout onclicklistener

如何在Android中制作自定义形状的可点击视图或按钮?

当我点击时,我想避免触摸空白区域.

在此输入图像描述

请帮忙.谢谢.

sro*_*mku 39

有趣的问题.我尝试了一些解决方案,这是我发现的,与你想要实现的结果相同.下面的解决方案解决了2个问题:

  1. 你提出的自定义形状
  2. 按钮的右上角不应该是可点击的

所以这是3个步骤的解决方案:

步骤1

创建两个形状.

  • 按钮的第一个简单矩形形状: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>
    
    Run Code Online (Sandbox Code Playgroud)
  • 第二个形状用作按钮右上角的掩码:shape_button_beer_mask.xml.它是黑色纯色的简单圆圈.

    <?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>
    
    Run Code Online (Sandbox Code Playgroud)

第2步

在主布局中,按下一种方法添加按钮:

  • RelativeLayout是此自定义按钮的容器
  • 第一个LinearLayout是蓝色按钮,里面有啤酒图标和文字
  • 第二个ImageView是蓝色按钮上方的掩码.这里有肮脏的伎俩:
    1. 在正确的位置设置遮罩的边距为负
    2. 我们定义id可以在点击时覆盖(参见步骤3)
    3. android:soundEffectsEnabled="false" - 这样用户就不会觉得他按下了某些东西.

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 -->
Run Code Online (Sandbox Code Playgroud)

第3步

在您的主要活动中,您可以在以下两个点击事件中定义:按钮和掩码,如下所示:

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
    }
});
Run Code Online (Sandbox Code Playgroud)

而已.我知道这不是一个完美的解决方案,但在您描述的用例中它可以提供帮助.我已经在我的手机上测试了它,这就是当你点击蓝色区域时它看起来的样子,其他区域什么都不会发生:

  • 在此输入图像描述

希望它有所帮助:)

  • @sromku感谢您的代码.但是,有一个问题.如果图像中的黑色区域不是黑色而是透明的,那么无论背景如何,通过该透明区域都可以看到它.在我的场景中,有一个图像而不是黑色背景.我该怎么办? (4认同)

Bas*_*rif 15

使用OnTouch而不是OnClick并检查您在按钮中使用的图像的alpha值.如果它不等于零,请执行您想要的任何操作.检查以下代码,

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;
}
Run Code Online (Sandbox Code Playgroud)