100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > android新消息提醒功能 Android-仿QQ/微信-全局新消息提示

android新消息提醒功能 Android-仿QQ/微信-全局新消息提示

时间:2021-05-20 15:50:17

相关推荐

android新消息提醒功能 Android-仿QQ/微信-全局新消息提示

最近赶项目比较忙,趁周末补点文章。

效果预览:

开发需求:

这个弹窗一般用于新消息展示,需要是全局的,所以采用WindowManager来做,可以显示在其他应用之上。

一般消息弹窗会在几秒内消息,否则会影响用户体验,所以还需要延时关闭。

消息弹出后要给用户选择的机会,所以用户可以手动移除弹窗,这里采用手势来达到取消显示的目的。

撸码:

1.先撸一个类,构造传入上下文,因为待会会用。

public class TitleTextWindow {

private Context mContext;

public TitleTextWindow(Context context) {

mContext = context;

}

}

2.抽取几个必要的方法,然后进行代码编写。

/**

* 向外部暴露显示的方法

*/

public void show(){

}

/**

* 向外部暴露关闭的方法

*/

public void dismiss(){

}

/**

* 视图创建方法

*/

private void createTitleView(){

}

3.将伪代码功能实现。

/**

* 向外部暴露显示的方法

*/

public void show(){

createTitleView();

animShow();

//3S后自动关闭

mHander.sendEmptyMessageDelayed(20, 3000);

}

/**

* 向外部暴露关闭的方法

*/

public void dismiss(){

animDismiss();

}

/**

* 视图创建方法

*/

private void createTitleView(){

//准备Window要添加的View

linearLayout = new LinearLayout(mContext);

final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

linearLayout.setLayoutParams(layoutParams);

View titleView = View.inflate(mContext, R.layout.header_toast, null);//这里是你弹窗的UI

// 为titleView设置Touch事件

linearLayout.setOnTouchListener(this);

linearLayout.addView(titleView);

// 定义WindowManager 并且将View添加到WindowManagar中去

wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

WindowManager.LayoutParams wm_params = new WindowManager.LayoutParams();

wm_params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_FULLSCREEN

| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

//这里需要注意,因为不同系统版本策略不一,所以需要根据版本判断设置type,否则会引起崩溃。

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {//大于android SDK 7.1.1

wm_params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

} else {

wm_params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

}

wm_params.gravity = Gravity.TOP;

wm_params.x = 0;

wm_params.y = 0;

wm_params.format = -3; // 会影响Toast中的布局消失的时候父控件和子控件消失的时机不一致,比如设置为-1之后就会不同步

wm_params.alpha = 1f;

linearLayout.measure(0, 0);

wm_params.height = linearLayout.getMeasuredHeight();

wm.addView(linearLayout, wm_params);

}

4.处理手势,让用户可以手指上拨,划出屏幕。

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

downY = (int) event.getRawY();

break;

case MotionEvent.ACTION_MOVE:

int moveY = (int) event.getRawY();

if (moveY - downY < 0) {//如果是向上滑动

linearLayout.setTranslationY(moveY - downY);

}

break;

case MotionEvent.ACTION_UP:

//达到一定比例后,松开手指将关闭弹窗

if (Math.abs(linearLayout.getTranslationY()) > linearLayout.getMeasuredHeight() / 1.5) {

Log.e("TAG", "回弹");

animDismiss();

} else {

linearLayout.setTranslationY(0);

}

break;

default:

break;

}

return true;

}

5.调用。

TitleTextWindow textWindow=new TitleTextWindow(this);

textWindow.show();

6.完整代码:

import android.animation.Animator;

import android.animation.AnimatorListenerAdapter;

import android.animation.ObjectAnimator;

import android.content.Context;

import android.os.Build;

import android.os.Looper;

import android.os.Message;

import android.util.Log;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.View;

import android.view.WindowManager;

import android.widget.LinearLayout;

import view.peakchao.view.R;

/**

* Created by Chao on -09-08.

*/

public class TitleTextWindow implements View.OnTouchListener {

private Context mContext;

private WindowManager wm;

private LinearLayout linearLayout;

private int downY;

public TitleTextWindow(Context context) {

mContext = context;

}

private android.os.Handler mHander = new android.os.Handler(Looper.myLooper()) {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

animDismiss();

}

};

/**

* 动画,从顶部弹出

*/

private void animShow(){

//使用动画从顶部弹出

ObjectAnimator animator = ObjectAnimator.ofFloat(linearLayout, "translationY", -linearLayout.getMeasuredHeight(), 0);

animator.setDuration(600);

animator.start();

}

/**

* 动画,从顶部收回

*/

private void animDismiss(){

if (linearLayout == null || linearLayout.getParent() == null) {

return;

}

ObjectAnimator animator = ObjectAnimator.ofFloat(linearLayout, "translationY", linearLayout.getTranslationY(), -linearLayout.getMeasuredHeight());

animator.setDuration(600);

animator.start();

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationCancel(Animator animation) {

super.onAnimationCancel(animation);

}

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

//移除HeaderToast (一定要在动画结束的时候移除,不然下次进来的时候由于wm里边已经有控件了,所以会导致卡死)

if (null != linearLayout && null != linearLayout.getParent()) {

wm.removeView(linearLayout);

}

}

@Override

public void onAnimationRepeat(Animator animation) {

super.onAnimationRepeat(animation);

}

@Override

public void onAnimationStart(Animator animation) {

super.onAnimationStart(animation);

}

@Override

public void onAnimationPause(Animator animation) {

super.onAnimationPause(animation);

}

@Override

public void onAnimationResume(Animator animation) {

super.onAnimationResume(animation);

}

});

}

/**

* 向外部暴露显示的方法

*/

public void show(){

createTitleView();

animShow();

//3S后自动关闭

mHander.sendEmptyMessageDelayed(20, 3000);

}

/**

* 向外部暴露关闭的方法

*/

public void dismiss(){

animDismiss();

}

/**

* 视图创建方法

*/

private void createTitleView(){

//准备Window要添加的View

linearLayout = new LinearLayout(mContext);

final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

linearLayout.setLayoutParams(layoutParams);

View titleView = View.inflate(mContext, R.layout.header_toast, null);//这里是你弹窗的UI

// 为titleView设置Touch事件

linearLayout.setOnTouchListener(this);

linearLayout.addView(titleView);

// 定义WindowManager 并且将View添加到WindowManagar中去

wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

WindowManager.LayoutParams wm_params = new WindowManager.LayoutParams();

wm_params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_FULLSCREEN

| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

//这里需要注意,因为不同系统版本策略不一,所以需要根据版本判断设置type,否则会引起崩溃。

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {//大于android SDK 7.1.1

wm_params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

} else {

wm_params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

}

wm_params.gravity = Gravity.TOP;

wm_params.x = 0;

wm_params.y = 0;

wm_params.format = -3; // 会影响Toast中的布局消失的时候父控件和子控件消失的时机不一致,比如设置为-1之后就会不同步

wm_params.alpha = 1f;

linearLayout.measure(0, 0);

wm_params.height = linearLayout.getMeasuredHeight();

wm.addView(linearLayout, wm_params);

}

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

downY = (int) event.getRawY();

break;

case MotionEvent.ACTION_MOVE:

int moveY = (int) event.getRawY();

if (moveY - downY < 0) {//如果是向上滑动

linearLayout.setTranslationY(moveY - downY);

}

break;

case MotionEvent.ACTION_UP:

//达到一定比例后,松开手指将关闭弹窗

if (Math.abs(linearLayout.getTranslationY()) > linearLayout.getMeasuredHeight() / 1.5) {

Log.e("TAG", "回弹");

animDismiss();

} else {

linearLayout.setTranslationY(0);

}

break;

default:

break;

}

return true;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。