Android開(kāi)發(fā)技巧之永不關(guān)閉的Toast信息框(長(zhǎng)時(shí)間顯示而非系統(tǒng)關(guān)閉)
從7.3.1節(jié)的內(nèi)容可以知道,Toast信息提示框需要調(diào)用Toast.show方法來(lái)顯示。下面來(lái)看一下show方法的源代碼。
publicvoidshow(){
if(mNextView==null){
thrownewRuntimeException("setViewmusthavebeencalled");
}
INotificationManagerservice=getService();
Stringpkg=mContext.getPackageName();
TNtn=mTN;
try{
//將當(dāng)前Toast加入到Toast隊(duì)列
service.enqueueToast(pkg,tn,mDuration);
}catch(RemoteExceptione){
//Empty
}
}
show方法的代碼并不復(fù)雜,可以很容易找到如下的代碼。
service.enqueueToast(pkg,tn,mDuration);
從上面的代碼可以很容易推斷出它的功能是將當(dāng)前的Toast加入到系統(tǒng)的Toast隊(duì)列中??吹竭@里,各位讀者應(yīng)該想到。雖然show方法的表面功能是顯示Toast信息提示框,但其實(shí)際的功能是將Toast加入到隊(duì)列中,再由系統(tǒng)根據(jù)Toast隊(duì)列來(lái)顯示Toast信息提示框。那么我們經(jīng)過(guò)更進(jìn)一步地思考,可以大膽地做出一個(gè)初步的方案。既然系統(tǒng)的Toast隊(duì)列可以顯示Toast信息提示框,那么我們?yōu)槭裁床豢梢宰约簛?lái)顯示它呢?這樣不是可以自己來(lái)控制Toast的信息提示框的顯示和關(guān)閉了嗎!當(dāng)然,這就不能再調(diào)用show方法來(lái)顯示Toast信息提示框了(因?yàn)閟how方法會(huì)將Toast加入隊(duì)列,這樣我們就控制不了Toast了)。
既然初步方案已擬定,現(xiàn)在就來(lái)實(shí)施它。先在Toast類(lèi)找一下還有沒(méi)有其他的show方法。結(jié)果發(fā)現(xiàn)了一個(gè)TN類(lèi),該類(lèi)是Toast的一個(gè)內(nèi)嵌類(lèi)。在TN類(lèi)中有一個(gè)show方法。TN是ITransientNotification.Stub的子類(lèi)。從ITransientNotification和TN類(lèi)中的show方法初步推斷(因?yàn)門(mén)ransient的中文意思是“短暫的”)系統(tǒng)是從Toast隊(duì)列中獲得了Toast對(duì)象后,利用TN對(duì)象的show方法顯示Toast,再利用TN.hide方法來(lái)關(guān)閉Toast。首先聲明,這只是假設(shè),我們還不知道這么做是否可行!當(dāng)然,這也是科學(xué)研究的一般方法,先推斷或假設(shè),然后再證明推斷或假設(shè)。
現(xiàn)在關(guān)鍵的一步是獲得TN對(duì)象。遺憾的是TN被聲明成private類(lèi)型,外部無(wú)法訪問(wèn)。不過(guò)別著急。在Toast類(lèi)中有一個(gè)mTN變量。雖然不是public變量,但仍然可以通過(guò)反射技術(shù)訪問(wèn)該變量。mTN變量會(huì)在創(chuàng)建Toast對(duì)象時(shí)初始化。因此,只要獲得mTN變量,就獲得了TN對(duì)象。下面的代碼顯示了一個(gè)永遠(yuǎn)不會(huì)自動(dòng)關(guān)閉的Toast信息提示框。
//先創(chuàng)建一個(gè)Toast對(duì)象
Toasttoast=Toast.makeText(this,"永不消失的Toast",Toast.LENGTH_SHORT);
//設(shè)置Toast信息提示框顯示的位置(在屏幕頂部水平居中顯示)
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL,0,0);
try
{
//從Toast對(duì)象中獲得mTN變量
Fieldfield=toast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
Objectobj=field.get(toast);
//TN對(duì)象中獲得了show方法
Methodmethod=obj.getClass().getDeclaredMethod("show",null);
//調(diào)用show方法來(lái)顯示Toast信息提示框
method.invoke(obj,null);
}
catch(Exceptione)
{
}
上面的代碼中try{…}catch(…){…}語(yǔ)句中的代碼是關(guān)鍵。先利用事先創(chuàng)建好的Toast對(duì)象獲得了mTN變量。然后再利用反射技術(shù)獲得了TN對(duì)象的show方法。
關(guān)閉Toast和顯示Toast的方法類(lèi)似,只是需要獲得hide方法,代碼如下:
try
{
//需要將前面代碼中的obj變量變成類(lèi)變量。這樣在多個(gè)地方就都可以訪問(wèn)了
Methodmethod=obj.getClass().getDeclaredMethod("hide",null);
method.invoke(obj,null);
}
catch(Exceptione)
{
}
上面的代碼已經(jīng)很完美地實(shí)現(xiàn)了通過(guò)代碼控制Toast信息提示框顯示和關(guān)閉的功能。但如果想實(shí)現(xiàn)得更完美,可以在AndroidSDK源代碼中找一個(gè)叫ITransientNotification.aidl的文件(該文件是AIDL服務(wù)定義文件,將在后面詳細(xì)介紹),并在Android工程的src目錄中建一個(gè)android.app包,將這個(gè)文件放到這個(gè)包中。然后ADT會(huì)自動(dòng)在gen目錄中生成了一個(gè)android.app包,包中有一個(gè)ITransientNotification.java文件。由于AndroidSDK自帶的ItransientNotification接口屬于內(nèi)部資源,外部程序無(wú)法訪問(wèn),因此,只能將從Toast對(duì)象中獲得的mTN變量轉(zhuǎn)換成剛才生成的ITransientNotification對(duì)象了。這樣就不需要使反射技術(shù)獲得show和hide方法了。經(jīng)過(guò)改良的顯示和關(guān)閉Toast信息提示框的代碼如下:
ITransientNotificationnotification=(ITransientNotification)field.get(toast);
//顯示Toast信息提示框
notification.show();
//關(guān)閉Toast信息提示框
notification.hide();
- Android開(kāi)發(fā)獲取當(dāng)前系統(tǒng)日期和時(shí)間功能示例
- Android動(dòng)態(tài)顯示當(dāng)前年月日時(shí)分秒系統(tǒng)時(shí)間(示例代碼)
- Android 用Time和Calendar獲取系統(tǒng)當(dāng)前時(shí)間源碼分享(年月日時(shí)分秒周幾)
- Android獲取系統(tǒng)時(shí)間的多種方法
- Android獲取系統(tǒng)時(shí)間以及網(wǎng)絡(luò)時(shí)間
- Android調(diào)用系統(tǒng)時(shí)間格式顯示時(shí)間信息
- 解析android中系統(tǒng)日期時(shí)間的獲取
- Android實(shí)現(xiàn)顯示系統(tǒng)實(shí)時(shí)時(shí)間
相關(guān)文章
Android工具欄頂出轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的實(shí)現(xiàn)方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Android工具欄頂出轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Android ScrollView嵌套ExpandableListView顯示不正常的問(wèn)題的解決辦法
這篇文章主要介紹了Android ScrollView嵌套ExpandableListView顯示不正常的問(wèn)題的解決辦法的相關(guān)資料,需要的朋友可以參考下2017-02-02Android非XML形式動(dòng)態(tài)生成、調(diào)用頁(yè)面的方法
這篇文章主要介紹了Android非XML形式動(dòng)態(tài)生成、調(diào)用頁(yè)面的方法,涉及Android構(gòu)建頁(yè)面的相關(guān)技巧,需要的朋友可以參考下2015-04-04Android實(shí)現(xiàn)在map上畫(huà)出路線(xiàn)的方法
這篇文章主要介紹了Android實(shí)現(xiàn)在map上畫(huà)出路線(xiàn)的方法,較為詳細(xì)的分析了Android在map上繪制路線(xiàn)所涉及的map圖調(diào)用、畫(huà)筆的使用、頁(yè)面布局及權(quán)限控制的相關(guān)技巧,需要的朋友可以參考下2015-07-07Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android項(xiàng)目實(shí)戰(zhàn)之仿網(wǎng)易新聞的頁(yè)面(RecyclerView )
這篇文章主要介紹了Android項(xiàng)目實(shí)戰(zhàn)之仿網(wǎng)易新聞的頁(yè)面,ViewPager作為RecyclerView的Header,感興趣的小伙伴們可以參考一下2016-01-01Android studio 將字符串寫(xiě)入本地的操作方法
本文通過(guò)實(shí)例代碼給大家介紹了Android studio 將字符串寫(xiě)入本地的操作方法,需要的朋友可以參考下2018-07-07Android編程滑動(dòng)效果之Gallery+GridView實(shí)現(xiàn)圖片預(yù)覽功能(附demo源碼下載)
這篇文章主要介紹了Android編程滑動(dòng)效果之Gallery+GridView實(shí)現(xiàn)圖片預(yù)覽功能,結(jié)合實(shí)例形式分析了Android通過(guò)GridView和Gallery兩個(gè)控件模仿Gallery圖像集圖片預(yù)覽功能,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2016-02-02