最近做的Andriod项目,在一个Activity上面添加了一个Fragment,点击Fragment时,会出现Activity上的点击事件起作用。马上反应到,这是点击穿透了。
赶紧查原因。先看代码。
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.fragment_slide_down,0);
if(mDetailFragment==null) {
mDetailFragment=newDetailFragment();
ft.replace(android.R.id.content,mDetailFragment);
}else{
ft.show(mDetailFragment);
}
ft.commitAllowingStateLoss();
mDetailFragment在Activity上面,点击mDetailFragment,事件继续向下传给Activity。那现在的关键就是把事件在mDetailFragment上消耗掉。
再看看Fragment,本质上也是View布局的管理器。使用replace,或者add方法,不是真的将view替换掉,或者add掉。只是叠加。再看看我自己的Activity布局,中间是一个FrameLayout。用户点击Fragment自然也是点击到FrameLayout上面。事件向下传递。
为了确定这个原因,查看Fragment源码:
先看它的主要方法:
FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务
transaction.add()
往Activity中添加一个Fragment
transaction.remove()
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。
transaction.replace()
用另一个Fragment替换当前的,也就是先remove()再add()
transaction.hide()
隐藏
transaction.show()
显示之前隐藏的Fragment
detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
attach()
重建view视图,附加到UI上并显示。
transatcion.commit()//提交一个事务
在看自己的代码逻辑:只用到replace一个空白view,再用show,hide。
解决办法1:在fragment布局的根节点加android:clickable="true"。
当然也可以使用代码控制。
解决办法2:
View view = inflater.inflate(R.layout.activity_content_list, container, false);
view.setClickable(true);
ButterKnife.bind(this, view);
return view;
使用 view.setClickable(true);即可。
当然也可以有解决办法3,也可以控制Touch事件,实现implements View.OnTouchListener
重写方法就好。
@Override
public boolean onTouch(View v, MotionEvent event) {
//防止点击穿透
return true;
}
以后尽量把自己开发的问题写在上面。哪怕在别人看来多low,对于自己就是一次进步。