国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

使用反射機(jī)制控制Toast的顯示時(shí)間

2019-10-21 21:39:59
字體:
供稿:網(wǎng)友

本文為大家分享了使用反射機(jī)制控制Toast顯示時(shí)間的具體代碼,供大家參考,具體內(nèi)容如下

1、Toast源碼分析:

      Toast的默認(rèn)view是在transient_notification.xml中定義的一個(gè)TextView,如果需要設(shè)置Toast的界面,可以通過setView方法實(shí)現(xiàn);如果需要設(shè)置Toast默認(rèn)顯示的位置,可以通過setGravity或者setMargin方法進(jìn)行設(shè)置,值得一提的是setMargin方法的參數(shù)范圍是0-1即它是屏幕的百分比,如setMargin(0.1,0.1)。

      Toast 的構(gòu)造函數(shù),會(huì)實(shí)例化TN對(duì)象,TN對(duì)象擁有show和hide兩個(gè)方法,可以控制Toast的顯示和消失。那么又是什么來完成調(diào)用和何時(shí)調(diào)用這兩個(gè)方法的呢?我們可以從Toast的show方法中找到答案:

public void show() {    if (mNextView == null) {      throw new RuntimeException("setView must have been called");    }     INotificationManager service = getService();     String pkg = mContext.getPackageName();     TN tn = mTN;     try {      service.enqueueToast(pkg, tn, mDuration);    } catch (RemoteException e) {      // Empty    }  }

該方法,首先會(huì)判斷待顯示的view對(duì)象是否為null;然后獲取單例的INotificationManager的對(duì)象,最后把當(dāng)前Toast的請(qǐng)求加入到顯示隊(duì)列,同時(shí)把該Toast需要顯示的時(shí)間也傳了進(jìn)去。enqueueToast的方法如下:

public void enqueueToast(java.lang.String pkg, android.app.ITransientNotification callback, int duration) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(pkg);_data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));_data.writeInt(duration);mRemote.transact(Stub.TRANSACTION_enqueueToast, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}

可以看到該方法,通過transact方法調(diào)用了底層代碼,即使用了binder的機(jī)制。service最終根據(jù)duration,調(diào)用TN的show和hide方法顯示和隱藏Toast界面。

2、如何修改Toast的顯示時(shí)間

      Toast默認(rèn)有兩種顯示時(shí)間,分別是LENGTH_SHORT和LENGTH_LONG。如果我們需要Toast顯示的時(shí)間,小于LENGTH_SHORT,那么非常容易實(shí)現(xiàn),直接調(diào)用Toast的cancel方法即可。那么我們?nèi)绻隩oast的顯示時(shí)間大于LENGTH_LONG,那就沒有辦法實(shí)現(xiàn)了,因?yàn)楹问抡{(diào)用TN的hide方法,不是由你控制的。

      下面通過Java的反射機(jī)制,拿到TN的show和hide方法,自己來控制Toast的顯示和隱藏。

 

public class ReflectToast {  Context mContext;   private Toast mToast;  private Field field;  private Object obj;  private Method showMethod, hideMethod;   public ReflectToast(Context c, View v) {    this.mContext = c;    mToast = new Toast(mContext);    mToast.setView(v);     reflectionTN();  }   public void show() {    try {      showMethod.invoke(obj, null);    } catch (Exception e) {      e.printStackTrace();    }  }   public void cancel() {    try {      hideMethod.invoke(obj, null);    } catch (Exception e) {      e.printStackTrace();    }  }   private void reflectionTN() {    try {      field = mToast.getClass().getDeclaredField("mTN");      field.setAccessible(true);      obj = field.get(mToast);      showMethod = obj.getClass().getDeclaredMethod("show", null);      hideMethod = obj.getClass().getDeclaredMethod("hide", null);    } catch (Exception e) {      e.printStackTrace();    }  }

在外部,我們可以調(diào)用ReflectToast的show和cancel方法,來實(shí)現(xiàn)控制Toast的顯示和隱藏。

為了不讓大家再出錯(cuò),給出調(diào)用代碼如下:

public class MainActivity extends Activity {  ReflectToast toast;  boolean isShown = false;    @Override  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    final TextView tView = new TextView(this);    tView.setText("ReflectToast !!!");    toast = new ReflectToast(this, tView);        findViewById(R.id.click).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        if(isShown){          toast.cancel();          isShown = false;        }else{           toast.show();          isShown = true;        }      }    });  }}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 永德县| 德格县| 始兴县| 淅川县| 辰溪县| 博客| 塔城市| 进贤县| 平南县| 越西县| 永胜县| 习水县| 邓州市| 威远县| 汉寿县| 太和县| 房产| 镇原县| 桐城市| 集安市| 九台市| 五指山市| 鄱阳县| 昆明市| 高碑店市| 宿州市| 蓬莱市| 玉林市| 永川市| 易门县| 浏阳市| 桐梓县| 河津市| 皋兰县| 册亨县| 彩票| 鸡泽县| 本溪市| 揭东县| 吉隆县| 六盘水市|