场景:通过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()中注册回调,触摸事件成功获取。