Can I increase a buttons onclick-area programmatically?

后端 未结 8 1979
孤独总比滥情好
孤独总比滥情好 2021-02-01 16:34

Sometimes I have a button in my UI that it is so small that it is difficult to click. My solution so far has been to add a transparent border around the button in photoshop. Jus

相关标签:
8条回答
  • 2021-02-01 16:46

    Maybe you could do so by looking at the X and Y coordinates of the MotionEvent passed into onTouchEvent ?

    0 讨论(0)
  • 2021-02-01 16:49

    I have just found a neat way to solve this problem.

    1. Surround the button with a say a LinearLayout that has the padding round the button.
    2. Add the same onclick to the LinearLayout as the Button.
    3. In the Button set the duplicateParentState to true which make the button highlight when you click outside the button but inside the LinearLayout.

      <LinearLayout
          android:layout_height="fill_parent"
          android:onClick="searchButtonClicked" 
          android:layout_centerVertical="true" 
          android:orientation="horizontal" 
          android:layout_width="wrap_content" 
          android:paddingRight="10dp" 
          android:paddingLeft="30dp">
          <Button 
              android:id="@+id/search_button"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:background="@drawable/toggle_button_selector"
              android:textColor="#fff"
              android:text="Search"
              android:focusable="true"
              android:textStyle="bold"
              android:onClick="searchButtonClicked" 
              android:layout_gravity="center_vertical" 
              android:duplicateParentState="true"/>
      </LinearLayout>
      
    0 讨论(0)
  • 2021-02-01 16:49

    What I did is not the recommended way and very few will find it useful.

    For me it was the best solution, because TouchDelegate did not worked in all View hierarchy scenarios.

    The solution is based on overriding the hidden

    View class
    public boolean pointInView(float localX, float localY, float slop)
    

    Here is the code:

       public boolean pointInView(float localX, float localY, float slop) {
        boolean res = ae_pointInView(localX, localY, slop, slop);
        if(!res) {
            if(viewIsClickableButToSmall(this)) {
                //our view is clickable itself
                float newSlopX = Math.max(slop, slop + minTouchableViewWidth - this.getWidth());
                float newSlopY = Math.max(slop, slop + minTouchableViewHeight - this.getHeight());
                if(ae_pointInView(localX, localY, newSlopX, newSlopY)) {
                    return true;
                }
            }
    
            //the point is outside our view, now check for views with increased tap area that may extent beyond it
            int childCount = getChildCount();
            for(int i = 0; i < childCount;i++) {
                View child = getChildAt(i);
                if(child instanceof MyViewGroup) {
                    //this is our container that may also contain views with increased tap area
    
                    float[] newPoint = ae_transformPointToViewLocal(localX, localY, child);
                    if(((MyViewGroup) child).pointInView(newPoint[0], newPoint[1], slop)) {
                        return true;
                    }
                }
                else {
                    if(viewIsClickableButToSmall(child)) {
                        float[] newPoint = ae_transformPointToViewLocal(localX, localY, child);
                        float newSlopX = Math.max(slop, slop + minTouchableViewWidth - this.getWidth());
                        float newSlopY = Math.max(slop, slop + minTouchableViewHeight - this.getHeight());
                        if(ae_pointInView(newPoint[0], newPoint[1], newSlopX, newSlopY)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        else
            return true;
    }
    
    private int minTouchableViewHeight, minTouchableViewWidth;
    private boolean viewIsClickableButToSmall(View view)
    {
        minTouchableViewHeight = GlobalHelper.dipToDevicePixels(40);
        minTouchableViewWidth = GlobalHelper.dipToDevicePixels(40);
    
        return (view.getHeight() < minTouchableViewHeight || view.getWidth() < minTouchableViewWidth) && view.hasOnClickListeners();
    }
    
    public boolean ae_pointInView(float localX, float localY, float slopX, float slopY) {
        boolean res = localX >= -slopX && localY >= -slopY && localX < ((getRight() - getLeft()) + slopX) &&
                localY < ((getBottom() - getTop()) + slopY);
        return res;
    }
    
    private float[] tempPoint;
    public float[] ae_transformPointToViewLocal(float x, float y, View child) {
        if(tempPoint == null) {
            tempPoint = new float[2];
        }
        tempPoint[0] = x + getScrollX() - child.getLeft();
        tempPoint[1] = y + getScrollY() - child.getTop();
    
        return tempPoint;
    }
    
    0 讨论(0)
  • 2021-02-01 16:50

    Me personally, I'd use a TouchDelegate. This lets you deal with the touch target, and the visual view bounds as two different things. Very handy...

    http://developer.android.com/reference/android/view/TouchDelegate.html

    0 讨论(0)
  • 2021-02-01 16:55

    I think your solution is the best one available at the moment, if you don't want to go deep into some android stuff and intercept all the motionEvent and TouchEvents yourself and then you also would need to trigger the pressed view of the button yourself etc.

    Just create a nine patch image with a stretchable transparent border. In that way you can change the size of the image without the need to change the image itself and your button will grow or shrink without the actual displayed background changing.

    0 讨论(0)
  • 2021-02-01 16:56

    Anothe idea is to make the new transparent image and put icon on it so the touch area will be more and design look perfect. Check out the image

    Thank you.

    0 讨论(0)
提交回复
热议问题