需求如下:当app在后台时 收到push消息用系统的Notification进行通知;当app在前台时 收到push后采用自定义风格弹出通知
效果如下:
第一种情况这里不探究 第二种情况这里采用PopWindow实现
步骤:
一 、实现自定义PopWindow类
public class TuyaPopWindow extends PopupWindow { private Activity mContext; private View view; //private ImageView iv_icon; private TextView tv_title; private TextView tv_content; private Handler mHandler; public TuyaPopWindow(View contentView, final Activity mContext) { super(contentView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, true); this.view = contentView; this.mContext = mContext; L.d("huohuo", "mContext:" + mContext); mHandler = new Handler(mContext.getMainLooper()); //this.iv_icon= (ImageView) contentView.findViewById(R.id.iv_push_icon); this.tv_title = (TextView) contentView.findViewById(R.id.tv_push_title); this.tv_content = (TextView) contentView.findViewById(R.id.tv_push_msg); tv_title.setText("设备:客厅插座"); tv_content.setText("xxxxx"); // 设置外部可点击 // mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框 this.view.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { //int height = view.findViewById(R.id.pop_layout).getTop(); // int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { //if (y < height) { dismiss(); //} } return true; } }); this.setFocusable(false); this.setTouchable(true); this.setOutsideTouchable(false); this.update(); // 实例化一个ColorDrawable颜色为半透明 this.setBackgroundDrawable(new BitmapDrawable()); // 设置弹出窗体的背景 this.setAnimationStyle(R.style.take_photo_anim); this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } public void show() { mHandler.post(new Runnable() { @Override public void run() { //适配8.0系统 TuyaPopWindow.this.showAtLocation((mContext.findViewById(android.R.id.content)), Gravity.NO_GRAVITY, 0, 0); //TuyaPopWindow.this.showAsDropDown(view, 0, 0); } }); //2s 消失 mHandler.postDelayed(new Runnable() { @Override public void run() { TuyaPopWindow.this.dismiss(); } }, 2000); } }
二 、 定义PopWindow弹出位置
TuyaPopWindow.this.showAtLocation((mContext.findViewById(android.R.id.content)), Gravity.NO_GRAVITY, 0, 0);
这里要注意的是不要用这个方法,因为在8.0系统上这样会显示在布局底部,具体原因待探究
TuyaPopWindow.this.showAsDropDown(view, 0, 0);
还有一点在设置popupWindow属性的时候 需要执行设置这个属性
this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
因为在4.0系统上会把状态栏算入布局中 这样会导致popupWindow覆盖掉状态栏
三、定义PopWindow 弹出动画
通过设置PopWindow的属性来实现
this.setAnimationStyle(R.style.take_photo_anim);
这里要用到的是style属性
首先我们需要声明 进入和离开的动画
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="-100%" android:toYDelta="0" /> <alpha android:duration="500" android:fromAlpha="0.5" android:toAlpha="1.0" /> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="0" android:toYDelta="-100%" /> <alpha android:duration="500" android:fromAlpha="1.0" android:toAlpha="0.5" /> </set>
申明style
<style name="take_photo_anim" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/pop_enter_anim</item> <item name="android:windowExitAnimation">@anim/pop_exit_anim</item> </style>
四、由于PopupWindow是依赖于Activity的,所以我们需要记录前台Activity
public class Constant { //前台 activity 栈 private static LinkedList<Activity> foreActivityStack = new LinkedList<>(); public static void attachForeActivity(Activity activity) { if (foreActivityStack.indexOf(activity) == -1) foreActivityStack.push(activity); //Log.e("huohuo","attachForeActivity size:"+foreActivityStack.size()+" push:"+activity); } public static void detachForeActivity(Activity activity) { foreActivityStack.remove(activity); //foreActivityStack.pop(); //Log.e("huohuo","detachForeActivity size:"+foreActivityStack.size()+" pop:"+activity); } public static Activity getForeActivity(){ if(foreActivityStack.isEmpty()) return null; //return foreActivityStack.peek().get(); return foreActivityStack.peek(); } }
我们在每个Activity的onStart() onStop()方法中都调用
Constant.attachForeActivity(this); Constant.detachForeActivity(this);
五、调用
if (Constant.getForeActivity() != null) { //应用在前台 L.d(TAG, "getForeActivity true"); View contentView = LayoutInflater.from(Constant.getForeActivity()).inflate(R.layout.push_custom_layout, null); TuyaPopWindow popWindow = new TuyaPopWindow(contentView,Constant.getForeActivity(), notify); popWindow.show(); }