背景
最近在開發(fā)中遇到了一個問題靴姿。我們的app需要統(tǒng)計(jì)用戶的頁面路徑,也就是用戶使用各個頁面的情況挖炬。這就需要在不同的頁面跳入和跳出時記錄下來雪情。但是我們的app主要是由Fragment構(gòu)成的。而在不同的使用情況下鸭巴,判斷Fragment是否可見的方法是不一樣的眷细。下面對這些不同的使用情況分開分析。
不同的情況
在Activity中直接使用
這種情況是最簡單的鹃祖,也就是在Activity使用XML引入溪椎,或者使用FragmentManager 的addFragment或者replaceFrament 動態(tài)載入。在這種情況下恬口,只要監(jiān)聽Fragment的onResume和onPause方法就能夠判斷其顯隱校读。在onResume和onPause中間是對用戶可見的.
@Override
public void onResume() {
super.onResume();
//TODO now visible to user
}
@Override
public void onPause() {
super.onPause();
//TODO now invisible to user
}
使用show和hide來顯隱的Fragment
FragmentManager除了addFragment和replaceFragment之外還有showFragment和hideFragment來做Fragment的顯隱,這樣可以提生頁面切換的速度祖能,是一種用空間換時間的方式歉秫。但是這樣使用的Fragment在被hide的時候是不會調(diào)用onPause方法的。因?yàn)樗皇窃谄聊恢胁豢梢娏搜菦]有Pause端考。這時候我們需要監(jiān)聽onHiddenChanged方法
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(hidden){
//TODO now visible to user
} else {
//TODO now invisible to user
}
}
但是我們需要注意一點(diǎn),那就是揭厚,如果用戶直接按home鍵退出了,我們的程序也沒有對按home鍵事件進(jìn)行監(jiān)聽扶供,在按home鍵時調(diào)用hideFragment筛圆,那么onHiddenChanged事實(shí)上沒有被調(diào)用,反而是onPause被調(diào)用了椿浓。所以我們需要針對這樣的情況做特殊的處理太援。比如在home鍵退出時顯示調(diào)用一下hideFragment或者在onPause中也發(fā)信號說本Fragment不可見了,這都是可以的扳碍。
在ViewPager中的Fragment
現(xiàn)在安卓市場上基本上的app都會做tab頁提岔,而tab頁基本都是通過android自帶的ViewPager實(shí)現(xiàn)的。ViewPager有這樣一個特點(diǎn)笋敞,當(dāng)滑到某一個Tab時碱蒙,它會同時加載這個tab的左右兩個tab頁,比如我從1頁面切換到了2頁面,那么3頁面的onResume也被調(diào)用了赛惩,但是3頁面其實(shí)對用戶是不可見的哀墓。這時候我們就需要監(jiān)聽setUserVisibleHint來判斷到底對用戶是否可見。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
//TODO now it's visible to user
} else {
//TODO now it's invisible to user
}
}
但是與第二條類似喷兼,我們依然不能完全依賴setUserVisibleHint這個方法來判斷是否ViewPager中的頁面是否對用戶可見篮绰。因?yàn)樵摲椒ㄖ挥性贔ragment切換的時候被調(diào)用。比如我從一個含有ViewPager的Actvity跳轉(zhuǎn)到另一個activity季惯,ViewPager中的Fragment的 setUserVisibleHint方法是不會被調(diào)用的吠各,只能通過onPause來判斷。進(jìn)入該Activity原理類似勉抓。那么怎么辦呢贾漏,我們需要結(jié)合setUserVisibleHint和onResume和onPause。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if ((isVisibleToUser && isResumed())) {
onResume();
} else if (!isVisibleToUser) {
Timber.i("On Pause on %s Fragment Invisble", getClass().getSimpleName());
onPause()
}
}
@Override
public void onResume() {
super.onResume();
if (getUserVisibleHint()) {
Timber.i("On Resume on %s Fragment Visible", getClass().getSimpleName());
//TODO give the signal that the fragment is visible
}
}
@Override
public void onPause() {
super.onPause();
//TODO give the signal that the fragment is invisible
}
需要注意以上方法并不完美琳状,F(xiàn)ragment不可見的信號會被多次發(fā)送磕瓷。目前還沒找到一個只發(fā)送一次的方法。如果讀者有更好的解決方案念逞,歡迎跟我交流困食。
轉(zhuǎn)自http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0422/7863.html