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

首頁 > 系統 > Android > 正文

使用反射機制控制Toast的顯示時間

2019-12-12 00:33:23
字體:
來源:轉載
供稿:網友

本文為大家分享了使用反射機制控制Toast顯示時間的具體代碼,供大家參考,具體內容如下

1、Toast源碼分析:

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

      Toast 的構造函數,會實例化TN對象,TN對象擁有show和hide兩個方法,可以控制Toast的顯示和消失。那么又是什么來完成調用和何時調用這兩個方法的呢?我們可以從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    }  }

該方法,首先會判斷待顯示的view對象是否為null;然后獲取單例的INotificationManager的對象,最后把當前Toast的請求加入到顯示隊列,同時把該Toast需要顯示的時間也傳了進去。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方法調用了底層代碼,即使用了binder的機制。service最終根據duration,調用TN的show和hide方法顯示和隱藏Toast界面。

2、如何修改Toast的顯示時間

      Toast默認有兩種顯示時間,分別是LENGTH_SHORT和LENGTH_LONG。如果我們需要Toast顯示的時間,小于LENGTH_SHORT,那么非常容易實現,直接調用Toast的cancel方法即可。那么我們如果想Toast的顯示時間大于LENGTH_LONG,那就沒有辦法實現了,因為何事調用TN的hide方法,不是由你控制的。

      下面通過Java的反射機制,拿到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();    }  }

在外部,我們可以調用ReflectToast的show和cancel方法,來實現控制Toast的顯示和隱藏。

為了不讓大家再出錯,給出調用代碼如下:

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;        }      }    });  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武强县| 醴陵市| 武强县| 马龙县| 泽库县| 冕宁县| 河间市| 衡南县| 本溪| 富锦市| 公安县| 宝兴县| 拉孜县| 河北区| 泸西县| 兰西县| 东城区| 江门市| 漯河市| 凌源市| 定边县| 威海市| 和政县| 双峰县| 永年县| 浮山县| 三明市| 武鸣县| 方城县| 泸西县| 德州市| 吴桥县| 武山县| 探索| 泾源县| 南和县| 永安市| 太仓市| 甘南县| 醴陵市| 林芝县|