各种Popwindow和Dialog的汇总以及仿ios的,可以自定义布局,也可以傻瓜式的代码生成,使用非常方便
由于原生带的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.自定义布局,底部弹出
布局就是普通的能实现需求就行
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal"> <LinearLayout android:id="@+id/pop_layout" android:layout_marginBottom="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/renwumiaoshu_bg" android:gravity="center_horizontal" android:orientation="vertical"> <LinearLayout android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:id="@+id/tubiaotongji" android:gravity="center_vertical" android:orientation="horizontal" android:clickable="true" android:background="?android:attr/selectableItemBackground" android:layout_width="match_parent" android:layout_height="42dp"> <ImageView android:layout_marginLeft="10dp" android:src="@drawable/tab_but_tubiao_2x" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="图表统计" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <View android:layout_gravity="center_horizontal" android:background="#a8a8a8" android:layout_width="320dp" android:layout_height="0.5dp"/> <LinearLayout android:layout_marginRight="5dp" android:layout_marginLeft="5dp" android:id="@+id/renwusousu" android:gravity="center_vertical" android:orientation="horizontal" android:clickable="true" android:background="?android:attr/selectableItemBackground" android:layout_width="match_parent" android:layout_height="42dp"> <ImageView android:layout_marginLeft="10dp" android:src="@drawable/tab_but_sousuo_2x" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="任务搜索" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <View android:layout_gravity="center_horizontal" android:background="#a8a8a8" android:layout_width="320dp" android:layout_height="0.5dp"/> <LinearLayout android:layout_marginRight="5dp" android:layout_marginLeft="5dp" android:id="@+id/paixu" android:gravity="center_vertical" android:orientation="horizontal" android:clickable="true" android:background="?android:attr/selectableItemBackground" android:layout_width="match_parent" android:layout_height="42dp"> <ImageView android:layout_marginLeft="10dp" android:src="@drawable/tab_but_paixu_2x" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="排序" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </RelativeLayout>
然后代码
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~