国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 乐亭县| 安吉县| 光山县| 盖州市| 乃东县| 阿克苏市| 临漳县| 稻城县| 乌拉特前旗| 黎城县| 贺州市| 乡宁县| 七台河市| 龙州县| 叶城县| 濮阳市| 阿拉尔市| 江油市| 弋阳县| 汪清县| 博乐市| 绵阳市| 新河县| 南阳市| 陇南市| 阳江市| 五家渠市| 顺义区| 东宁县| 兴化市| 凤阳县| 夏津县| 维西| 博客| 富源县| 平果县| 新巴尔虎右旗| 丹东市| 广平县| 阳原县| 汪清县|