scrollview中的Android可触摸项目

时间:2015-01-22 10:15:56

标签: android events touch scrollview

我在scrollivew内的linearlayout中有一个imageViews数组。 图像视图具有onTouchEvent并在滚动时获得DOWN触摸事件。 我需要一个方法,所以我可以在没有拦截DOWN事件的视图的情况下滚动。

儿童触控听众

image.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int action = event.getAction();

                    switch (action) {
                    case MotionEvent.ACTION_DOWN:

                        Animation scale = new ScaleAnimation(1f, 0.5f, 1f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f);
                        scale.setInterpolator(new DecelerateInterpolator());
                        scale.setFillEnabled(true);
                        scale.setFillBefore(true);
                        scale.setFillAfter(true);
                        scale.setDuration(300);
                        v.startAnimation(scale);
                        image.getParent().getParent().requestDisallowInterceptTouchEvent(true);
                        break;

                    case MotionEvent.ACTION_UP:
                        image.getParent().getParent().requestDisallowInterceptTouchEvent(false);
                        scale = new ScaleAnimation(0.5f, 1.0f, 0.5f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f);
                        scale.setInterpolator(new OvershootInterpolator());
                        scale.setFillEnabled(true);
                        scale.setFillBefore(true);
                        scale.setFillAfter(true);

                        scale.setDuration(200);

                        scale.setAnimationListener(new AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                toggle();

                            }
                        });

                        image.startAnimation(scale);
                        mPager.setCurrentItem(image.getId(), false);
                        v.performClick();

                        break;
                    case MotionEvent.ACTION_CANCEL:
                        scale = new ScaleAnimation(0.5f, 1.0f, 0.5f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f);
                        scale.setInterpolator(new OvershootInterpolator());
                        scale.setFillEnabled(true);
                        scale.setFillBefore(true);
                        scale.setFillAfter(true);

                        scale.setDuration(200);

                        scale.setAnimationListener(new AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                toggle();

                            }
                        });

                        image.startAnimation(scale);
                        mPager.setCurrentItem(image.getId(), false);
                        v.performClick();
                        break;
                    }
                    return true;
                }
            });

1 个答案:

答案 0 :(得分:1)

每一组"一系列行动"从ACTION_DOWN开始,因此您的ImageView将始终获得此操作,因为他们可以处理它(状态更改)。但ACTION_MOVE只能由ScrollView处理,因此这些TouchEvent会通过论坛Button-child(已调度)传递给ScrollView-parent(通过LinearLayout)。

您可以使用调度和拦截TouchEvent s(more here)并将您的操作类型传递给正确的View

但是......你怎么知道用户想要什么?在确切的触摸时刻(ACTION_DOWN)用户可能想要滚动或单击按钮,因此您不知道如何/谁将调度以后的事件以及视图的行为方式。我在您的代码中看到您希望为按钮添加动画效果 - 最好尝试使用其状态并在state_pressed更改为true时开始动画,并在设置false时将其反转。但它可能会给你同样的效果。另一种方法是在按钮被点击时保持整个ScrollViewsome examples),但其在UX方面的解决方案很差

查看Google Play中的某些应用,甚至是Google Play应用。在任何列表上按任何可点击的视图/应用程序 - 它会改变背景,在棒棒糖上有一些涟漪效果等....但是当您按下整个视图时,按下View / App会失去这些效果(state_pressed为false)。你无法猜出用户在ACTION_DOWN时想要做什么,所以上述效果(失败)是正常的

编辑: 正如我所说 - 在ACTION_DOWN时刻猜测用户想要做什么(点击/滚动)是没有办法和正确的行为,所以你的代码和使用都很好。几乎...

这是我的一个(非常古老的)自定义视图的示例,名为Arrow(它包含箭头;))

@SuppressLint("NewApi")  //Honeycomb ofc, use NineOldAndroid for older
public class Arrow extends ImageView implements ValueAnimator.AnimatorUpdateListener{

    ValueAnimator va_scaleX=null, va_scaleY=null;

    public Arrow(Context context) {
        super(context);
        createAnimation();
    }

    public Arrow(Context context, AttributeSet attrs) {
        super(context, attrs);
        createAnimation();
    }

    public Arrow(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        createAnimation();
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        invalidate();
    }

    private void createAnimation() {
        if (va_scaleX == null || va_scaleY==null) {
            va_scaleX = ObjectAnimator.ofFloat(this, "scaleX", 0.5f);
            va_scaleY = ObjectAnimator.ofFloat(this, "scaleY", 0.5f);
            /* useful, optional, similar methods from Animation
            va_scaleX.setDuration(150);
            va_scaleY.setDuration(150);
            va_scaleX.setInterpolator(new LinearInterpolator());
            va_scaleY.setInterpolator(new LinearInterpolator());*/

            va_scaleY.addUpdateListener(this); //one is enough
        }
    }

    public void startAnimation() {
        va_scaleX.start();
        va_scaleY.start();
    }

    public void reverseAnimation() {
        va_scaleX.reverse();
        va_scaleY.reverse();
    }
}

它不是最好的方式(两个动画师),但是就像魅力一样..请注意,虽然动画此View可绘制状态不会刷新(例如,当您将selector设置为背景时)。使用ValueAnimator代替常规Animation

arrow.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        a.startAnimation();
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        a.reverseAnimation();
                        break;
                    default:
                        break;
                    }
                    return false;
                }
            });

它会创建平滑的反向动画,因此当用户按下箭头(ACTION_DOWN)时,动画将会启动,但是当此视图的下一个动作不适用时(在这种情况下为ACTION_MOVE){将调用{1}}方法,将此视图返回到原始大小。整个操作将非常快,因此用户甚至不会注意到这个小的调整大小(和反转)