自学Android做项目已经有一段日子了,不过一如既往的还是那么弱鸡。鉴于笔猪在项目里面应用到PopupWindow弹出框这个功能,所以就去网上四处查找了。此过程中也吃了不少苦头,不过由于PopupWinow还是比较简单,所以笔猪也成功做出了自己想要的效果了。特意想以PopupWindow作为自己的第一篇博客来展开自己的编程之类,希望能来看的朋友多多支持。如有写得不好或是不足,甚至是关于该功能效果有更好的实现方法的朋友请提出来,笔猪希望能与大家一起交流学习。
。首先我们来看一下笔猪这个项目的运行效果如下图所示:
笔猪这里做了两个PopupWindow,一个为普通的、带有EditText的弹出框[分享面板],另外一个则是笔猪做的一个手动计时倒数的[倒数面板]。该功能可以防止用户误操作,虽然真实项目中不常见,不过其实也没有什么常见不常见,只要有需求,无论之前有没有例子已经实践过,程序猿还不是不得不去做么?下面则是该项目的项目结构,如图所示都十分的简单,只有3个class,其中一个是Activity和两个PopupWindow。
由于笔猪是第一次做PopupWindow,经过预览网上的众多相关博客资料后,对某些博客感到显得有些蛋疼。
所以笔猪就先基于这些博客来改进PopupWindow的使用。
主要参考博客有:1,HTTP://www.tuicool.com/articles/6RZBVvI
2,HTTP://104zz.iteye.com/blog/1685389
想参考博客1里面,因为笔猪很不喜欢把PopupWindow里面的代码跟Activity的写在一起,所以采取了参考博客2中分来写的方法实现。不过这样往往会有几个问题,或者应该说是几个比较难实现的效果。其中最要紧的就是:在PopuWindow出现的时候,背景灰度改变,变成半透明。因为PopupWinodw不是继承Activity的,所以无法在PopupWindow里面使用getWindow()让背景改变灰度的代码。
WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 0.5f; getWindow().setAttributes(lp);//改变背景颜色
。PopupWindow消失的时候恢复背景灰度,使用的是setOnDismissListener相关代码:
contdownWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 1f;//恢复背景颜色 getWindow().setAttributes(lp); } });
下面贴出所以类文件的代码:
MainActivity
public class MainActivity extends Activity { //声明PopupWindow类对象 private SharePopupWindow sharePopupWindow; private CountdownPopupWindow contdownWindow; private Button ShareButton,CountDownButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ShareButton = (Button)findViewById(R.id.main_button_share); initPopupWindow(); } /** * ************************************************分享面板************************************************** */ private void initPopupWindow() { sharePopupWindow = new SharePopupWindow(MainActivity.this, itemOnClick); ShareButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 0.6f; getWindow().setAttributes(lp);//设置PopupWindow弹出后背景颜色改变为半透明的黑色 /** * 第一个参数指定PopupWindow的锚点view,即依附在哪个view上。 * 第二个参数指定起始点为parent的右下角, * 第三个参数设置以parent的右下角为原点,向左、上各偏移多少像素。 * 将PopupWindow作为anchor的下拉窗口显示。即在anchor的左下角显示 **/ sharePopupWindow.showAtLocation(MainActivity.this.findViewById(R.id.main_id), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); sharePopupWindow.update(); //弹出窗体销毁时恢复背景颜色 sharePopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 1f;//恢复原来背景颜色的透明度 getWindow().setAttributes(lp); hideKeyboard(); } }); } }); /** * *******************************[倒计时]面板******************************* */ CountDownButton = (Button) findViewById(R.id.home_button_countdown); CountDownButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(MainActivity.this, "长按2秒获得信息", Toast.LENGTH_SHORT).show(); } else if ((event.getAction() == MotionEvent.ACTION_OUTSIDE || event.getAction() == MotionEvent.ACTION_UP) && contdownWindow != null) { contdownWindow.dismiss(); } return false; } }); contdownWindow = new CountdownPopupWindow(MainActivity.this,itemOnClick); //设置弹出面板时为这个按钮的长按事件里面发生 CountDownButton.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //初始化PopupWindow时改变背景灰度 WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 0.5f; getWindow().setAttributes(lp);//改变背景颜色 //实例化SelectPicPopucWindow contdownWindow = new CountdownPopupWindow(MainActivity.this, itemOnClick); //显示窗体,设置显示位置为activity的底部 /** * 第一个参数指定PopupWindow的锚点view,即依附在哪个view上。 * 第二个参数指定起始点为parent的右下角, * 第三个参数设置以parent的右下角为原点,向左、上各偏移多少像素。 * 将PopupWindow作为anchor的下拉窗口显示。即在anchor的左下角显示 **/ contdownWindow.showAtLocation(MainActivity.this.findViewById(R.id.main_id), Gravity.CENTER | Gravity.CENTER, 0, 0);//设置layout在PopupWindow中显示的位置 contdownWindow.update(); //当弹出界面销毁时恢复背景颜色 contdownWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 1f;//恢复背景颜色 getWindow().setAttributes(lp); } }); return true; } }); } //PopupWindow中对点击事件的处理也可以放在这里,我这里特地放了一个 private OnClickListener itemOnClick = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.sharepopupwindow_share_cancel_btn: sharePopupWindow.dismiss(); break; } } }; public InputMethodManager mInputMethodManager; /** * 隐藏软键盘 */ public void hideKeyboard() { if (getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) { if (getCurrentFocus() != null) mInputMethodManager.hideSoftInputFromWindow(getCurrentFocus() .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } }
SharePopupWindow:
public class SharePopupWindow extends PopupWindow implements OnClickListener { //代表这整个PopupWindow视图 private View mPopupView; private Activity context;//传入一个Activity的context; //三个分享按钮和一个取消按钮 private Button wechatShareBtn, friendcircleSharenBtn, weiboShareBtn, cancleShareBtn; //输入框 private EditText shareEditText; public SharePopupWindow(final Activity context, OnClickListener itemOnClick) { super(context); this.context = context; //取得xml里面定义的view LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mPopupView = inflater.inflate(R.layout.sharepopupwindow_layout, null); wechatShareBtn = (Button) mPopupView.findViewById(R.id.sharepopupwindow_share_wechat_btn); wechatShareBtn.setOnClickListener(this); friendcircleSharenBtn = (Button) mPopupView.findViewById(R.id.sharepopupwindow_share_friendcircle_btn); friendcircleSharenBtn.setOnClickListener(this); weiboShareBtn = (Button) mPopupView.findViewById(R.id.sharepopuwindow_share_weibo_btn); weiboShareBtn.setOnClickListener(this); cancleShareBtn = (Button) mPopupView.findViewById(R.id.sharepopupwindow_share_cancel_btn); cancleShareBtn.setOnClickListener(this); shareEditText = (EditText) mPopupView.findViewById(R.id.sharepopupwindow_edittext_share_input); shareEditText.setOnClickListener(this); //绑定监听 cancleShareBtn.setOnClickListener(itemOnClick); //初始化PopupWindow时改变背景灰度 WindowManager.LayoutParams lp = context.getWindow().getAttributes(); lp.alpha = 0.5f; context.getWindow().setAttributes(lp);//改变背景颜色 /** * ********************PopupWindow相关属性********************* */ //设置PopupWindow主视图 this.setContentView(mPopupView); //设置PopouWindow弹出窗体的宽度,有三个属性(FILL_PARENT/WRAP_CONTENT/MATCH_PARENT) this.setWidth(ActionBar.LayoutParams.FILL_PARENT); //设置PopupWindow弹出窗体的高度,属性同上 this.setHeight(ActionBar.LayoutParams.WRAP_CONTENT); //设置PopupWindow弹出窗体是否可点击 this.setFocusable(true); //设置PopupWindow弹出动画效果 this.setAnimationStyle(R.style.SharePopupAniamtion); //实例化一个ColorDrawable颜色为半透明 ColorDrawable dw = new ColorDrawable(0xb0000000); //设置PopupWindow弹出窗体的背景 this.setBackgroundDrawable(dw); //设置PopuoWindow弹出窗体需要软键盘 this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); //设置弹出的软键盘大少和弹出框一样,覆盖尺寸,不会着PopupWindow //属性有[SOFT_INPUT_ADJUST_PAN]:覆盖在PopuWindow上、 [SOFT_INPUT_ADJUST_RESIZE]:总在PopuWindow下,不会挡着。若不需要键盘显示则不用设置 this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); //当PopuopWindow弹出时,是否接受PopupWindow范围以外的点击事件(默认为可点击) // this.setOutsideTouchable(false); //mPopuView添加OnTouchListener监听判断获取触摸位置,如果是在PopupWindow选框外面则销毁弹出框 //不过实质上不加也一样有相同的效果 mPopupView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int popheight = mPopupView.findViewById(R.id.sharepopupwindow_id).getTop(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { if (y < popheight) { dismiss(); } } return true; } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.sharepopupwindow_share_wechat_btn: dismiss(); break; case R.id.sharepopupwindow_share_friendcircle_btn: dismiss(); break; case R.id.sharepopuwindow_share_weibo_btn: dismiss(); break; case R.id.sharepopupwindow_edittext_share_input: shareEditText.requestFocus();//启动输入框焦点 shareEditText.setFocusable(true);//输入框获取焦点 shareEditText.setFocusableInTouchMode(true);//输入框允许点击 showkeyboard(); break; // case R.id.sharepopupwindow_share_cancel_btn: // dismiss(); // break; } } //隐藏虚拟键 public void hideKeybord() { InputMethodManager imm = (InputMethodManager) shareEditText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(shareEditText.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } //显示虚拟键盘 public void showkeyboard() { InputMethodManager imm = (InputMethodManager) shareEditText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(shareEditText, 0); } //PopupWindow窗体的销毁 @Override public void dismiss() { WindowManager.LayoutParams lp = context.getWindow().getAttributes(); lp.alpha = 1f; context.getWindow().setAttributes(lp);//改变背景颜色 hideKeybord(); super.dismiss(); } }
CountdownPopupWindow:
public class CountdownPopupWindow extends PopupWindow{ private View mMenuView; private TextView countdownMumTextView; //倒计时UI Animation animation; public CountdownPopupWindow(final Activity context, View.OnClickListener itemOnClick) { super(context); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//取得xml里定义的view mMenuView = inflater.inflate(R.layout.popupwindow_count_down_layout, null); countdownMumTextView = (TextView) mMenuView.findViewById(R.id.popuview_countdown_textview_num); animation = AnimationUtils.loadAnimation(context, R.anim.anim_dlog); countdownMumTextView.startAnimation(animation); countdownMumTextView.startAnimation(animation); countDownhander.sendEmptyMessageDelayed(0, 1000); //设置SelectPicPopupWindow的view this.setContentView(mMenuView); //设置SelectPicPopupWindow弹出窗口的宽 this.setWidth(ActionBar.LayoutParams.FILL_PARENT); //设置SelectPicPopupWindow弹出窗口的高 this.setHeight(ActionBar.LayoutParams.FILL_PARENT); //设置SelectPicPopupWindow弹出窗体可点击 this.setFocusable(true); //设置SelectPicPopupWindow弹出窗体动画效果 this.setAnimationStyle(R.style.PopupCountdownAnimation); //实例化一个ColorDrawable颜色为透明 ColorDrawable dw = new ColorDrawable(-00000); //设置SelectPicPopupWindow弹出框需要软键盘 this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); //设置弹出的软键盘大少和弹出框一样,覆盖尺寸,不会挡着popupwindow //[SOFT_INPUT_ADJUST_PAN]:覆盖在PopuWindow上、 [SOFT_INPUT_ADJUST_RESIZE]:总在PopuWindow下,不会挡着 this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); // // 当菜单出现时菜单以外的区域是否接受点击事件 // this.setOutsideTouchable(false); //设置SelectPicPopupWindow弹出窗体的背景 this.setBackgroundDrawable(dw); } private int count = 2; private int getCount() { count--; return count; } private void anim() { countdownMumTextView.startAnimation(animation); } Handler countDownhander = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: countdownMumTextView.setText("" + getCount()); if (count > 0) { countDownhander.sendEmptyMessageDelayed(0, 1000); anim(); } else if (count == 0) { dismiss(); } break; } } }; @Override public void dismiss() { count = -1; super.dismiss(); } }
关于该项目的PopupWindow的动画使用可以根据自己的实际需要来定制,从PopupWindow的弹出消失动画,到PopupWindow的出现位置,以及背景颜色的变化。
最后,写得不好,或是觉得排版不好,废话太多的就请见谅了,新手博客是这样啦。好了本博客就到这里,代码我会发出来供大家下载的~喳呢~