最近做的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,對于自己就是一次進步。