我编写了一个自定义视图组来实现我想要的功能。但我有一个问题需要你的帮助。问题是:手指从视图组移动到子视图。但是当手指放在子视图上时,我错过了触摸事件。我覆盖了视图组的 ViewGroup.onInterceptTouchEvent 和 ViewGroup.onTouchEvent 方法。我喜欢当视图组的 ViewGroup.onInterceptTouchEvnet 返回 true 时,视图组的 ViewGroup.onTouchEvent 将处理运动事件。然后运动事件将发布到视图组的 ViewGroup.onTouchEvent,不会通过视图组的 ViewGroup.onInterceptTouchEvent 方法。当手指从视图组移动到子视图时,运动事件将直接传递给视图组的 ViewGroup.onTouchEvent ,我无法将运动事件分派给子视图。等待你的帮助。请!
This is the Layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textview_title"
android:layout_width="match_parent"
android:layout_height="50dip"
android:background="#00ff00"
android:gravity="center"
android:text="@string/str_textview_title"
android:textSize="30sp" />
<com.example.pullrefreshlayout.PullRefreshLayout
android:id="@+id/layout_pull_refresh"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/textview_title" >
<ListView
android:id="@+id/listview_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</com.example.pullrefreshlayout.PullRefreshLayout>
</RelativeLayout>
This is my ViewGroup , it's a PullRefreshLayou.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i(TAG, "onInterceptTouchEvent action is: " + ev.getAction());
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mTouchEventY = ev.getY();
mTouchEventX = ev.getX();
if (mHeaderView.getBottom() <= 0) {
return false;
} else {
if (mState == STATE_REFRESHING) {
return false;
} else {
return true;
}
}
case MotionEvent.ACTION_MOVE:
double moveDistanceY = ev.getY() - mTouchEventY;
double moveDistanceX = ev.getX() - mTouchEventX;
mTouchEventX = ev.getX();
mTouchEventY = ev.getY();
if (Math.abs(moveDistanceY) < 2 * Math.abs(moveDistanceX)) {
Log.d(TAG, "moveDistanceY < 2 * moveDistanceX");
return false;
}
Log.i(TAG, "move distance is :" + moveDistanceY);
if (isRefreshReady() && moveDistanceY > 3) {
// 判断ContentView在顶部,而且有下拉的操作,moveDistance还可调大
return true;
}
if (mHeaderView.getBottom() <= 0) {
return false;
} else {
return true;
}
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG, "onTouchEvent action is :" + event.getAction());
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
int moveDistance = (int) (event.getY() - mTouchEventY);
Log.i(TAG, "move distance is :" + moveDistance);
if (moveDistance < 0) {
moveDistance = moveDistance > -mHeaderView.getBottom() ? moveDistance
: -mHeaderView.getBottom();
}
mHeaderView.offsetTopAndBottom(moveDistance);
mContentView.offsetTopAndBottom(moveDistance);
invalidate();
int headerViewTop = mHeaderView.getTop();
if (headerViewTop >= 0 && mHeaderViewTop < 0
&& mState != STATE_REFRESHING) {
mHeaderView.startUpAnimation();
mHeaderView.onReleaseToRefresh(mRefreshTime);
mState = STATE_RELEASE_TO_REFRESH;
}
if (headerViewTop < 0 && mHeaderViewTop >= 0
&& mState != STATE_REFRESHING) {
mHeaderView.startDownAnimation();
mHeaderView.onPullToRefresh(mRefreshTime);
mState = STATE_PULL_TO_REFRESH;
}
mHeaderViewTop = headerViewTop;
mTouchEventY = event.getY();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mHeaderView.getTop() >= 0) {
// 刷新
if (mState != STATE_REFRESHING) {
if (null != mPullRefreshListener) {
mPullRefreshListener.onRefresh();
}
mState = STATE_REFRESHING;
mHeaderView.onRefresh(mRefreshTime);
}
scrollToRefresh();
} else {
// 不刷新
if (mHeaderView.getTop() > -mHeaderViewHeight
&& mState != STATE_REFRESHING) {
mState = STATE_DEFAULT;
scrollToClose();
}
}
break;
default:
break;
}
return false;
}
OK.