Android顶部弹出提示语的三种实现方式:WindowManager、PopupWindow、Toast
16lz
2021-01-26
需求:在主页Activity顶部从上向下滑动出现提示条,且5秒后自动从下向上滑动消失。
自定义布局文件:layout_tips.xml
// layout_tips.xml<LinearLayout android:layout_width="match_parent" android:layout_height="120px" android:paddingStart="20px" android:paddingEnd="20px" android:gravity="center" android:background="#cc000000"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30px" android:layout_marginBottom="30px" android:text="提示语" android:textSize="38px" android:textColor="@android:color/white"/></LinearLayout>
自定义滑动动画:
<style name="popwindowAnimStyle" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/anim_popup_show</item> <item name="android:windowExitAnimation">@anim/anim_popup_exit</item></style>
自定义出现动画:anim_popup_show.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="-120%" android:toYDelta="0" android:duration="400"/></set>
自定义消失动画:anim_popup_exit.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0" android:toYDelta="-120%" android:duration="400"/></set>
一、WindowManager实现
优点:可始终显示在当前Activity内所有Fragment、Dialog之上;
缺点:若切换Activity,则被新Activity覆盖。
View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);if(windowManager != null) { WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |//不拦截页面点击事件 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.gravity = Gravity.TOP; layoutParams.y = (int) getResources().getDimension(R.dimen.y30); layoutParams.height = (int) getResources().getDimension(R.dimen.y119); layoutParams.windowAnimations = R.style.popwindowAnimStyle;//自定义动画 windowManager.addView(contentView, layoutParams); new Handler().postDelayed(new Runnable() { @Override public void run() { if(windowManager != null) { windowManager.removeViewImmediate(contentView); windowManager = null; } } }, 3000);}
二、PopupWindow实现
缺点:会被当前Activity新出现的Fragment、Dialog覆盖。
View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);DisplayMetrics dm = getResources().getDisplayMetrics();PopupWindow popupWindow = new PopupWindow(contentView, dm.widthPixels - contentView.getPaddingStart() * 2, (int) getResources().getDimension(R.dimen.y120));popupWindow.setOutsideTouchable(false);//点击外部区域不消失popupWindow.setTouchable(false);popupWindow.setBackgroundDrawable(null);popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);popupWindow.setAnimationStyle(R.style.popwindowAnimStyle);//自定义动画popupWindow.showAtLocation(tvShopDeviceName, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, (int) getResources().getDimension(R.dimen.y30));//指定顶部位置new Handler().postDelayed(new Runnable() { @Override public void run() { popupWindow.dismiss(); }}, 3000);
三、Toast实现
优点:可始终显示在屏幕最上层,不被新Activity覆盖;
缺点:Android 7.0后无法自定义显示/隐藏动画,默认为渐隐渐现。
View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);Toast videoToast = Toast.makeText(this, "", Toast.LENGTH_LONG);videoToast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, (int) getResources().getDimension(R.dimen.y30));videoToast.setView(contentView);try { Object mTN = getField(videoToast, "mTN"); if(mTN != null) { Object mParams = getField(mTN, "mParams"); if(mParams instanceof WindowManager.LayoutParams) { WindowManager.LayoutParams params = (WindowManager.LayoutParams) mParams; //params.windowAnimations = R.style.popwindowAnimStyle;//自定义动画无效 params.width = dm.widthPixels - contentView.getPaddingStart() * 2; params.height = (int) getResources().getDimension(R.dimen.y120); } }} catch (Exception e){ e.printStackTrace();}videoToast.show();private Object getField(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException{ Field field = object.getClass().getDeclaredField(fieldName); if(field != null) { field.setAccessible(true); return field.get(object); } return null;}
更多相关文章
- 高仿网易4.0新UI框架
- 【Android(安卓)UI】具有弹性的ListView
- 《Android开发艺术探索》第六章Android的Drawable+第七章Android
- android view滑动的几种方法
- Android(安卓)listview指定垂直滑动距离
- Android(安卓)--启动画面制做 png图片-->initlogo.rle
- android 弹性ScrollView(已优化)
- android 动画效果
- Android(安卓)仿联系人菜单,带字母索引,顶部挤压动画,recyclerview