一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - Android開(kāi)發(fā)技巧之永不關(guān)閉的Toast信息框(長(zhǎng)時(shí)間顯示而非系統(tǒng)關(guān)閉)

Android開(kāi)發(fā)技巧之永不關(guān)閉的Toast信息框(長(zhǎng)時(shí)間顯示而非系統(tǒng)關(guān)閉)

2021-01-05 12:03Android開(kāi)發(fā)網(wǎng) Android

Toast信息提示框之所以在顯示一定時(shí)間后會(huì)自動(dòng)關(guān)閉,是因?yàn)樵谙到y(tǒng)中有一個(gè)Toast隊(duì)列;那么有些時(shí)候需要這個(gè)Toast信息提示框長(zhǎng)時(shí)間顯示,直到需要關(guān)閉它時(shí)通過(guò)代碼來(lái)控制,而不是讓系統(tǒng)自動(dòng)來(lái)關(guān)閉Toast信息提示框

Toast信息提示框之所以在顯示一定時(shí)間后會(huì)自動(dòng)關(guān)閉,是因?yàn)樵谙到y(tǒng)中有一個(gè)Toast隊(duì)列。系統(tǒng)會(huì)依次從隊(duì)列中取(出隊(duì)列)一個(gè)Toast,并顯示它。在顯示一段時(shí)間后,再關(guān)閉,然后再顯示下一個(gè)Toast信息提示框。直到Toast隊(duì)列中所有Toast都顯示完為止。那么有些時(shí)候需要這個(gè)Toast信息提示框長(zhǎng)時(shí)間顯示,直到需要關(guān)閉它時(shí)通過(guò)代碼來(lái)控制,而不是讓系統(tǒng)自動(dòng)來(lái)關(guān)閉Toast信息提示框。不過(guò)這個(gè)要求對(duì)于Toast本身來(lái)說(shuō)有些過(guò)分,因?yàn)門(mén)oast類并沒(méi)有提供這個(gè)功能。雖然如此,但方法總比問(wèn)題多。通過(guò)一些特殊的處理還是可以實(shí)現(xiàn)這個(gè)功能的,而且并不復(fù)雜。

從7.3.1節(jié)的內(nèi)容可以知道,Toast信息提示框需要調(diào)用Toast.show方法來(lái)顯示。下面來(lái)看一下show方法的源代碼。

復(fù)制代碼 代碼如下:


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ù)雜,可以很容易找到如下的代碼。

復(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類找一下還有沒(méi)有其他的show方法。結(jié)果發(fā)現(xiàn)了一個(gè)TN類,該類是Toast的一個(gè)內(nèi)嵌類。在TN類中有一個(gè)show方法。TN是ITransientNotification.Stub的子類。從ITransientNotification和TN類中的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類型,外部無(wú)法訪問(wèn)。不過(guò)別著急。在Toast類中有一個(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信息提示框。

復(fù)制代碼 代碼如下:


//先創(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的方法類似,只是需要獲得hide方法,代碼如下:

復(fù)制代碼 代碼如下:


try
{
//需要將前面代碼中的obj變量變成類變量。這樣在多個(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信息提示框的代碼如下:

復(fù)制代碼 代碼如下:


ITransientNotificationnotification=(ITransientNotification)field.get(toast);
//顯示Toast信息提示框
notification.show();
//關(guān)閉Toast信息提示框
notification.hide();

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 极限淫生小说 | 国产精品久久国产精品99 gif | 草莓香蕉榴莲丝瓜秋葵绿巨人在线看 | 国产女乱淫真高清免费视频 | 欧美洲大黑香蕉在线视频 | 好大~好爽~再进去一点 | 含羞草传媒一天免费看下 | 精品久久免费视频 | 亚洲成在人线久久综合 | 96免费精品视频在线 | 日韩欧美亚洲每日更新网 | av中文字幕网免费观看 | 国产女主播福利在线 | 久久免费看少妇级毛片蜜臀 | 手机在线伦理片 | 国产精品国产三级在线专区 | 动漫美女人物被黄漫小说 | 久久免费国产 | 国产大神91一区二区三区 | 狐媚小说 | 国产女乱淫真高清免费视频 | 色综合天天综合中文网 | 青草视频在线观看免费网站 | 视频一区二区三区欧美日韩 | 1024免费永久福利视频 | 黄篇网站在线观看 | 双龙高h| 国产肥臀 | 免费看一级 | 美女gif趴跪式抽搐动态图 | 亚洲国产在线99视频 | 污到湿的爽文免费阅读 | 亚洲成a人片777777久久 | 无码射肉在线播放视频 | t66y地址一地址二地址三 | 91亚洲一区二区在线观看不卡 | 亚洲免费国产 | 国产经典一区 | 精品国产免费第一区二区三区日韩 | 成人伊人青草久久综合网破解版 | 奇米影视7777|