PopupWindow 模拟通知弹出

最近遇到一个需求,下面记录下实现方法 以及遇到的一些坑

需求如下:当app在后台时 收到push消息用系统的Notification进行通知;当app在前台时 收到push后采用自定义风格弹出通知

效果如下:
[img]http://dl2.iteye.com/upload/attachment/0127/2715/7b2c00ab-36fa-3643-a00a-5c89290e29d3.gif[/img]

第一种情况这里不探究 第二种情况这里采用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();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值