小菜最近遇到一个需求,需要把Toast显示在指定View的正中央,一番研究发现Toast的方法里只有setGravity(int gravity, int xOffset, int yOffset)可以使用,而这个需求需要获取到Toast的自身宽度才能确定xOffset的值,而小菜发现Toast只有show之后才能获取到Toast.getView()的宽度,这时候已经晚了,那难道就没有什么好办法了么?就在小菜打算弃用Toast,改用Dialog之时,突然灵机一动,想到一个妙招,代码如下:
final Toast toast = Toast.makeText(mActivity, R.string.delete_complete, Toast.LENGTH_SHORT);
LayoutInflater inflate = (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflate.inflate(R.layout.toast_view, null);
view.setAlpha(0f);
toast.setView(view);
toast.getView().getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
toast.getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
final Toast toast1 = Toast.makeText(mActivity, R.string.delete_complete, Toast.LENGTH_SHORT);
view.setAlpha(1.0f);
toast1.setView(view);
toast1.setGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mView.getMeasuredWidth()/2-
toast.getView().getMeasuredWidth()/2, 0);
toast1.show();
}
});
((TextView)toast.getView().findViewById(R.id.tv_message_toast)).setText(R.string.delete_complete);
toast.show();
toast.cancel();
原理:我们先new好一个Toast,让其自定义View的透明度为0,show之后立即cancel,这样用户是看不到这个toast的,接着在getViewTreeObserver监听中我们重新new一个toast,自定义的View透明度设为1.0,这时候自定义的View的宽高已经获取到了,xOffset当然就可以计算了!于是Toast就显示在我们指定的View正中央了.(因为我指定的View布局Height刚好是matchParent,顶格且位于屏幕最右侧,读者可适当修改上述代码即可适配自己的代码,若有错误或者新的解决方法还请读者指出,谢谢!)