DialogFragment——解決PopupWindow中的輸入框無(wú)法復(fù)制粘貼的問(wèn)題椎例;Android中的兩種彈窗PopupWindow和Dialog的區(qū)別挨决。

本文旨在介紹Android中的兩種彈窗PopupWindow和Dialog的區(qū)別。以及關(guān)于寫(xiě)代碼的一些思考订歪。

其實(shí)之前各類(lèi)彈窗脖祈,都是使用PopupWindow來(lái)實(shí)現(xiàn)的。因?yàn)镻opupWindow能實(shí)現(xiàn)這些需求刷晋,雖然有的時(shí)候有些麻煩盖高,比如前面的文章有寫(xiě)到PopupWindow去實(shí)現(xiàn)蒙版遮罩的問(wèn)題。它本身是沒(méi)有蒙版提供的眼虱。

我們項(xiàng)目中使用各種方法去給它增加遮蓋層喻奥。如今看來(lái)確實(shí)是有些愚蠢的。我不介意說(shuō)出以前存在的問(wèn)題捏悬,因?yàn)榘l(fā)現(xiàn)問(wèn)題并改進(jìn)問(wèn)題才是學(xué)習(xí)的過(guò)程撞蚕。當(dāng)然也希望看到這篇文章的小伙伴有自己的想法可以多多溝通,如果也有跟過(guò)去的我一樣盲目的使用PopupWindow來(lái)做需求的同學(xué)过牙,可以從這篇文章中學(xué)到東西甥厦。

這次遇到PopupWindow中的輸入框無(wú)法復(fù)制粘貼,慣例先去網(wǎng)上搜了一下抒和,發(fā)現(xiàn)很多人遇到同樣的問(wèn)題矫渔,解決方案全部都是換成DialogFragment就好了。得到這個(gè)結(jié)果后我有點(diǎn)不服氣摧莽,為啥我PopupWindow復(fù)制粘貼就不行庙洼,為啥就非得換成DialogFragment。關(guān)于為啥PopupWindow復(fù)制粘貼不行镊辕,我開(kāi)始各種搜索油够,也去學(xué)習(xí)了一下長(zhǎng)按復(fù)制粘貼的源碼,但是感覺(jué)自己的智商不是很夠征懈,到現(xiàn)在也沒(méi)弄明白到底為啥不行石咬。如果有知道的小伙伴希望不吝賜教。

通過(guò)這個(gè)問(wèn)題我開(kāi)始思考卖哎,為什么我不管什么彈窗類(lèi)的需求都用PopupWindow來(lái)實(shí)現(xiàn)鬼悠,到底它有啥好的?既然它這么好亏娜,那dialog存在的意義又是什么呢焕窝。其實(shí)以前的做法說(shuō)白了,就是有項(xiàng)目里有了一套沒(méi)什么問(wèn)題的類(lèi)似代碼以后维贺,再來(lái)相關(guān)的需求它掂,不外乎就是復(fù)制粘貼去實(shí)現(xiàn)。所以就導(dǎo)致了一直用PopupWindow的這個(gè)問(wèn)題溯泣。其實(shí)在用的時(shí)候虐秋,尤其是在強(qiáng)行給PopupWindow加入灰色蒙版的時(shí)候榕茧,我就有個(gè)疑問(wèn),為什么PopupWindow不自帶蒙版客给,還要自己去實(shí)現(xiàn)用押,而且網(wǎng)上處理這類(lèi)問(wèn)題的文章并不多。這次真的想弄明白官方為什么要提供兩種彈窗以后起愈,這些疑惑也就想通了只恨。

簡(jiǎn)單介紹:

Dialog

默認(rèn)帶灰色遮蓋層,會(huì)覆蓋整個(gè)屏幕抬虽,使dialog下層的內(nèi)容不可點(diǎn)擊官觅,只有先取消dialog才能繼續(xù)點(diǎn)擊其他內(nèi)容。

所以當(dāng)你的需求阐污,是需要一個(gè)灰色覆蓋層的時(shí)候休涤,優(yōu)先考慮使用Dialog。

Dialog可以指定顯示在屏幕個(gè)各個(gè)位置笛辟,可以通過(guò)設(shè)置偏移實(shí)現(xiàn)顯示在屏幕的某個(gè)位置上功氨。

灰色蒙層的透明度可控,展示位置可控手幢,頁(yè)面布局可控捷凄。

AlertDialog

沒(méi)啥說(shuō)的,是Dialog的一個(gè)子類(lèi)围来,就是為了更方便使用而存在的跺涤。

DialogFragment

谷歌官網(wǎng)推薦的Dialog實(shí)現(xiàn)方式,使用這個(gè)可以讓Dialog的生命周期可控监透。

用法可以參考官網(wǎng)對(duì)DialogFragment的介紹:https://developer.android.google.cn/guide/topics/ui/dialogs#java

PopupWindow

不帶灰色遮蓋層桶错,可以顯示在屏幕的任意位置,也可以基于某個(gè)view的位置顯示胀蛮。

其他能實(shí)現(xiàn)的功能基本與dialog一致院刁。所以其實(shí)這兩個(gè)確實(shí)是可以互相替代的。

總結(jié)粪狼,我的理解:

一般來(lái)說(shuō)退腥,我們開(kāi)發(fā)需求的時(shí)候很少會(huì)使用到系統(tǒng)自帶的樣式,基本上都需要自定義樣式的再榄。在這一點(diǎn)上阅虫,Dialog和PopupWindow并沒(méi)什么區(qū)別,都是可以做到的不跟。

1.那么通常當(dāng)需求中需要實(shí)現(xiàn)灰色蒙版的時(shí)候,建議使用DialogFragment實(shí)現(xiàn)米碰,自帶蒙版窝革。

2.當(dāng)需求的彈窗里面有輸入框的時(shí)候购城,建議使用DialogFragment(因?yàn)橐话阏6夹枰С謴?fù)制粘貼的)

3.如果需求是要求基于某個(gè)view的位置去顯示,那么建議使用PopupWindow虐译。如果不帶蒙版效果瘪板,建議使用PopupWindow。

具體情況還是具體分析啦漆诽。不過(guò)通過(guò)這次讓我明白一個(gè)道理侮攀,官方提供的同類(lèi)View是針對(duì)不同情況下存在更合適使用的。雖然很多功能我們通過(guò)一套邏輯就能實(shí)現(xiàn)厢拭,但是還是應(yīng)該多去思考一下不同的實(shí)現(xiàn)方式到底有什么不同兰英,選一個(gè)更合適更合理的方法。

下面附一下我學(xué)習(xí)了DialogFragment后供鸠,對(duì)它的一個(gè)簡(jiǎn)單基類(lèi)封裝畦贸,旨在對(duì)同類(lèi)彈窗的一個(gè)封裝,減少每個(gè)彈窗都要去初始化dialog代碼楞捂,讓子類(lèi)只需要處理業(yè)務(wù)邏輯薄坏。

```

/**

?*?基于DialogFragment實(shí)現(xiàn)的dialog基類(lèi)(目的:基類(lèi)完成初始化彈窗等一些配置工作,子類(lèi)做邏輯處理)

?*?通過(guò)實(shí)現(xiàn)getLayoutId()返回布局文件寨闹,實(shí)現(xiàn)自定義布局

?*?通過(guò)實(shí)現(xiàn)initView()完成布局初始化胶坠。

?*?通過(guò)調(diào)用?show(FragmentManager?manager,?String?tag)?方法展示彈窗。

?*?DialogFragment的dismiss處理了fragment的移除操作繁堡,因此每次使用時(shí)直接New對(duì)象即可沈善,不需考慮復(fù)用問(wèn)題(親試:考慮的話會(huì)存在一些問(wèn)題)。

?*

?*?可配置帖蔓,彈窗位置(當(dāng)居頂部顯示的時(shí)候矮瘟,可配置距頂部的百分比setMarginTop)

?*?可配置是否可取消

?*?可配置灰色蒙版透明度

?*

*?Time:2021/2/4

*?Author:yang.dong

*/

public?abstract?class?BaseDialogFragmentextends?DialogFragment?{

protected?ViewmLayout;

? ? private?AlertDialogdialog;

? ?@NonNull

@Override

? ?public?DialogonCreateDialog(@Nullable?Bundle?savedInstanceState)?{

if(dialog?==null){

AlertDialog.Builder?builder?=new?AlertDialog.Builder(getActivity());

? ? ? ? ? ?LayoutInflater?inflater?=?getActivity().getLayoutInflater();

? ? ? ? ? ?mLayout?=?inflater.inflate(getLayoutId(),?null);

? ? ? ? ? ?builder.setView(mLayout);

? ? ? ? ? ?dialog?=?builder.create();

? ? ? ? ? ?Window?dialogWindow?=dialog.getWindow();

? ? ? ? ? ?WindowManager.LayoutParams?lp?=?dialogWindow.getAttributes();

? ? ? ? ? ?dialogWindow.setDimAmount(alpha);?//設(shè)置灰色遮蓋層的透明度

? ? ? ? ? ?dialogWindow.setBackgroundDrawableResource(android.R.color.transparent);?//dialog會(huì)有默認(rèn)背景,設(shè)置透明后塑娇,可以完美展示自己的布局

? ? ? ? ? ?dialogWindow.setGravity(gravity);?//設(shè)置居頂部顯示

? ? ? ? ? ?if(gravity?==?Gravity.TOP){//距離屏幕頂部

? ? ? ? ? ? ? ?Display?d?=?getActivity().getWindowManager().getDefaultDisplay();?//?獲取屏幕寬澈侠、高用

? ? ? ? ? ? ? ?lp.y?=?(int)(d.getHeight()?*marginTop);?//?新位置Y坐標(biāo)

? ? ? ? ? ?}

dialogWindow.setAttributes(lp);

? ? ? ? ? ?dialog.setCanceledOnTouchOutside(cancelable);

? ? ? ?}

initView();

? ? ? ? return?dialog;

? ?}

@Override

? ?public?void?show(FragmentManager?manager,?String?tag)?{

//防止重復(fù)添加fragment崩潰

? ? ? ?FragmentTransaction?transaction?=?manager.beginTransaction();

? ? ? ?Fragment?fragment?=?manager.findFragmentByTag(tag);

? ? ? ? if(fragment?!=null){

transaction.remove(fragment);

? ? ? ?}

transaction.commit();

? ? ? ? super.show(manager,?tag);

? ?}

private?float?alpha?=0.3f;

? ? private?float?marginTop?=0.3f;?//?距離頂部的高度(當(dāng)Gravity為top時(shí),生效)

? ?private?int?gravity?=?Gravity.TOP;

? ? private?boolean?cancelable?=false;?//點(diǎn)擊灰色區(qū)域是否可以取消埋酬,默認(rèn)不取消

? ?private?void?setAlpha(float?alpha){

this.alpha?=?alpha;

? ?}

protected?void?setMarginTop(float?marginTop){

this.marginTop?=?marginTop;

? ?}

protected?void?setGravity(int?gravity){//Gravity.TOP

? ? ? ?this.gravity?=?gravity;

? ?}

protected?void?setCancel(boolean?cancelable){//Gravity.TOP

? ? ? ?this.cancelable?=?cancelable;

? ?}

protected?abstract?int?getLayoutId();

? ? protected?abstract?void?initView();

}

```

另外在使用的過(guò)程中哨啃,遇到兩個(gè)問(wèn)題:

1.一直覺(jué)得在實(shí)例化對(duì)象的時(shí)候(也就是點(diǎn)擊按鈕出現(xiàn)彈窗的時(shí)候),不應(yīng)該每次都去創(chuàng)建fragment實(shí)例写妥,而應(yīng)該去判一個(gè)空拳球,創(chuàng)建過(guò)一次以后,再次點(diǎn)擊就只去修改UI珍特。之前使用PopupWindow的時(shí)候一直采用這種做法祝峻。但是這次真的是,去這樣處理感覺(jué)給自己挖了一個(gè)好大的坑。具體現(xiàn)象就是莱找,第二次點(diǎn)擊后UI無(wú)法正常刷新酬姆。

嘗試解決了好久,最后我妥協(xié)了奥溺。還是每次都去new一個(gè)新的吧辞色!也去看了一下dismiss方法的源碼,dismiss后是會(huì)把fragment給移除掉的浮定。并且在Profiler中去觀察了我瘋狂點(diǎn)擊按鈕相满,一直出彈窗的情況下內(nèi)存變化。確實(shí)真的沒(méi)啥變化桦卒。放心去new就好了立美。(歡迎指教)

2.快速點(diǎn)擊導(dǎo)致閃退。其實(shí)這個(gè)問(wèn)題我是為了解決第一個(gè)問(wèn)題闸盔,在網(wǎng)上找答案的時(shí)候悯辙,看別人使用這個(gè)遇到的坑,說(shuō)快速連著點(diǎn)兩下就會(huì)閃退迎吵。我試了一下 躲撰, 果然特喵的閃退了。還真的是击费。拢蛋。。我想不出來(lái)當(dāng)時(shí)的心情蔫巩。感覺(jué)這種問(wèn)題真的不該我們來(lái)處理的谆棱。一個(gè)方案是別人幫我踩的坑,如上對(duì)show()方法的一個(gè)重寫(xiě)圆仔。重寫(xiě)了以后連續(xù)點(diǎn)兩次以后確實(shí)不閃退了垃瞧。不過(guò)感覺(jué)體驗(yàn)也不是特別好,彈窗還是會(huì)出現(xiàn)兩次坪郭,第一個(gè)先消失然后出現(xiàn)第二個(gè)个从。所以我又給點(diǎn)擊事件加上了防止連續(xù)點(diǎn)擊的處理。兩手準(zhǔn)備吧算是~

這次的分享就到這里啦歪沃,歡迎指教嗦锐,大家加油哦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沪曙,隨后出現(xiàn)的幾起案子奕污,更是在濱河造成了極大的恐慌,老刑警劉巖液走,帶你破解...
    沈念sama閱讀 210,835評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碳默,死亡現(xiàn)場(chǎng)離奇詭異贾陷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)嘱根,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)昵宇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人儿子,你說(shuō)我怎么就攤上這事≡矣鳎” “怎么了柔逼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,481評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)割岛。 經(jīng)常有香客問(wèn)我愉适,道長(zhǎng),這世上最難降的妖魔是什么癣漆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,303評(píng)論 1 282
  • 正文 為了忘掉前任维咸,我火速辦了婚禮,結(jié)果婚禮上惠爽,老公的妹妹穿的比我還像新娘癌蓖。我一直安慰自己,他們只是感情好婚肆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,375評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布租副。 她就那樣靜靜地躺著,像睡著了一般较性。 火紅的嫁衣襯著肌膚如雪用僧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,729評(píng)論 1 289
  • 那天赞咙,我揣著相機(jī)與錄音责循,去河邊找鬼。 笑死攀操,一個(gè)胖子當(dāng)著我的面吹牛院仿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播崔赌,決...
    沈念sama閱讀 38,877評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼意蛀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了健芭?” 一聲冷哼從身側(cè)響起县钥,我...
    開(kāi)封第一講書(shū)人閱讀 37,633評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慈迈,沒(méi)想到半個(gè)月后若贮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體省有,經(jīng)...
    沈念sama閱讀 44,088評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,443評(píng)論 2 326
  • 正文 我和宋清朗相戀三年谴麦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蠢沿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,563評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匾效,死狀恐怖舷蟀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情面哼,我是刑警寧澤野宜,帶...
    沈念sama閱讀 34,251評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站魔策,受9級(jí)特大地震影響匈子,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闯袒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,827評(píng)論 3 312
  • 文/蒙蒙 一虎敦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧政敢,春花似錦其徙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,712評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至摩骨,卻和暖如春通贞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恼五。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,943評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工昌罩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灾馒。 一個(gè)月前我還...
    沈念sama閱讀 46,240評(píng)論 2 360
  • 正文 我出身青樓茎用,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親睬罗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子轨功,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,435評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容