最近项目中有一个需求是类似于探探的滑动页面的,具体效果为手指滑动页面可以随手指移动,超过一定距离后,这个页面就消失,并显示下一个页面(如果还有下个页面)。本项目中该页面含有多张图片及文字,点击图片可以查看图片,点击文字进入到详情页面。从网上找了一个案例后,移植过来,出现以下问题:当图片及文字部分增加点击事件后,这个页面的滑动效果就不起作用了,并相应的是点击事件,即这个控件内部的子view消费了滑动事件。
具体代码为:
可滑动控件部分代码:
public class CardStack extends RelativeLayout {
public interface CardEventListener{
//section
// 0 | 1
//--------
// 2 | 3
// swipe distance, most likely be used with height and width of a view ;
public boolean swipeEnd(int section, float distance);
public boolean swipeStart(int section, float distance);
public boolean swipeContinue(int section, float distanceX, float distanceY);
public void discarded(int mIndex, int direction);
public void topCardTapped();
}
public CardStack(Context context, AttributeSet attrs) {
super(context, attrs);
//String sMyValue = attrs.getAttributeValue( "http://schemas.android.com/apk/res/android", "padding" );
//get attrs assign minVisiableNum
for(int i = 0; i<mNumVisible; i++){
addContainerViews();
}
setupAnimation();
}
private void setupAnimation(){
final View cardView = viewCollection.get(viewCollection.size()-1);
mCardAnimator = new CardAnimator(viewCollection);
mCardAnimator.initLayout();
final DragGestureDetector dd = new DragGestureDetector(CardStack.this.getContext(),new DragGestureDetector.DragListener(){
@Override
public boolean onDragStart(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
mCardAnimator.drag(e1,e2,distanceX,distanceY);
return true;
}
@Override
public boolean onDragContinue(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
float x1 = e1.getRawX();
float y1 = e1.getRawY();
float x2 = e2.getRawX();
float y2 = e2.getRawY();
//float distance = CardUtils.distance(x1,y1,x2,y2);
final int direction = CardUtils.direction(x1,y1,x2,y2);
mCardAnimator.drag(e1,e2,distanceX,distanceY);
mEventListener.swipeContinue(direction, Math.abs(x2-x1), Math.abs(y2-y1));
return true;
}
@Override
public boolean onDragEnd(MotionEvent e1, MotionEvent e2) {
//reverse(e1,e2);
float x1 = e1.getRawX();
float y1 = e1.getRawY();
float x2 = e2.getRawX();
float y2 = e2.getRawY();
float distance = CardUtils.distance(x1,y1,x2,y2);
final int direction = CardUtils.direction(x1,y1,x2,y2);
boolean discard = mEventListener.swipeEnd(direction, distance);
if(discard){
mCardAnimator.discard(direction, new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator arg0) {
mCardAnimator.initLayout();
mIndex++;
mEventListener.discarded(mIndex,direction);
//mIndex = mIndex%mAdapter.getCount();
loadLast();
viewCollection.get(0).setOnTouchListener(null);
viewCollection.get(viewCollection.size()-1)
.setOnTouchListener(mOnTouchListener);
}
});
}else{
mCardAnimator.reverse(e1,e2);
}
return true;
}
@Override
public boolean onTapUp() {
mEventListener.topCardTapped();
return true;
}
}
);
mOnTouchListener = new OnTouchListener() {
private static final String DEBUG_TAG = "MotionEvents";
@Override
public boolean onTouch(View arg0, MotionEvent event) {
dd.onTouchEvent(event);
return true;
}
};
cardView.setOnTouchListener(mOnTouchListener);
}
}
以下是DragGestureDetector 的部分代码:
public class DragGestureDetector {
GestureDetectorCompat mGestrueDetector;
DragListener mListener;
private boolean mStarted = false;
private MotionEvent mOriginalEvent;
public static interface DragListener {
public boolean onDragStart(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY);
public boolean onDragContinue(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY);
public boolean onDragEnd(MotionEvent e1, MotionEvent e2);
public boolean onTapUp();
}
public DragGestureDetector(Context context, DragListener myDragListener){
mGestrueDetector = new GestureDetectorCompat(context,new MyGestureListener());
mListener = myDragListener;
}
public void onTouchEvent(MotionEvent event){
mGestrueDetector.onTouchEvent(event);
int action = MotionEventCompat.getActionMasked(event);
switch(action) {
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,"Action was UP");
if(mStarted) {
mListener.onDragEnd(mOriginalEvent, event);
}
mStarted = false;
Log.e("TAG", "CardStack + ACTION_UP");
case (MotionEvent.ACTION_DOWN) :
//need to set this, quick tap will not generate drap event, so the
//originalEvent may be null for case action_up
//which lead to null pointer
mOriginalEvent = event;
case MotionEvent.ACTION_MOVE:
break;
}
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
if(mListener == null) return true;
if( mStarted == false){
mListener.onDragStart(e1,e2,distanceX,distanceY);
mStarted = true;
}
else{
mListener.onDragContinue(e1,e2,distanceX,distanceY);
}
mOriginalEvent = e1;
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return mListener.onTapUp();
}
}
}
以下是activity的部分代码:
public class YuepaoSwipActivity extends BaseActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
ActivityUtil.setTransparentActivity(this);
this.setContentView(R.layout.activity_yuepao_swiper);
mCardStack = (CardStack)findViewById(R.id.container);
mCardStack.setContentResource(R.layout.card_content);
mCardStack.setStackMargin(9);
mCardAdapter = new CardsDataAdapter(this,0);
for(int i= 0; i<10; i++) {
YuepaoBean bean = new YuepaoBean();
bean.a = i;
// mCardAdapter.add(bean);
}
// mCardStack.setAdapter(mCardAdapter);
initView();
initData();
}
}
请教大神,我应该如何解决这个冲突?