点击事件的传递/实现下拉刷新/手势检测

点击事件的传递

1.DispatchTouchEvent()返回True代表可以分发事件,

2.onInterceptTouchEvent()返回False表示不拦截事件,

3.onTouchEvent()返回True代表执行点击事件,在执行完以后必须返回True,否则不会处理Touch事件
这里写图片描述

通过点击事件来实现下拉刷新的操作

实现下拉刷新的原理其实就是在FramLayout布局中添加两个View,写有下拉刷新的View放在最底下,然后拖拽最上面的一个View将下面的View漏出来,来实现刷新操作,最后在将最上面的View放回到原来的位置

1.首先创建一个Java类继承与FramLayout,然后复写里面的构造器

2.得到LayoutInflater对象,然后添加View

3.在onInterceptTouchEvent()中设置条件进行事件拦截,最后交给TouchEvent处理

4.在TouchEvent对事件进行处理,实现下拉刷新的操作

public class MyRefresh extends FrameLayout{
    private ListView content;
    public MyRefresh(Context context) {
        super(context);
    }

    public MyRefresh(Context context, AttributeSet attrs) {
        super(context, attrs);
        //得到inflater
        LayoutInflater inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //添加View
        View refresh=inflater.inflate(R.layout.refresh, null);
        addView(refresh);
        //添加ListView
        content=(ListView) inflater.inflate(R.layout.content, null);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1,
                new String[]{"as", "sadf", "der", "as", "sadf", "der", "as", "sadf", "der",
                        "as", "sadf", "der", "as", "sadf", "der", "as", "sadf", "der"});
        content.setAdapter(adapter);
        addView(content);
        Log.d("fresh","第一个子View的位置"+content.getFirstVisiblePosition());
    }

    public MyRefresh(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);
    }



    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d("fresh","DispatchTouchEvent:"+ev.getAction()+"是否拦截:"+super.dispatchTouchEvent(ev));
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction()==MotionEvent.ACTION_DOWN){
            Log.d("fresh","InterceptTouchEvent:"+ev.getAction()+"是否拦截:"+super.onInterceptTouchEvent(ev));
        }
        //判断ListView的位置,如果ListView的第一个子View的位置在(0,0)就拦截事件,然后然后就发送到onTOuchEvent事件中进行处理
        if (content.getFirstVisiblePosition()==0){
                View firstView=content.getChildAt(0);
            Log.d("fresh","得到第一个View的Y值"+firstView.getY());
            if (firstView.getY()>=0.0){
                Log.d("fresh","已经拦截");
                return true;//返回true就表示拦截
            }
        }
        return super.onInterceptTouchEvent(ev);
    }
    float oldY;
    float y;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("fresh","运行到"+event.ACTION_DOWN);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                oldY=event.getY();//首先得到触摸时的位置
                Log.d("fresh","oldy的值为"+oldY);
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d("fresh","运行到"+event.ACTION_MOVE);
                y=event.getY();//MOVE结束时的位置
                float distance=y-oldY;//得到MOVE距离
                content.setTranslationY(content.getTranslationY()+distance);//位移
                oldY=y;
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                Log.d("fresh","运行到"+event.ACTION_UP);
                //设置动画将ListView放回到原来的位置
                ObjectAnimator.ofFloat(content,"translationY",content.getTranslationY(),0).setDuration(300).start();
                break;
        }
        return true;
    }
}

其中ListView的xml布局是

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

</ListView>

手势检测

0.创建一个Java类继承一个Button

1.首先创建一个手势对象,然后在设置Simple监听事件复写里面的方法

2.最后需要在TouchEvent事件中将手势事件放入到里面

3.最后创建一个自定义的手势监听

public class MyButton extends Button {
    /***
     * 自定义点击监听
     * 首先是写一个接口,里面包含一个方法,这个方法里的参数包含了这个View
     * 然后创建一个实例化的对象
     * 最后给这个对象加上一个set方法
     */
    public interface OnClickDoubleListener{
        public void onClickDouble(View v);
    }
    private OnClickDoubleListener listener;

    public void setOnClickDoubleListener(OnClickDoubleListener listener) {
        this.listener = listener;
    }



    public OnClickDoubleListener getListener() {
        return listener;
    }

    private GestureDetector mGesture;//创建一个手势检测对象
    public MyButton(Context context) {
        super(context);
    }

    public MyButton(final Context context, AttributeSet attrs) {
        super(context, attrs);
        //创建手势监听复写方法
        mGesture=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
            //复写点击两次的方法
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                if (listener!=null){
                    listener.onClickDouble(MyButton.this);
                }
                Log.d("button","连续点击了两次");
                return true;
            }
                //复写滑动方法
            //第一个参数是DOWN下的事件,即手触摸到屏幕时的事件
            //第二个参数是MOVE事件,即手移动时的事件,
            //第三个参数是沿x轴滑动的速度
            //第四个参数是是沿Y轴滑动的速度
//            @Override
//            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//                if (Math.abs(e2.getX()-e1.getX())>50){
//                    setTranslationX(e2.getX()-e1.getX());//X轴平移平移
//                    ObjectAnimator.ofFloat(MyButton.this,"translationX",getTranslationX(),e2.getX()-e1.getX()).setDuration(2000).start();
//                    return true;
//                }
//                return super.onFling(e1, e2, velocityX, velocityY);
//            }
            //复写滚动方法
                //第一个参数是DOWN下的事件,即手触摸到屏幕时的事件
                //第二个参数是MOVE事件,即手移动时的事件,
                //第三个参数是沿x轴滑动的速度
                //第四个参数是是沿Y轴滑动的速度
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                setTranslationX(getTranslationX()+e2.getX()-e1.getX());//X轴平移
                setTranslationY(getTranslationY()+e2.getY()-e1.getY());//Y轴平移
                return super.onScroll(e1, e2, distanceX, distanceY);
            }
        });

    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGesture.onTouchEvent(event);//手势检测一定要在onTouchEvent中获取事件,否则不会触发时间
        return super.onTouchEvent(event);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值