fragment可以說是在android開發必需要使用到技術,專案中的介面基本上都是使用fragment來實現,而activity只是作為fragment的載體,但有些特殊情況下fragment也不得不處理back鍵,如果是activity的話還好說,直接覆蓋 activity的onbackpressed
即可,但fragment可就沒有這麼幸運了,你可能和我一樣,最開始有這樣的需求的時候都會想去覆蓋fragment的onbackpressed
方法,但是事與願違,fragment中並沒有這樣的方法,不僅如此,fragment也沒有更不可能有onkeydown
、onkeyup
這樣的方法,那麼fragment如何處理back鍵成難題。
在此之前先賣個關子看看別人都是怎麼實現的,看過的該方式的同學可以直接到最後。
注:出自優雅的讓fragment監聽返回鍵
1、定義乙個backhandledinte***ce
public2、定義乙個backhandledfragment 抽象類繼承fragment並提供乙個inte***ce
backhandledinte***ce
onbackpressed
方法,所有的fragment都派生自該類
public3、activity實現第一步中定義的abstract
class
backhandledfragment extends fragment
else
} @override
public
void
onstart()
}
backhandledinte***ce
介面
public原理分析class
mainactivity extends fragmentactivity implements backhandledinte***ce
@override
public
void
onbackpressed()
else
} }
}
1、利用fragment的生命週期,在fragment顯示時通知到activity,並由activity保持。
2、當使用者按下acitivity時,首先將back鍵請求交給fragment處理,如果處理返回true
,未處理時返回false
。
3、如果fragment沒有處理則由activity處理。
存在的問題
1、只適用於乙個activity上只有乙個fragment的情況。
2、只適用於沒有fragment巢狀的情況。
改進方式
1、將activity中的backhandledfragment 改為list。
2、為保證fragment存在巢狀的情況下也能正常使用,fragment本身也要用list持有 子可見fragment的引用集合。
3、fragment不可見時通知activity或父fragment移除。
4、當使用者按下back鍵時遍歷所有的可見fragment,同樣為了支援巢狀的情況fragment本身也要遍歷所有的
子可見fragment。
雖然這樣可以,但是這樣太麻煩了,還得自己持有fragment例項,難道就沒有更好的方法?
其實我們根本不用去持有各個fragment的例項,fragmentmanager已經幫我們做了。1、同樣的先定義乙個activity中的有的fragment由fragmentmanager管理,fragment巢狀的子fragment也由fragmentmanager處理,那只要拿到fragmentmanager就可以用遞迴的方式處理了,等等,我好像發現了什麼。
fragmentbackhandler
介面。
public2、定義乙個inte***ce
fragmentbackhandler
backhandlerhelper
工具類,用於實現分發back事件,fragment和activity的外理邏輯是一樣,所以兩者都需要呼叫該類的方法。
public3、當然class
backhandlerhelper
}if (fragmentmanager.getbackstackentrycount() > 0
)
return
false
; }
public
static
boolean handlebackpress(fragment fragment)
public
static
boolean handlebackpress(fragmentactivity fragmentactivity)
/*** 判斷fragment是否處理了back鍵
** @return 如果處理了back鍵則返回true*/
public
static
boolean isfragmentbackhandled(fragment fragment)
}
fragment
也要實現fragmentbackhandler
介面(按需)
//4、activity覆蓋沒有處理back鍵需求的fragment不用實現
public
abstract
class
backhandledfragment extends fragment implements fragmentbackhandler
}
onbackpressed
方法(必須)
public不是說好的兩步麼,這tm是4步啊!大哥不要生氣,第一步和第二步我都給你做了,你只要在gradle中加入以下的話以及第3、4步即可。你可以使用我提供的class
myactivity extends fragmentactivity }}
backhandledfragment
也可以讓自己的basefragment
實現fragmentbackhandler介面(只在需要fragmen中實現就行),並在onbackpressed
中用填入return backhandlerhelper.handlebackpressed(this);
。
allprojects當你需要自己處理back事件時覆蓋}}dependencies
onbackpressed
方法,如:
@override圖示public
boolean onbackpressed()
else
fragment的back鍵處理原理
圖中紅色部分為backhandledfragment
或其它實現了fragmentbackhandler
的fragment。
back事件由下往上傳遞,當中間有未實現fragmentbackhandler
的fragment作為其它fragment的容器時,或該fragment攔截了事件時,其子fragment無法處理back事件。
有沒有一種似曾相識的感覺?其實這和view的事件分發機制是乙個道理。
原理1、不管是activity
也好,fragment
也好,其中內部包含的fragment都是通過fragmentmanager
來管理的。
2、fragmentmanager.getfragments()
可以獲取當前fragment/activity
中處於活動狀態的所有fragment
3、事件由activity交給當前fragment處理,如果fragment有子fragment的情況同樣可以處理。
這麼做的好處
1、activity不必實現介面,僅需在onbackpressed
中呼叫backhandlerhelper.handlebackpress(this)
即可,fragment同理。
2、支援多個fragment
3、支援fragment巢狀
4、改動小,只修改有攔截back鍵需求的fragment及其父fragment,其它可以不動。
結語部分**有刪減,完整版請見github:fragmentbackhandler
兩步搞定 VIM 高亮 NGINX 配置檔案
在預設設定下,vim不會對nginx的配置檔案做語法高亮處理,需要手動開啟這一功能。cd usr share vim vim74 syntax wget o nginx.vim編輯filetype.vim檔案來註冊nginx語法檔案 vim usr share vim vim74 filetype....
看似難懂的異地組網 只需兩步搞定
異地組網是什麼?異地組網方式多嗎?答案是肯定的。當然不差錢的可以拉專線,大型企業的可以選擇大河雲聯,阿里雲等業,那麼,小企業或者個人門店類怎麼辦呢?零遁的智慧型網關,有企業版和微企版服務,既可以跑大型企業的組網專案,也可以跑三五個小辦公室的協同辦公專案,可以說適用範圍還是很廣的。以下這是乙個設定流程...
兩步路軌跡檔案位置 關於兩步路
戶外探索,從兩步路出發。多年來,兩步路始終以 探索新世界,安全戶外行 的理念服務廣大戶外愛好者,曾舉辦 協辦的大型活動有 第三屆中國百色山地戶外挑戰賽 首屆全國攀岩精英賽 全能五仕挑戰賽 為愛健行徒步大會 北回歸線上的足跡 紅牛24小時越野系列賽等.兩步路戶外網 兩步路戶外網是乙個戶外資源共享和社群...