时间:2020-12-27 16:05:21 | 栏目:Android代码 | 点击:次
一丶概述
弹框在Android项目中经常出现,常见的实现方法有三种:Dialog 弹框,Window弹框,Activity伪弹框。本文就说一说三种弹框的实现及在项目中的运用。
二丶演示图
图一为常见的三种弹框(文末上链接),图二为项目中用到的Activity伪弹框
三丶正文
1.Dialog弹框
先看一篇一篇文章:
android 8种对话框(Dialog)使用方法汇总
Dialog是系统自带的弹框,然而常常因为UI不好看而遭嫌弃,常需要自定义
public class MyDialog extends Dialog implements android.view.View.OnClickListener { private Context mContext; private String mTitle; private String mDetail; private TextView mTextTitle; private TextView mTextDetail; private TextView mButtonYes; private TextView mButtonNo; private onClickInterface mOnclClickInterface; public MyDialog(Context context, String title, String detail) { super(context, R.style.MyDialogStyle); this.mContext = context; this.mTitle = title; this.mDetail = detail; } @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); initView(); } private void initView() { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.layout_dialog, null); setContentView(view); mButtonYes = (TextView) view.findViewById(R.id.dialog_yes); mButtonNo = (TextView) view.findViewById(R.id.dialog_no); mTextTitle = (TextView) view.findViewById(R.id.dialog_title); mTextDetail = (TextView) view.findViewById(R.id.dialog_detail); mTextTitle.setText(mTitle); mTextDetail.setText(mDetail); mButtonYes.setOnClickListener(this); mButtonNo.setOnClickListener(this); } public interface onClickInterface { public void clickYes(); public void clickNo(); } public void setOnClickInterface(onClickInterface onclClickInterface) { this.mOnclClickInterface = onclClickInterface; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.dialog_yes: mOnclClickInterface.clickYes(); break; case R.id.dialog_no: mOnclClickInterface.clickNo(); break; default: break; } } }
这里就是:1.绑定布局 2.设置监听,监听接口
主要说一下布局里的stytle(悬浮在Activity上,模糊显示就是在这里控制)
<style name="MyDialogStyle"> <item name="android:windowBackground">@android:color/transparent</item> <!--设置dialog的背景--> <item name="android:windowFrame">@null</item> <!--Dialog的windowFrame框为无--> <item name="android:windowNoTitle">true</item> <!--是否有title--> <item name="android:windowIsFloating">true</item> <!--是否浮现在activity之上--> <item name="android:windowIsTranslucent">false</item> <!--是否半透明--> <item name="android:windowContentOverlay">@null</item> <!--对话框是否有遮盖,这个不设置的话,可能会出现边框黑线--> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <!--动画--> <item name="android:backgroundDimEnabled">true</item> <!-- 背景是否模糊显示--> </style>
Dialog弹框一般用于,网络数据加载显示,或交互较少的弹框(基本被新下拉刷新控件SwipeRefreshLayout替代)
2.Window弹框
public class MyWindow { private Context mContext; private WindowManager mwinWindowManager; private View mView; private static boolean isShow = false; public MyWindow(Context context) { mContext = context.getApplicationContext(); } public void showMyWindow() { if (isShow) { return; } mwinWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); //设置WindowManager.LayoutParams的属性 WindowManager.LayoutParams params = new WindowManager.LayoutParams(); //类型 params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; //flags //如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View没焦点,收不到Back键的事件 //当按Back、Home键时,背景应用退出,弹出的view就可以悬浮在桌面了。 params.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; params.format = PixelFormat.TRANSLUCENT; params.width = LayoutParams.MATCH_PARENT; params.height = LayoutParams.MATCH_PARENT; params.gravity = Gravity.CENTER; //初始化View mView = initView(mContext); //点击back键,关闭window mView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { Log.d("wxx", "onKey"); switch (keyCode) { case KeyEvent.KEYCODE_BACK: Log.d("wxx", "onKey BACK"); hideMyWindow(); return true; default: return false; } } }); mwinWindowManager.addView(mView, params); isShow = true; } private View initView(Context context) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.layout_window, null); Button btnYes = (Button) view.findViewById(R.id.window_yes); btnYes.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "Window yes!", Toast.LENGTH_LONG).show(); hideMyWindow(); } }); Button btnNO = (Button) view.findViewById(R.id.window_no); btnNO.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "Window No!", Toast.LENGTH_LONG).show(); hideMyWindow(); } }); //点击window窗口外围,关闭window final View wView = view.findViewById(R.id.view_layout); view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); Rect rect = new Rect(); wView.getGlobalVisibleRect(rect); if (!rect.contains(x, y)) { hideMyWindow(); } return false; } }); return view; } public void hideMyWindow() { if (isShow && mView != null) { mwinWindowManager.removeView(mView); isShow = false; } } }
这个就厉害了,展现,隐藏,点击监听都是自己写的方法,原来点击窗口外关闭窗口是这样实现的,是不是又学到了
然后是关于:
android Window WindowManager 整理
主要用于自定义控件,比如说下拉框:
自定义spinner下拉框
3.Activity伪弹框
public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.layout_activity); } @Override public boolean onTouchEvent(MotionEvent event) { this.finish(); return true; } public void YesButton(View v) { this.finish(); Toast.makeText(getApplicationContext(), "Yes, Hunman is Activity", Toast.LENGTH_LONG).show(); } public void NoButton(View v) { this.finish(); Toast.makeText(getApplicationContext(), "No, Hunman is not Activity", Toast.LENGTH_LONG).show(); } }
简单得不能再简单,跳转跳转到另一个Activity
注意点Activity主题(控制Activity为弹框样式):
<activity android:name="com.wuxianxi.hunman.smallwindows.MyActivity" android:theme="@style/MyActivityStyle" > </activity> <style name="MyActivityStyle"> <item name="android:windowBackground">@android:color/transparent</item> <!--设置dialog的背景--> <item name="android:windowFrame">@null</item> <!--Dialog的windowFrame框为无--> <item name="android:windowNoTitle">true</item> <!--是否有title--> <item name="android:windowIsFloating">true</item> <!--是否浮现在activity之上--> <item name="android:windowIsTranslucent">true</item> <!--是否半透明--> <item name="android:windowContentOverlay">@null</item> <!--对话框是否有遮盖,这个不设置的话,可能会出现边框黑线--> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <!--动画--> <item name="android:backgroundDimEnabled">true</item> <!-- 背景是否模糊显示--> </style>
Activity伪弹框最常用,用于交互,操作较复杂的弹框,如图二
补充这里可通过方法控制Activity弹框宽比
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** 设置宽度为屏幕的0.9*/ WindowManager windowManager = getWindowManager(); /* 获取屏幕宽、高 */ Display display = windowManager.getDefaultDisplay(); /* 获取对话框当前的参数值 */ WindowManager.LayoutParams p = getWindow().getAttributes(); /* 宽度设置为屏幕的0.9 */ p.width = (int) (display.getWidth() * 0.9); /* 设置透明度,0.0为完全透明,1.0为完全不透明 */ p.alpha = 0.95f; /* 设置布局参数 */ getWindow().setAttributes(p); // getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, // ViewGroup.LayoutParams.WRAP_CONTENT); /* 设置点击弹框外部不可消失 */ setFinishOnTouchOutside(false); }
最后贴上MainActivity
public class MainActivity extends ActionBarActivity implements OnClickListener { private Button btnWindow; private Button btnDialog; private Button btnActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { btnWindow = (Button) findViewById(R.id.btn_window); btnDialog = (Button) findViewById(R.id.btn_dialog); btnActivity = (Button) findViewById(R.id.btn_activity); btnWindow.setOnClickListener(this); btnDialog.setOnClickListener(this); btnActivity.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_window: MyWindow myWindow = new MyWindow(this); myWindow.showMyWindow(); break; case R.id.btn_dialog: //注意下面第一个参数不能为getApplicationContext(),而应该是Activity, 因为办有activity才能添加窗口 final MyDialog dialog = new MyDialog(MainActivity.this, "Hunman - Dialog", "Hunman is a Dialog\nYes or No!"); dialog.show(); dialog.setOnClickInterface(new MyDialog.onClickInterface() { @Override public void clickYes() { dialog.dismiss(); Toast.makeText(getApplicationContext(), "Yes, Hunman is Dialog", Toast.LENGTH_LONG).show(); } @Override public void clickNo() { dialog.dismiss(); Toast.makeText(getApplicationContext(), "Yes, Hunman is not Dialog", Toast.LENGTH_LONG).show(); } }); break; case R.id.btn_activity: Intent intent3 = new Intent(MainActivity.this, MyActivity.class); startActivity(intent3); break; default: break; } } }