『ANDROID』Android增大button响应区域

对照下面的提示写了个蹩脚的代码:

/**
	 * 扩展touch的区域大小
	 * 
	 * EXPAND_RELATIVELY	相对拓展,上下左右,依据父view
	 * 
	 * EXPAND_ABSOLUTELY	绝对拓展,上下左右像素值
	 * 
	 * value 在EXPAND_ABSOLUTELY下,对应方向上的增加值
	 * 
	 * b	  在下,如果b为真,则按照其父view的大小扩展
	 * */
	enum ExpandTypeEnum {
		EXPAND_RELATIVELY, EXPAND_ABSOLUTELY
	}
	public static class ExpandParam {
		ExpandTypeEnum type;
		
		int value;
		
		boolean b;
		int boundary;
		
		public ExpandParam(int value) {
			this.type = ExpandTypeEnum.EXPAND_ABSOLUTELY;
			this.value = value;
		}
		
		public ExpandParam(boolean b) {
			this.type = ExpandTypeEnum.EXPAND_RELATIVELY;
			this.b = b;
			this.boundary = this.boundary; //需要延迟设置,控件的响应区域信息,应该在layout之后有效?!
		}
	}
	static int doExpand(int src, ExpandParam param) {
		int v = src;
		switch (param.type) {
			case EXPAND_RELATIVELY:
			{
				if (param.b) v = param.boundary;
			}
				break;
			case EXPAND_ABSOLUTELY:
			{
				v = src+param.value;
			}
				break;
		}
		
		return v;
	}
	public static void expandTouchAreaRelatively(final View subView,
												 final View parentView,
												 final ExpandParam top,
											     final ExpandParam left,
											     final ExpandParam bottom,
											     final ExpandParam right) {
		parentView.post(new Runnable() {
			
			@Override
			public void run() {
				Rect parentRect = new Rect();
				parentView.getHitRect(parentRect);
				
				Rect delegateArea = new Rect();
				subView.getHitRect(delegateArea);
				
				// 扩大响应区域
				top.boundary = parentRect.top;
				left.boundary = parentRect.left;
				bottom.boundary = parentRect.bottom;
				right.boundary = parentRect.right;
				
				delegateArea.top = doExpand(delegateArea.top, top);
				delegateArea.left = doExpand(delegateArea.left, left);
				delegateArea.bottom = doExpand(delegateArea.bottom, bottom);
				delegateArea.right = doExpand(delegateArea.right, right);
				
				Log.d("", parentRect.top + ", " + parentRect.left + ", " + parentRect.bottom);
				
				TouchDelegate expendedAreaDelegate = new TouchDelegate(delegateArea, subView);
				
				 // give the delegate to an ancestor of the view we're delegating the area to 
				if (View.class.isInstance(subView.getParent())) {
					((View)subView.getParent()).setTouchDelegate(expendedAreaDelegate);
				}
			}
		});
	}



转载:

Android: TouchDelegate tutorialI’ve been doing quite a lot of Android development lately. Most of the time the API Specificationand Dev Guide are quite complete, but sometimes information is difficult to find. An example of this is the TouchDelegate class. According to the Specification TouchDelegate is a “Helper class to handle situations where you want a view to have a larger touch area than its actual view bounds.”. That’s exactly what it does and most application developers are likely to feel the need to use it.
Since I couldn’t find an example on how to actually use it, I wrote this small tutorial. It’s rather easy, but does expect you have some very basic Android knowledge (eg. how to build and use an Activity).
First up: the simplest layout file in history: (eg. tutorial.xml)

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/FrameContainer"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
            <ImageButton android:id="@+id/tutorial"
                android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:background="@null" android:src="@drawable/tutorial" />
</FrameLayout>



Put this file in res/layout/. Make sure you have a drawable (an image), called tutorial.png (or any other supported format) located in res/drawable/
The layout file only contains a FrameLayout with an ImageButton in it, which is all we need for this tutorial. I choose an ImageButton , but any View will do.
If you have questions regarding the layout file, visit the UI guide.
First thing to do, is to reference our layout file in the Activity, using

1setContentView(R.layout.tutorial);



In order to have a larger touch area than the actual view bounds, we need to get a hold of the parent of our ImageButton: the FrameLayout  called FrameContainer. We post a small Runnable on the UI thread. In that Runnable we instantiate a Rect that specifies the bounds for our TouchDelegate. We then get the hit rectangle of the tutorialButton. The coordinates of the Rect are public, so we change them to what we want them to be. In the example I made the touch area of the tutorial ImageButton larger on the right side. After we have our Rect, we build a TouchDelegate with it and we set that TouchDelegate to the parent of our tutorialButton. I added a random message in onClick for testing purposes.
Code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
View mParent = findViewById(R.id.FrameContainer);
mParent.post(new Runnable() {
    @Override
    public void run() {
        Rect bounds = new Rect();
        ImageButton mTutorialButton = (ImageButton) findViewById(R.id.tutorial);
        mTutorialButton.setEnabled(true);
        mTutorialButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Toast.makeText(TouchDelegateActivity.this, "Test TouchDelegate", Toast.LENGTH_SHORT).show();
            }
        });

        mTutorialButton.getHitRect(bounds);
        bounds.right += 50;
        TouchDelegate touchDelegate = new TouchDelegate(bounds, mTutorialButton);

        if (View.class.isInstance(mTutorialButton.getParent())) {
            ((View) mTutorialButton.getParent()).setTouchDelegate(touchDelegate);
        }
    }
});



That’s it. The actual bounds of your Rect might require some experimenting when used in an actual layout. Feel free to post remarks and questions.

 

 

 

 

 

 

I was recently asked about how to use a TouchDelegate. I was a bit 
rusty myself on this and I couldn't find any good documentation on it. 
Here's the code I wrote after a little trial and error. 
touch_delegate_view is a simple RelativeLayout with the id 
touch_delegate_root. I defined with a single, child of the layout, the 
button delegated_button. In this example I expand the clickable area 
of the button to 200 pixels above the top of my button. 

public class TouchDelegateSample extends Activity {

  Button mButton; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.touch_delegate_view); 
    mButton = (Button)findViewById(R.id.delegated_button); 
    View parent = findViewById(R.id.touch_delegate_root);

    // post a runnable to the parent view's message queue so its run 
after 
    // the view is drawn 
    parent.post(new Runnable() { 
      @Override 
      public void run() { 
        Rect delegateArea = new Rect(); 
        Button delegate = TouchDelegateSample.this.mButton; 
        delegate.getHitRect(delegateArea); 
        delegateArea.top -= 200; 
        TouchDelegate expandedArea = new TouchDelegate(delegateArea, 
delegate); 
        // give the delegate to an ancestor of the view we're 
delegating the 
        // area to 
        if (View.class.isInstance(delegate.getParent())) { 
          ((View)delegate.getParent()).setTouchDelegate(expandedArea); 
        } 
      } 
    }); 
  }

 



Cheers, 
Justin 
Android Team @ Google


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值