【问题标题】:Android circular button clickable areaAndroid圆形按钮可点击区域
【发布时间】:2015-03-10 19:36:45
【问题描述】:

我在 Android Studio 中制作了这个圆形按钮:

我使用了自定义背景。问题是图像中突出显示的黄色区域是可点击的。我想将可点击区域缩小为红色圆圈。

有没有办法做这样的事情?

【问题讨论】:

    标签: android user-interface android-studio


    【解决方案1】:

    不能移除图片的透明区域。因为它是你形象的一部分。

    任何类型的图像总是具有矩形形状。如果图像的角是透明的,并不意味着角处的那些像素 与图像分离!这些像素总是被您的图像占据,您无法移除那个区域。

    还没有创建可以将图像的透明区域与图像本身分开的库。

    【讨论】:

    • 嗨@Apurva 我不希望我的图像的透明区域是可点击的。
    • @RenatoReyes 这是不可能的,因为您无法将这些像素与图像分开。我从未见过任何人可以使这成为可能。创建您自己的图书馆并通过互联网连接,您将成为英雄。
    【解决方案2】:

    之前有一篇关于clickable area of image的帖子,但是..这里可能无法解决这个问题。

    相反,您应该使用OnTouchListener 来获取触摸事件的x 和y,然后计算并比较中心和偶数之间的距离与半径,以确定这是否是一次点击。

    【讨论】:

      【解决方案3】:

      迟到总比没有好...

      是的,如果您拦截和过滤触摸事件,您可以手动将可点击区域缩小到只有红色圆圈,方法是实现View.OnTouchListener 或覆盖onTouchEvent()。后者要求您对按钮进行子类化,这很简单,但可能不太理想,所以这里有一个使用 View.OnTouchListener 来完成这项工作的示例:

      OvalTouchAreaFilter.java:

      public class OvalTouchAreaFilter implements View.OnTouchListener {
      
          private boolean mIgnoreCurrentGesture;
      
          public TouchAreaFilter() {
              mIgnoreCurrentGesture = false;
          }
      
          public boolean isInTouchArea(View view, float x, float y) {
              int w = view.getWidth();
              int h = view.getHeight();
              if(w <= 0 || h <= 0)
                  return false;
              float xhat = 2*x / w - 1;
              float yhat = 2*y / h - 1;
              return (xhat * xhat + yhat * yhat <= 1);
          }
      
          @SuppressLint("ClickableViewAccessibility")
          @Override
          public boolean onTouch(View view, MotionEvent event) {
              int action = event.getActionMasked();
              if(action == MotionEvent.ACTION_DOWN) {
                  mIgnoreCurrentGesture = !this.isInTouchArea(view, event.getX(), event.getY());
                  return mIgnoreCurrentGesture;
              }
              boolean ignoreCurrentGesture = mIgnoreCurrentGesture;
              if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)
                  mIgnoreCurrentGesture = false;
              return ignoreCurrentGesture;
          }
      }
      

      内部活动 onCreate():

      View button = findViewById(R.id.my_button);
      button.setOnTouchListener(new OvalTouchAreaFilter());
      

      请注意:

      • isInTouchArea() 可以任意实现,将可点击区域设置为您想要的任何形状,甚至可能依赖于复杂条件,例如按钮的背景图像等。

      • setOnTouchListener() 不特定于 Button 类。此解决方案可用于任何类型的视图。

      • 仅仅根据 X 和 Y 位置盲目过滤所有触摸消息并不是一个好的解决方案(例如,如答案 here 中所建议的那样),因为您因此破坏了 MotionEvent consistency guarantee。这个解决方案会过滤掉完整的手势MotionEvent 的序列以ACTION_DOWN 开头并以ACTION_UP/ACTION_CANCEL 结尾,中间可能还有许多其他动作,例如ACTION_MOVE)在他们的起始坐标上。这意味着该方法在多点触控情况下不会中断。

      【讨论】:

        【解决方案4】:

        像这样创建 xml 可绘制对象:

        在drawable文件夹中保存为round_button.xml

            <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="oval">
            <solid android:color="#9F2200"/>
            <stroke android:width="2dp" android:color="#fff" />
        </shape>
        

        并将其设置为 xml 中 Button 的背景,如下所示:`

        <Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/round_button"
        android:gravity="center_vertical|center_horizontal"
        android:text="hello"
        android:textColor="#fff" />
        

        【讨论】:

        • 我已经这样做了,伙计。我只是想知道如何减少可点击区域。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 2013-10-15
        • 1970-01-01
        相关资源
        最近更新 更多