Skip to content

Instantly share code, notes, and snippets.

@chiemy
Created November 22, 2016 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chiemy/0be2eadf17e5510e153d441b8dbf9391 to your computer and use it in GitHub Desktop.
Save chiemy/0be2eadf17e5510e153d441b8dbf9391 to your computer and use it in GitHub Desktop.
/**
* Created: chiemy
* Date: 16/11/22
* Description: 可控制显示时长, 可点击的Toast
*/
public class ExtendToast {
public static final int LENGTH_ALWAYS = 0;
public static final int LENGTH_SHORT = 2;
private Toast toast;
private Context mContext;
private int mDuration = LENGTH_SHORT;
private int animations = -1;
private boolean isShow = false;
private Object mTN;
private Method show;
private Method hide;
private WindowManager.LayoutParams params;
private View mView;
private Handler handler = new Handler();
public ExtendToast(Context context, @NonNull View contentView){
this.mContext = context;
if (toast == null) {
toast = new Toast(mContext);
}
mView = contentView;
}
private Runnable hideRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
/**
* Show the view for the specified duration.
*/
public void show(){
if (isShow) return;
toast.setView(mView);
initTN();
try {
show.invoke(mTN);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
isShow = true;
//判断duration,如果大于#LENGTH_ALWAYS 则设置消失时间
if (mDuration > LENGTH_ALWAYS) {
handler.postDelayed(hideRunnable, mDuration * 1000);
}
}
/**
* Close the view if it's showing, or don't show it if it isn't showing yet.
* You do not normally have to call this. Normally view will disappear on its own
* after the appropriate duration.
*/
public void hide(){
if(!isShow) return;
try {
hide.invoke(mTN);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
isShow = false;
}
public void setView(View view) {
toast.setView(view);
}
public View getView() {
return toast.getView();
}
/**
* Set how long to show the view for.
* @see #LENGTH_SHORT
* @see #LENGTH_ALWAYS
*/
public void setDuration(int duration) {
mDuration = duration;
}
public int getDuration() {
return mDuration;
}
public void setMargin(float horizontalMargin, float verticalMargin) {
toast.setMargin(horizontalMargin, verticalMargin);
}
public float getHorizontalMargin() {
return toast.getHorizontalMargin();
}
public float getVerticalMargin() {
return toast.getVerticalMargin();
}
public void setGravity(int gravity, int xOffset, int yOffset) {
toast.setGravity(gravity,xOffset,yOffset);
}
public int getGravity() {
return toast.getGravity();
}
public int getXOffset() {
return toast.getXOffset();
}
public int getYOffset() {
return toast.getYOffset();
}
public int getAnimations() {
return animations;
}
public void setAnimations(int animations) {
this.animations = animations;
}
private void initTN() {
try {
Field tnField = toast.getClass().getDeclaredField("mTN");
tnField.setAccessible(true);
mTN = tnField.get(toast);
show = mTN.getClass().getMethod("show");
hide = mTN.getClass().getMethod("hide");
Field tnParamsField = mTN.getClass().getDeclaredField("mParams");
tnParamsField.setAccessible(true);
params = (WindowManager.LayoutParams) tnParamsField.get(mTN);
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
/**设置动画*/
if (animations != -1) {
params.windowAnimations = animations;
}
/**调用tn.show()之前一定要先设置mNextView*/
Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView");
tnNextViewField.setAccessible(true);
tnNextViewField.set(mTN, toast.getView());
} catch (Exception e) {
e.printStackTrace();
}
setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment