通过回调在fragment中获取activity的触摸事件

来源:互联网 发布:小指头结局 知乎 编辑:程序博客网 时间:2024/05/17 23:38

场景:通过Activity搭配Fragment来搭建项目框架是很流行的做法,在开发中,你很可能需要在Fragment中去获取触摸事件来实现业务需求,比如,你可能希望在你的页面中实现如下功能,在界面上触摸滑动的时候显示右下角的添加按钮,否则自动隐藏该按钮
这里写图片描述
但是,Fragment本身是没有触摸事件的,也许有人会从Layout的触摸事件入手,这也不失为一个好方法,但是在某些情况下,比如你的布局里面还嵌套了一个listView,那么就可能会出现Layout的触摸事件失灵的现象。所以我决定从MainActivity的触摸事件入手。通过回调的方式将MainActivity的触摸事件传递到Fragment中去。
首先是MainActivity:

public class MainActivity extends FragmentActivity {    private FragmentManager mFragmentManager;    private MyTouchListener myTouchListener;//实现接口    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        mFragmentManager = getSupportFragmentManager();        mFragmentManager.beginTransaction()                .replace(R.id.container, new TouchFragment()).commit();    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        //将触摸事件传递给回调函数        if (null != myTouchListener) {            myTouchListener.onTouch(ev);        }        return super.dispatchTouchEvent(ev);    }    /**     * 用于注册回调事件     */    public void registerMyTouchListener(MyTouchListener myTouchListener) {        this.myTouchListener = myTouchListener;    }    /**     * 定义一个接口     * @author fox     *     */    public interface MyTouchListener {        public void onTouch(MotionEvent ev);    }}

定义一个接口,用于实现回调,然后在MainActivity中实现这个接口,接着在dispatchTouchEvent()函数中将事件传递给回调函数。随后提供一个注册方法registerMyTouchListener(MyTouchListener myTouchListener) ,Fragment可以通过该方法注册回调。之所以使用dispatchTouchEvent()而不用onTouchEvent()是因为,onTouchEvent()的传递事件会被页面中的ListView拦截而出现触摸无响应的情况。
接着是Fragment

public class TouchFragment extends Fragment {    private View view;    private ImageView mImageView;// 右下角的添加按钮,默认隐藏    private float lastTouchX;    private float lastTouchY;    // 实现回调接口,定义触摸后的操作    private MainActivity.MyTouchListener myTouchListener = new MyTouchListener() {        @Override        public void onTouch(MotionEvent ev) {            switch (ev.getAction()) {            // 手指点击屏幕时,记录当前的X坐标和Y坐标            case MotionEvent.ACTION_DOWN:                lastTouchX = ev.getX();                lastTouchY = ev.getY();                break;            /*             * 手指在屏幕上滑动的时候,获取当前的X坐标和Y坐标,然后和起始位置的坐标做对比,             * 如果移动的距离超过1,显示该图片             */            case MotionEvent.ACTION_MOVE:                float disX = ev.getX() - lastTouchX;                float disY = ev.getY() - lastTouchY;                if (disX > 1 || disY > 1 || disX < -1 || disY < -1) {                    // 显示图片                    showAddImage();                }                break;            default:                break;            }        }        private void showAddImage() {            // 如果图片是隐藏的,将该图片设置成显示            if (mImageView.getVisibility() == view.INVISIBLE) {                mImageView.setVisibility(View.VISIBLE);                // 开启一个线程,在三秒后将图片设置成隐藏                Thread thread = new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(3000);                            if (getActivity() != null) {                                getActivity().runOnUiThread(new Runnable() {                                    @Override                                    public void run() {                                        mImageView                                                .setVisibility(View.INVISIBLE);                                    }                                });                            }                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                });                thread.start();            }        }    };    @Override    public View onCreateView(LayoutInflater inflater,            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        view = inflater.inflate(R.layout.touchfragment, null);        mImageView = (ImageView) view.findViewById(R.id.image);        return view;    }    @Override    public void onResume() {        super.onResume();        // 在onResume里面注册回调        ((MainActivity) this.getActivity())                .registerMyTouchListener(myTouchListener);    }}

在Fragment中实现回调接口,定义触摸后的操作,随后在onResume()中注册回调,触摸事件成功获取。布局的代码很简单,我就不贴上来了。如果各位有更好的实现方式,欢迎留言分享

2 0
原创粉丝点击