中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2021-06-28 10:16:36 來源:億速云 閱讀:174 作者:小新 欄目:移動開發

這篇文章主要介紹了如何使用反射機制控制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;
        }
      }
    });
  }
}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“如何使用反射機制控制Toast的顯示時間”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

同江市| 攀枝花市| 山阴县| 定结县| 容城县| 宝应县| 武冈市| 吐鲁番市| 逊克县| 蒲江县| 三穗县| 麦盖提县| 水富县| 溧水县| 故城县| 板桥市| 理塘县| 西丰县| 象州县| 南昌县| 儋州市| 苏州市| 永德县| 隆尧县| 沙坪坝区| 九台市| 芦山县| 东丽区| 庐江县| 东山县| 株洲县| 大渡口区| 吉林省| 横峰县| 保康县| 鄢陵县| 扶绥县| 永安市| 宝应县| 大兴区| 大关县|