PopupWindow点击外部区域消失(三)
来源:互联网 发布:淘宝视频直播内容下载 编辑:程序博客网 时间:2024/05/17 21:48
续前言PopupWindow点击外部区域消失(二)
既然我们知道了为什么一定要先设置 mBackground 然后才能 dismiss PopupWindow,那么下面就来看怎么不用设置也能破之。。
首先还要来看这里:
private void preparePopup(WindowManager.LayoutParams p) { if (mContentView == null || mContext == null || mWindowManager == null) { throw new IllegalStateException("You must specify a valid content view by " + "calling setContentView() before attempting to show the popup."); } if (mBackground != null){ final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); int height = ViewGroup.LayoutParams.MATCH_PARENT; if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { height = ViewGroup.LayoutParams.WRAP_CONTENT; } // when a background is available, we embed the content view // within another view that owns the background drawable PopupViewContainer popupViewContainer = new PopupViewContainer(mContext); PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height ); popupViewContainer.setBackground(mBackground); popupViewContainer.addView(mContentView, listParams); mPopupView = popupViewContainer; }else { **mPopupView = mContentView;** } mPopupView.setElevation(mElevation); mPopupViewInitialLayoutDirectionInherited = (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); mPopupWidth = p.width; mPopupHeight = p.height; }
既然 mBackgroud == null 的时候 mPopupView = mContentView;
那么我们可以为什么不可以通过自定义该View来处理它的点击事件呢,
在这里我自定义了一个LinearLayout ,下面来看它的实现,
public class MyLinearLayout extends LinearLayout{ public MyLinearLayout(Context context) { this(context,null); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } private onMyDismissListener onMyDismissListener; public void setOnMyDismissListener(onMyDismissListener onMyDismissListener) { this.onMyDismissListener = onMyDismissListener; } private static final String TAG = "PopupWindow.MyLinearLayout"; private OnTouchListener mTouchInterceptor; /** * Set a callback for all touch events being dispatched to the popup * window. */ public void setTouchInterceptor(OnTouchListener l) { mTouchInterceptor = l; } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { if (getKeyDispatcherState() == null) { return super.dispatchKeyEvent(event); } if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.startTracking(event, this); } return true; } else if (event.getAction() == KeyEvent.ACTION_UP) { KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null && state.isTracking(event) && !event.isCanceled()) { if(onMyDismissListener != null){ onMyDismissListener.onDismiss(); } return true; } } return super.dispatchKeyEvent(event); } else { return super.dispatchKeyEvent(event); } } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { return true; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); if ((event.getAction() == MotionEvent.ACTION_DOWN) && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { if(onMyDismissListener != null){ onMyDismissListener.onDismiss(); } return true; } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { if(onMyDismissListener != null){ onMyDismissListener.onDismiss(); } return true; } else { return super.onTouchEvent(event); } }}
细心的朋友应该会发现这段代码与 PopupViewContainer 的代码特别相似,不错就是照着它的来写的。。值得一提的是这个地方
if(onMyDismissListener != null){ onMyDismissListener.onDismiss(); }
这里呢,我定义了一个接口来实现它的 dismiss() 功能。
public interface onMyDismissListener { void onDismiss();}
下面来看它的具体用法:
public class MyPopupWindow implements onMyDismissListener{ private static final String TAG = "MyPopupWindow"; public Context mContext; private PopupWindow mPopupWindow; private PopupWindowType type; public PopupWindowType getType() { return type; } public void setType(PopupWindowType type) { this.type = type; } public MyPopupWindow(Context context,PopupWindowType type, int width, int height, boolean focusable) { this.mContext = context; if(type == null){ type = PopupWindowType.TYPE_1; } View view = inflaterView(type); mPopupWindow = new PopupWindow(view, width, height, focusable);// mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); Drawable background = mPopupWindow.getBackground(); Log.v(TAG, ""+background); mPopupWindow.setAnimationStyle(R.style.Animation); mPopupWindow.setOutsideTouchable(focusable); } private View inflaterView(PopupWindowType type){ View contentView; switch (type) { case TYPE_1: default: contentView = LayoutInflater.from(mContext).inflate(R.layout.popup_view, null); try { MyLinearLayout layout = (MyLinearLayout) contentView.findViewById(R.id.mll); layout.setOnMyDismissListener(this); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e(TAG, "You must set a id name is rId's name " + " in rootlayout"); } break; } return contentView; } @Override public void onDismiss() { mPopupWindow.dismiss(); } public void showAtLocation(View findViewById, int gravity, int x, int y) { // TODO Auto-generated method stub mPopupWindow.showAtLocation(findViewById, gravity, x, y); }}
大家可以看到第 42,43行 我们并没有给他设置 mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
它实现了上述的接口,然后在 onDismiss 里调用了 mPopupWindow.dismiss(); 然后来看,第57,58行代码给layout设置监听方法,它的布局是这样的:
<?xml version="1.0" encoding="utf-8"?><com.xfchen.opensource.widget.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mll" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/shape_popup_bg" android:orientation="vertical" > // 可以自行添加布局</com.xfchen.opensource.widget.MyLinearLayout>
然后在Activity里调用它就可以了,
private void showPopupWindow(){ MyPopupWindow myPopupWindow = new MyPopupWindow(this, PopupWindowType.TYPE_1, LayoutParams.MATCH_PARENT, 500, true); myPopupWindow.showAtLocation(MainActivity.this.findViewById(R.id.rlMain), Gravity.BOTTOM|Gravity.CENTER_VERTICAL, 0, 0); }
这里是设置它从底部显示。。然后就大功告成了,这个并不是什么特别适用的功能,只是为了证明我们的猜想是正确的。。如有不足,请不吝赐教!
代码下载地址
0 0
- PopupWindow点击外部区域消失(三)
- PopupWindow点击外部区域消失(二)
- 点击PopupWindow 外部区域消失
- PopupWindow点击外部区域消失
- 点击PopupWindow外部消失
- PopupWindow在点击外部区域的时候消失(二)
- PopupWindow设置点击区域以外部分时自动消失
- PopupWindow点击外部区域不能消失的解决办法
- 点击popupwindow以外区域 popupwindow自动消失
- popupwindow点击其它区域自动消失
- PopupWindow点击外面区域自动消失
- Android Popupwindow 点击外部消失的实现
- popupwindow的基本应用,点击外部消失
- 关于点击popupwindow以外区域 popupwindow自动消失问题
- android:点击popupwindow以外区域 popupwindow自动消失(转载)
- 点击popupwindow窗口之外的区域使popupwindow消失
- android:点击popupwindow以外区域 popupwindow自动消失
- android:点击popupwindow以外区域 popupwindow自动消失
- ubuntu 10.10 的 输入法图标不见了
- eclipse 基本设置
- Decorator——结构型模式
- G - Give Me the Number --- (first qualifying)
- 再谈循环嵌套
- PopupWindow点击外部区域消失(三)
- ssh 反向代理
- hdu 1076(An Easy Task)
- 心中的激动与兴奋交加,阿里内推面试
- UITableViewRowAction的使用
- 比较炫丽的幻灯片
- FastJson和Gson解析json的小例子
- 深度学习-CNN入门
- Maven核心概念之依赖,聚合与继承