Android 兩步搞定Fragment的返回鍵

2021-09-08 13:23:16 字數 4526 閱讀 4652

fragment可以說是在android開發必需要使用到技術,專案中的介面基本上都是使用fragment來實現,而activity只是作為fragment的載體,但有些特殊情況下fragment也不得不處理back鍵,如果是activity的話還好說,直接覆蓋 activity的onbackpressed即可,但fragment可就沒有這麼幸運了,你可能和我一樣,最開始有這樣的需求的時候都會想去覆蓋fragment的onbackpressed方法,但是事與願違,fragment中並沒有這樣的方法,不僅如此,fragment也沒有更不可能有onkeydownonkeyup這樣的方法,那麼fragment如何處理back鍵成難題。

在此之前先賣個關子看看別人都是怎麼實現的,看過的該方式的同學可以直接到最後。

注:出自優雅的讓fragment監聽返回鍵

1、定義乙個backhandledinte***ce

public

inte***ce

backhandledinte***ce

2、定義乙個backhandledfragment 抽象類繼承fragment並提供乙個onbackpressed方法,所有的fragment都派生自該類

public

abstract

class

backhandledfragment extends fragment

else

} @override

public

void

onstart()

}

3、activity實現第一步中定義的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已經幫我們做了。

activity中的有的fragment由fragmentmanager管理,fragment巢狀的子fragment也由fragmentmanager處理,那只要拿到fragmentmanager就可以用遞迴的方式處理了,等等,我好像發現了什麼。

1、同樣的先定義乙個fragmentbackhandler介面。

public

inte***ce

fragmentbackhandler

2、定義乙個backhandlerhelper工具類,用於實現分發back事件,fragment和activity的外理邏輯是一樣,所以兩者都需要呼叫該類的方法。

public

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)

}

3、當然fragment也要實現fragmentbackhandler介面(按需)

//

沒有處理back鍵需求的fragment不用實現

public

abstract

class

backhandledfragment extends fragment implements fragmentbackhandler

}

4、activity覆蓋onbackpressed方法(必須)

public

class

myactivity extends fragmentactivity }}

不是說好的兩步麼,這tm是4步啊!大哥不要生氣,第一步和第二步我都給你做了,你只要在gradle中加入以下的話以及第3、4步即可。你可以使用我提供的backhandledfragment也可以讓自己的basefragment實現fragmentbackhandler介面(只在需要fragmen中實現就行),並在onbackpressed中用填入return backhandlerhelper.handlebackpressed(this);

allprojects 

}}dependencies

當你需要自己處理back事件時覆蓋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小時越野系列賽等.兩步路戶外網 兩步路戶外網是乙個戶外資源共享和社群...