由于原生带的dialog或者popuwindow弹窗确实有点丑,有时候完成不了UI布局和设计,所以整合了各种各样的popuwindow和dialog,居中,底部,带动画,有阴影,仿iOS效果,自定义布局等,原理都差不多
都是自定义继承popuwindow和dialog写的,实现点击按钮的监听事件,设置动画样式,设置Activity的背景透明度,给出实现点击事件接口,先看效果图:
下载地址:
https://github.com/PangHaHa12138/ManyPopWindowAndDialog
先看Popuwindow
1.超简单的仿ios效果,底部弹出
使用:
final BottomPopupOption bottomPopupOption = new BottomPopupOption(MainActivity.this);
bottomPopupOption.setItemText("拍照","相册");//这里数值个数即条目个数,名字即条目名字
bottomPopupOption.showPopupWindow();
bottomPopupOption.setItemClickListener(new BottomPopupOption.onPopupWindowItemClickListener() {
@Override
public void onItemClick(int position) {
switch (position){
case 0:
Toast.makeText(MainActivity.this,"拍照",Toast.LENGTH_SHORT).show();
bottomPopupOption.dismiss();//点击项目消失的方法
break;
case 1:
Toast.makeText(MainActivity.this,"相册",Toast.LENGTH_SHORT).show();
bottomPopupOption.dismiss();//点击项目消失的方法
break;
}
}
});
代码 其实就是对popuwindow包装了一下,设置弹出的位置和动画,以及背景变暗
package com.panghaha.it.manypopwindowanddialog.View;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.panghaha.it.manypopwindowanddialog.R;
/**
* 从下面出来的仿ios popuwindow
* */
public class BottomPopupOption {
//上下文对象
private Context mContext;
//Title文字
private String mTitle;
//PopupWindow对象
private PopupWindow mPopupWindow;
//选项的文字
private String[] options;
//选项的颜色
private int[] Colors;
//点击事件
private onPopupWindowItemClickListener itemClickListener;
/**
* 一个参数的构造方法,用于弹出无标题的PopupWindow
*
* @param context
*/
public BottomPopupOption(Context context) {
this.mContext = context;
}
/**
* 2个参数的构造方法,用于弹出有标题的PopupWindow
*
* @param context
* @param title 标题
*/
public BottomPopupOption(Context context, String title) {
this.mContext = context;
this.mTitle = title;
}
/**
* 设置选项的点击事件
*
* @param itemClickListener
*/
public void setItemClickListener(onPopupWindowItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
/**
* 设置选项文字
*/
public void setItemText(String... items) {
options = items;
}
/**
* 设置选项文字颜色,必须要和选项的文字对应
*/
public void setColors(int... color) {
Colors = color;
}
/**
* 添加子View
*/
private void addView(View v) {
LinearLayout lin_layout = (LinearLayout) v.findViewById(R.id.layout_popup_add);
//Title
TextView tv_pop_title = (TextView) v.findViewById(R.id.tv_popup_title);
//取消按钮
Button btn_cancel = (Button) v.findViewById(R.id.btn_cancel);
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
if (mTitle != null) {
tv_pop_title.setText(mTitle);
} else {
tv_pop_title.setVisibility(View.GONE);
}
if (options != null && options.length > 0) {
for (int i = 0; i < options.length; i++) {
View item = LayoutInflater.from(mContext).inflate(R.layout.basetools_popup_item, null);
Button btn_txt = (Button) item.findViewById(R.id.btn_popup_option);
btn_txt.setText(options[i]);
if (Colors != null && Colors.length == options.length) {
btn_txt.setTextColor(Colors[i]);
}
final int finalI = i;
btn_txt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (itemClickListener != null) {
itemClickListener.onItemClick(finalI);
}
}
});
lin_layout.addView(item);
}
}
}
/**
* 弹出Popupwindow
*/
public void showPopupWindow() {
View popupWindow_view = LayoutInflater.from(mContext).inflate(R.layout.basetools_popup_bottom, null);
//添加子View
addView(popupWindow_view);
mPopupWindow = new PopupWindow(popupWindow_view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.setAnimationStyle(R.style.popwindow_anim_style);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
setWindowAlpa(false);
}
});
/**
* 防止挡住虚拟键
* */
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
show(popupWindow_view);
}
/**
* 显示PopupWindow
*/
private void show(View v) {
if (mPopupWindow != null && !mPopupWindow.isShowing()) {
mPopupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
}
setWindowAlpa(true);
}
/**
* 消失PopupWindow
*/
public void dismiss() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
}
/**
* 动态设置Activity背景透明度
*
* @param isopen
*/
public void setWindowAlpa(boolean isopen) {
if (Build.VERSION.SDK_INT < 11) {
return;
}
final Window window = ((Activity) mContext).getWindow();
final WindowManager.LayoutParams lp = window.getAttributes();
window.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
ValueAnimator animator;
if (isopen) {
animator = ValueAnimator.ofFloat(1.0f, 0.5f);
} else {
animator = ValueAnimator.ofFloat(0.5f, 1.0f);
}
animator.setDuration(400);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float alpha = (float) animation.getAnimatedValue();
lp.alpha = alpha;
window.setAttributes(lp);
}
});
animator.start();
}
/**
* 点击事件选择回调
*/
public interface onPopupWindowItemClickListener {
void onItemClick(int position);
}
}
2.自定义布局,底部弹出
布局就是普通的能实现需求就行
然后代码
package com.panghaha.it.manypopwindowanddialog.View;
/**
* Created by pang on 2017/4/4.
* 自定义 popupwindow 弹窗
*/
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import com.panghaha.it.manypopwindowanddialog.R;
public class PhotoPopupWindows extends PopupWindow {
private View mMenuView; // PopupWindow 菜单布局
private Context context; // 上下文参数
private OnClickListener myOnClick; // PopupWindow 菜单 空间单击事件
private LinearLayout tubiaotongji;
private LinearLayout renwusousu;
private LinearLayout paixu;
public PhotoPopupWindows(Activity context, OnClickListener myOnClick) {
super(context);
this.context = context;
this.myOnClick = myOnClick;
Init();
}
private void Init() {
// TODO Auto-generated method stub
// PopupWindow 导入
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.popuwindow_chaxun, null);
tubiaotongji = (LinearLayout) mMenuView.findViewById(R.id.tubiaotongji);
renwusousu = (LinearLayout) mMenuView.findViewById(R.id.renwusousu);
paixu = (LinearLayout) mMenuView.findViewById(R.id.paixu);
//图表统计
tubiaotongji.setOnClickListener(myOnClick);
//任务搜索
renwusousu.setOnClickListener(myOnClick);
//排序
paixu.setOnClickListener(myOnClick);
// 导入布局
this.setContentView(mMenuView);
// 设置动画效果
this.setAnimationStyle(R.style.popwindow_anim_style);
//防止虚拟键挡住
this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//设置弹出窗体的 宽,高
this.setWidth(LayoutParams.WRAP_CONTENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
// 设置可触
this.setFocusable(true);
ColorDrawable dw = new ColorDrawable(0x0000000);
this.setBackgroundDrawable(dw);
// 单击弹出窗以外处 关闭弹出窗
mMenuView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int height = mMenuView.findViewById(R.id.pop_layout).getTop();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
if (y < height) {
dismiss();
}
}
return true;
}
});
}
}
上面代码中先是找控件id 设置点击事件,构造方法传点击事件对象
调用;
//展示弹窗 popuwindow 为底部弹出的窗口进行按钮的监听。
private void showPopMenu() {
//弹窗与虚拟键重合
// popMenus.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popMenus = new PhotoPopupWindows(MainActivity.this, myMenusOnClick);
popMenus.showAtLocation(MainActivity.this.findViewById(R.id.main_activity),
Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
}
private View.OnClickListener myMenusOnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
popMenus.dismiss();
switch (v.getId()) {
//图表统计
case R.id.tubiaotongji:
Toast.makeText(MainActivity.this,"图表统计",Toast.LENGTH_SHORT).show();
break;
//任务搜索
case R.id.renwusousu:
Toast.makeText(MainActivity.this,"任务搜索",Toast.LENGTH_SHORT).show();
break;
//排序
case R.id.paixu:
Toast.makeText(MainActivity.this,"排序",Toast.LENGTH_SHORT).show();
break;
}
}
};
3.居中的popuwindow 代码跟上面 差不多,
popMenus2.showAtLocation(MainActivity.this.findViewById(R.id.main_activity),
Gravity.CENTER | Gravity.CENTER_HORIZONTAL, 0, 0);
就是设置位置的时候,设置为center,
4.仿微信右上角的poupwindow
控件代码,其实也是先自定义布局
package com.panghaha.it.manypopwindowanddialog.View;
/**
* Created by pang on 2017/4/4.
* 自定义 popupwindow 弹窗 仿微信下拉选择器
*/
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import com.panghaha.it.manypopwindowanddialog.R;
public class TopPopupWindows extends PopupWindow {
private View mMenuView; // PopupWindow 菜单布局
private Context context; // 上下文参数
private OnClickListener myOnClick; // PopupWindow 菜单 空间单击事件
private LinearLayout zhuzhuang,zhexian;
public TopPopupWindows(Activity context, OnClickListener myOnClick) {
super(context);
this.context = context;
this.myOnClick = myOnClick;
Init();
}
private void Init() {
// TODO Auto-generated method stub
// PopupWindow 导入
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.popuwindow_weixin, null);
zhuzhuang = (LinearLayout) mMenuView.findViewById(R.id.zhu_layout);
zhexian = (LinearLayout) mMenuView.findViewById(R.id.zhexian_layout);
//柱状图
zhuzhuang.setOnClickListener(myOnClick);
//折线图
zhexian.setOnClickListener(myOnClick);
// 导入布局
this.setContentView(mMenuView);
// 设置动画效果
this.setAnimationStyle(R.style.AnimBottom);
//防止虚拟键挡住
this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//设置弹出窗体的 宽,高
this.setWidth(LayoutParams.WRAP_CONTENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
// 设置可触
this.setFocusable(true);
ColorDrawable dw = new ColorDrawable(0x0000000);
this.setBackgroundDrawable(dw);
// 单击弹出窗以外处 关闭弹出窗
mMenuView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int height = mMenuView.findViewById(R.id.pop_layout).getTop();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
if (y < height) {
dismiss();
}
}
return true;
}
});
}
}
用法;
private void ShowTopPopwindow() {
//显示排序弹窗
topPopupWindows = new TopPopupWindows(Pop4.this,myMenusOnClick);
topPopupWindows.showAsDropDown(ChoseModelBut,0,0);
}
private View.OnClickListener myMenusOnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
topPopupWindows.dismiss();
switch (v.getId()) {
//柱状图
case R.id.zhu_layout:
ChoseModelName.setText("柱状图");
jiatu.setImageResource(R.drawable.zhuzhuang);
break;
//折线图
case R.id.zhexian_layout:
ChoseModelName.setText("折线图");
jiatu.setImageResource(R.drawable.zhexian);
break;
}
}
};
注意;
topPopupWindows.showAsDropDown(ChoseModelBut,0,0);
这行代码决定了弹窗显示的位置,第一个参数是你要显示哪个控件下面的对象
即上面柱状图和三个点所在的Linelayout对象,
这里可以换成任何你在上面的view控件 Imageview Imagebutton 随意,只要找到控件id
然后设置在控件底部就ok
5.居中的dialog
package com.panghaha.it.manypopwindowanddialog.View;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.panghaha.it.manypopwindowanddialog.R;
/**
* @author 庞世宇
* @describe 自定义居中弹出dialog
*/
public class CenterDialog extends Dialog implements View.OnClickListener {
private Context context;
private int layoutResID;
/**
* 要监听的控件id
*/
private int[] listenedItems;
private OnCenterItemClickListener listener;
public CenterDialog(Context context, int layoutResID, int[] listenedItems) {
super(context, R.style.MyDialog);
this.context = context;
this.layoutResID = layoutResID;
this.listenedItems = listenedItems;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.setGravity(Gravity.CENTER); // 此处可以设置dialog显示的位置为居中
window.setWindowAnimations(R.style.bottom_menu_animation); // 添加动画效果
setContentView(layoutResID);
// 宽度全屏
WindowManager windowManager = ((Activity) context).getWindowManager();
Display display = windowManager.getDefaultDisplay();
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.width = display.getWidth()*4/5; // 设置dialog宽度为屏幕的4/5
getWindow().setAttributes(lp);
// 点击Dialog外部消失
setCanceledOnTouchOutside(true);
for (int id : listenedItems) {
findViewById(id).setOnClickListener(this);
}
}
public interface OnCenterItemClickListener {
void OnCenterItemClick(CenterDialog dialog, View view);
}
public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
this.listener = listener;
}
@Override
public void onClick(View view) {
dismiss();
listener.OnCenterItemClick(this, view);
}
}
使用;
这里对点击事件先进行了dimiss()方法,所有点击就会消失,可以不用手动dimiss
centerDialog.show();
centerDialog.setOnCenterItemClickListener(new CenterDialog.OnCenterItemClickListener() {
@Override
public void OnCenterItemClick(CenterDialog dialog, View view) {
switch (view.getId()){
case R.id.dialog_sure:
Toast.makeText(MainActivity.this,"确定退出",Toast.LENGTH_SHORT).show();
break;
}
}
});
6.底部弹出的dialog基本一样就不贴代码了
周围变暗的dialog
package com.panghaha.it.manypopwindowanddialog.View;
/**
* Created by pang on 2017/4/4.
* 自定义 dialog对话框
*/
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import com.panghaha.it.manypopwindowanddialog.R;
public class MyDialog extends Dialog {
private LinearLayout xiangce;
private LinearLayout paizhao;
private Context mcontext;
private onPaizhao_OnclickListener onpaizhao_onclickListener;//拍照按钮被点击了的监听器
private onXiangce_OnclickListener onxiangce_onclickListener;//相册按钮被点击了的监听器
/**
* 设置确定按钮的显示内容和监听
*
* @param
* @param
*/
public void set_paizhao_OnclickListener(onPaizhao_OnclickListener paizhao_onclick) {
this.onpaizhao_onclickListener = paizhao_onclick;
}
/**
* 设置取消按钮的显示内容和监听
*
* @param
* @param
*/
public void set_xiangce_OnclickListener( onXiangce_OnclickListener xiangce_onclick) {
this.onxiangce_onclickListener = xiangce_onclick;
}
public MyDialog(Context context) {
super(context, R.style.MyDialog);
this.mcontext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_touxiang);
//按空白处取消动画
setCanceledOnTouchOutside(true);
//初始化界面控件
initView();
//初始化界面控件的事件
initEvent();
}
/**
* 初始化界面的确定和取消监听器
*/
private void initEvent() {
//设置拍照 按钮被点击后,向外界提供监听
paizhao.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onpaizhao_onclickListener != null) {
onpaizhao_onclickListener.paizhao_onClick();
}
}
});
//设置相册 按钮被点击后,向外界提供监听
xiangce.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onxiangce_onclickListener != null) {
onxiangce_onclickListener.xiangce_onClick();
}
}
});
}
/**
* 初始化界面控件
*/
private void initView() {
xiangce = (LinearLayout) findViewById(R.id.xiangce);
paizhao = (LinearLayout) findViewById(R.id.paizhao);
}
/**
* 动态设置Activity背景透明度
*
* @param isopen
*/
public void setWindowAlpa(boolean isopen) {
if (Build.VERSION.SDK_INT < 11) {
return;
}
final Window window = ((Activity) mcontext).getWindow();
final WindowManager.LayoutParams lp = window.getAttributes();
window.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
ValueAnimator animator;
if (isopen) {
animator = ValueAnimator.ofFloat(1.0f, 0.5f);
} else {
animator = ValueAnimator.ofFloat(0.5f, 1.0f);
}
animator.setDuration(400);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float alpha = (float) animation.getAnimatedValue();
lp.alpha = alpha;
window.setAttributes(lp);
}
});
animator.start();
}
/**
* 设置确定按钮和取消被点击的接口
* 相册 拍照
*/
public interface onPaizhao_OnclickListener {
void paizhao_onClick();
}
public interface onXiangce_OnclickListener {
void xiangce_onClick();
}
}
这里留出了手动设置Activity背景透明度的方法
使用;
myDialog = new MyDialog(MainActivity.this);
myDialog.show();
myDialog.setWindowAlpa(true);
myDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
myDialog.setWindowAlpa(false);
}
});
//拍照
myDialog.set_paizhao_OnclickListener(new MyDialog.onPaizhao_OnclickListener() {
@Override
public void paizhao_onClick() {
Toast.makeText(MainActivity.this,"拍照",Toast.LENGTH_SHORT).show();
myDialog.dismiss();
myDialog.setWindowAlpa(false);
}
});
//相册
myDialog.set_xiangce_OnclickListener(new MyDialog.onXiangce_OnclickListener() {
@Override
public void xiangce_onClick() {
Toast.makeText(MainActivity.this,"相册",Toast.LENGTH_SHORT).show();
myDialog.dismiss();
}
});
监听dimiss时候把activity变暗,show的时候取消
7.小火箭弹窗之前写过了,跟5其实原理一样,就是换个背景
最后 感谢阅读
demo地址:https://github.com/PangHaHa12138/ManyPopWindowAndDialog
~have a nice day~