不依赖具体activity弹出全局性弹窗

1.全局弹窗的几种方式

在软件开发当中经常遇到需要全局性弹窗,比如用户在使用软件时被挤下线了、有软件需要强制更新或者消息来了需要及时处理性弹窗,无论软件当前在
哪个页面,都要即时弹出对话框。此种情况下要弹出弹窗,有一下几种方式可以实现:
(1). 第一个方法利用系统AlertDialog弹出dialog,不过样式有点不优雅,也需要AndroidManifest.xml中注册SYSTEM_ALERT_WINDOW权限
(2).第二种利用WindowManager弹出悬浮窗,但是WindowManager弹出悬浮窗需要根据sdk版本设置LayoutParams.type样式,并且也需要到 AndroidManifest.xml中 注册YSTEM_ALERT_WINDOW权限,有一点需要注意的是在android 6.0版本,系统悬浮窗权限默认关闭,需要到对应的应用中开启,或者代码检测权限,用户点击授权才可以。
(3).第三种更activity相关,有两种实现方案,第一种在baseActivity中onStart注册广播,在页面onStop方法中注销,通知当前界面弹出对话框。第二种利用activity,把activity样式设置为透明对话框样式, 把activity的背景设置为透明的,然后启动activity即可。

2.利用系统对话框AlertDialog的简单实现

 alter为AlertDialog类型对象,注意要在alter.show()语句前加入
  alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 
 然后在AndroidManifest.xml中加入权限:
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission> 
 下面是简单实例:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.drawable.ic);
builder.setTitle("标题");
builder.setMessage("消息");
builder.setPositiveButton(R.string.btn_update, new OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        //增加按钮,回调事件
    }
);
builder.setCancelable(false);//弹出框不可以换返回键取消
AlertDialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//将弹出框设置为全局
dialog.setCanceledOnTouchOutside(false);//失去焦点不会消失
dialog.show();

3.利用WindowManager弹出悬浮窗

   通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得WindowManager对象。
   每一个WindowManager对象都和一个特定的Display绑定。
   想要获取一个不同的display的WindowManager,可以用 createDisplayContext(Display)来获取那个displayContext,之后再使用:Context.getSystemService(Context.WINDOW_SERVICE)来获取WindowManager

     调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。

    下面是简单实例:

package com.mg.view.manager;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;

import com.mg.common.dispath.CommonAdvController;

public abstract class BaseWindowManager {
	public WindowManager manager;
	public Context context;
	public LayoutParams params;
	public int PARAMS_TYPE;
	public boolean isFinish = false;
	public static Map<View, Integer> showViewMap = new HashMap<View, Integer>();
	public String imagePath = "";
	public Bitmap bitmap, bitmapCorner;
	public FrameLayout mContainer;

	public BaseWindowManager(Context context) {
		this.context = context;
		if (android.os.Build.VERSION.SDK_INT >= 19) {
			PARAMS_TYPE = LayoutParams.TYPE_TOAST;
		} else {
			PARAMS_TYPE = LayoutParams.TYPE_PHONE;
		}
		if (manager == null) {
			manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		}
		if (params == null) {
			params = new LayoutParams();
			switch (getManagerType()) {
			case fallType:
				params.width = LayoutParams.WRAP_CONTENT;
				params.height = LayoutParams.WRAP_CONTENT;
				params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_LAYOUT_NO_LIMITS | LayoutParams.FLAG_NOT_FOCUSABLE;
				params.gravity = Gravity.TOP | Gravity.LEFT;
				params.format = PixelFormat.TRANSLUCENT;
				params.windowAnimations = android.R.style.Animation_Translucent;
				break;
			case floatType:
				params.width = LayoutParams.MATCH_PARENT;
				params.height = LayoutParams.WRAP_CONTENT;
				params.flags = LayoutParams.FLAG_FULLSCREEN | LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
						| LayoutParams.FLAG_NOT_FOCUSABLE;
				params.format = PixelFormat.TRANSLUCENT;
				params.windowAnimations = android.R.style.Animation_Translucent;
				break;
			case coverType:
				params.width = LayoutParams.MATCH_PARENT;
				params.height = LayoutParams.MATCH_PARENT;
				params.gravity = Gravity.CENTER;
				params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL;
				params.format = PixelFormat.TRANSLUCENT;
				params.windowAnimations = android.R.style.Animation_Translucent;
				break;
			default:
				break;
			}
			params.type = PARAMS_TYPE;
		}
	}

	/**
	 * 显示View
	 * 
	 */
	public void onShowView(Intent intent) {
		CommonAdvController.getInstance(context).onStart();
		isFinish = false;
	}

	/**
	 * 获取加入WindowManager的view
	 * 
	 * @return
	 */
	public abstract View getShowView();

	/**
	 * 
	 */
	public void finish() {
		onAdvFinish();
		if (bitmapCorner != null) {
			bitmapCorner.recycle();
			bitmapCorner = null;
		}
		if (bitmap != null) {
			bitmap.recycle();
			bitmap = null;
		}
		View view = (View) getShowView();
		if (view != null && showViewMap.containsKey(view)) {
			try {
				manager.removeViewImmediate(view);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			}
			showViewMap.remove(view);
			view = null;
		}
		clearManagerAllView();
		System.gc();
	}

	/**
	 * 清楚所有managerview
	 */
	public synchronized void clearManagerAllView() {
		if (!showViewMap.isEmpty() && showViewMap.size() > 0) {
			for (View baseView : showViewMap.keySet()) {
				if (baseView != null) {
					manager.removeViewImmediate(baseView);
				}
			}
			showViewMap.clear();
		}
	}

	/**
	 * 结束显示
	 * 
	 * @param intent
	 */
	public void onAdvFinish() {
		CommonAdvController.getInstance(context).onStop();
	}

	/**
	 * @author ChenDs floatType:浮窗类型 coverType:覆盖类型 fallType:下坠类型
	 */
	public enum ManagerType {
		floatType, coverType, fallType
	}
	public abstract ManagerType getManagerType();
}

4.利用透明样式的activity实现全局弹窗样式

    把activity样式在AndroidManifest.xml中设置android:theme="@android:style/Theme.Translucent"样式,然后通过启动该activity即可,启动activity代码实例如下:
package com.mg.view.utils;

import android.content.Context;
import android.content.Intent;

import com.mg.view.ui.BaseUiActivity;

public class IntentUtils {
	/**
	 * 获取一个带baseui的intent
	 * 
	 * @param Context
	 * @return
	 */
	public static Intent getBaseUiIntent(Context Context, Class<?> cls) {
		Intent intent = new Intent(Context, BaseUiActivity.class);
		intent.putExtra(BaseUiActivity.EXTRA_KEY_UI_CLASS, cls.getName());
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
		intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
		return intent;
	}
}
   activity具体封装代码样例:
package com.mg.view.ui;

import java.lang.reflect.Constructor;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

import com.mg.common.dispath.CommonAdvController;
import com.mg.view.manager.ActivityManager;

public class BaseUiActivity extends Activity {
	public static String EXTRA_KEY_UI_CLASS = new String(new byte[] { 99, 108, 97, 115, 115, 86, 105, 101, 119, 78, 97, 109, 101 }); // classViewName
	private BaseUiView mBaseUIVIew;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Intent intent = getIntent();
		// 反射创建对象
		try {
			Class<?> classType = Class.forName(intent.getStringExtra(EXTRA_KEY_UI_CLASS));
			Constructor<?> con = classType.getConstructor(Context.class, Intent.class);
			mBaseUIVIew = (BaseUiView) con.newInstance(this, intent);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (mBaseUIVIew == null) {
			finish();
		} else {
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			if (mBaseUIVIew.setFullScreenSwitch()) {
				getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
			}
			setContentView(mBaseUIVIew);
			ActivityManager.getManager().addActivity(this);
			mBaseUIVIew.getIntentData(getIntent());
			mBaseUIVIew.onCreate();
		}
	}

	@Override
	protected void onStart() {
		super.onStart();
		CommonAdvController.getInstance(this).onStart();
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onStart();
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onResume();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onPause();
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		CommonAdvController.getInstance(this).onStop();
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onStop();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onDestroy();
		}
		if (ActivityManager.getManager().hasActivity()) {
			ActivityManager.getManager().removeCurrentActivityStack();
		}
		System.gc();
		mBaseUIVIew = null;
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onNewIntent(intent);
		}
	}

	@Override
	public void onBackPressed() {
		if (mBaseUIVIew != null && mBaseUIVIew.setBackPressedSwitch()) {
			super.onBackPressed();
			return;
		}
		if (mBaseUIVIew != null) {
			mBaseUIVIew.onBackPressed();
		}
	}

	@Override
	public void finish() {
		super.finish();
	}

}
转载请说明出处:http://blog.csdn.net/u012438830/article/details/78451575
以上是全部事例,具体实现请根据各自的需求实现。
下面是本人的具体代码事例demo,需要的到请下载






  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用以下代码来实现弹出PopupWindow,并添加背景遮罩以及点击遮罩时弹窗消失。 首先,在你的布局文件(例如activity_main.xml)中添加一个透明的背景遮罩视图: ```xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Your main layout content here --> <View android:id="@+id/background_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" /> </FrameLayout> ``` 然后,在你的Activity或Fragment中的代码中,添加以下方法来显示和隐藏PopupWindow: ```java public class MainActivity extends AppCompatActivity { private PopupWindow popupWindow; private View backgroundView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); backgroundView = findViewById(R.id.background_view); // 设置背景遮罩点击事件 backgroundView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismissPopupWindow(); } }); // 显示PopupWindow showPopupWindow(); } private void showPopupWindow() { // 创建PopupWindow视图 LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View popupView = inflater.inflate(R.layout.popup_window, null); // 设置PopupWindow的属性 popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setFocusable(true); popupWindow.setOutsideTouchable(true); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // 显示PopupWindow popupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0); } private void dismissPopupWindow() { // 隐藏PopupWindow if (popupWindow != null && popupWindow.isShowing()) { popupWindow.dismiss(); } } } ``` 最后,创建一个popup_window.xml资源文件来定义PopupWindow的布局: ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="vertical" android:padding="16dp"> <!-- Your PopupWindow content here --> </LinearLayout> ``` 这样,当你的Activity或Fragment启动时,PopupWindow将显示在屏幕中央,并且点击背景遮罩时PopupWindow将被隐藏。请根据你的需要修改布局和样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值