如何在 Android 中制作自定义形状的可点击视图或按钮?
当我单击时,我想避免触摸空白区域。
请帮忙。谢谢你。
如何在 Android 中制作自定义形状的可点击视图或按钮?
当我单击时,我想避免触摸空白区域。
请帮忙。谢谢你。
有趣的问题。我尝试了一些解决方案,这就是我发现的与您想要实现的结果相同的结果。以下解决方案解决了 2 个问题:
所以这是分三步解决的问题:
创建两个形状。
按钮的第一个简单矩形形状: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>
第二个形状用作按钮右上角的掩码: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>
在您的主布局中,通过下一种方法添加按钮:
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 -->
在您的主要活动中,您定义了两个:按钮和掩码的点击事件,如下所示:
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
}
});
而已。我知道这不是一个完美的解决方案,但在您描述的用例中它可能会有所帮助。我已经在我的手机上对其进行了测试,当您单击蓝色区域时,它的外观是这样的,而其他区域则不会发生任何事情:
希望它以某种方式有所帮助:)
使用 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;
}
使用图层列表,您可以设计任何形状任何渐变按钮顶部这里是示例
<?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>
使用 -ve 半径值来制作你提到的按钮形状
你可以试试这个:
<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"/>
并在 drawable 文件夹中创建 round.xml 文件:
<?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>
我有一个类似的问题,但我不想依赖后面的代码来检查像素值。我想要一种简单的方法(不是类重载)将触摸事件限制为仅可绘制的子部分。下面我对可绘制对象使用 LinearLayout,然后在其中放置一个透明按钮(带文本)。我可以调整按钮的边距以定位可点击区域。
<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>
我在这里找到的最佳和最简单的解决方案 (as4me) - 它是 Button 的子类,因此它支持选择器。因此,您需要做的就是为每个按钮状态绘制/添加相应的 png,以使用选择器并在 xml 中声明 onClick 或在代码中添加 OnClickListener,您就可以开始了。
我尝试了@Basim Sherif (链接) 的答案,但只有当按钮大小与原始图像相同时,它才能很好地工作。如果按钮被拉伸,则可点击区域将更小,如果按钮设置为更小尺寸,则可点击区域将大于实际按钮。
解决方案很简单,即缩放 iX 和 iY 值以匹配原始位图。
这是我修改后的代码版本:
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;
}
与其做所有这些更改,不如在按钮周围的部分使用框架布局,并用一些东西(圆形,如圆形按钮)遮住右上角,并在该部分上不分配点击侦听器。这实际上隐藏了下框架(即您的原始按钮)并用非活动部分掩盖它。