Android中PopupWindow自定义坐标实现

Android中PopupWindow位置的确定一般通过showAsDropDown函数来实现,该函数有两个重载函数,分别定义如下:

[java] view plaincopyprint?

  1. public void showAsDropDown(View anchor) {  
  2.     showAsDropDown(anchor, 0, 0);  
  3. }  
  4.   
  5. public void showAsDropDown(View anchor, int xoff, int yoff) {  
  6.     if (isShowing() || mContentView == null) {  
  7.         return;  
  8.     }  
  9.   
  10.     registerForScrollChanged(anchor, xoff, yoff);  
  11.   
  12.     mIsShowing = true;  
  13.     mIsDropdown = true;  
  14.   
  15.     WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());  
  16.     preparePopup(p);  
  17.   
  18.     updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff));  
  19.   
  20.     if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;  
  21.     if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;  
  22.   
  23.     p.windowAnimations = computeAnimationResource();  
  24.   
  25.     invokePopup(p);  
  26. }  
    public void showAsDropDown(View anchor) {
        showAsDropDown(anchor, 0, 0);
    }

    public void showAsDropDown(View anchor, int xoff, int yoff) {
        if (isShowing() || mContentView == null) {
            return;
        }

        registerForScrollChanged(anchor, xoff, yoff);

        mIsShowing = true;
        mIsDropdown = true;

        WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());
        preparePopup(p);

        updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff));

        if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
        if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;

        p.windowAnimations = computeAnimationResource();

        invokePopup(p);
    }

也就是说,调用第一个函数时,x和y坐标偏移量默认是0,此时PopupWindow显示的结果如下中图所示。而要实现PopupWindow显示在wenwen的正下方时,就需要程序员自己进行坐标偏移量的计算,下右图所示,当点击wenwen时,PopupWindow显示在正下方,这正是我们所需要的,对称是一种美啊。

代码实现的关键是点击wenwen后的响应函数,此处直接上代码,不废话了:

[java] view plaincopyprint?

  1. public void onClick(View v) {  
  2.     LayoutInflater mLayoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);  
  3.     ViewGroup menuView = (ViewGroup) mLayoutInflater.inflate(  
  4.             R.layout.tips, null, true);  
  5.     pw = new PopupWindow(menuView, LayoutParams.WRAP_CONTENT,  
  6.             LayoutParams.WRAP_CONTENT, true);    
  7.     // 设置点击返回键使其消失,且不影响背景,此时setOutsideTouchable函数即使设置为false
      
  8.     // 点击PopupWindow 外的屏幕,PopupWindow依然会消失;相反,如果不设置BackgroundDrawable
      
  9.     // 则点击返回键PopupWindow不会消失,同时,即时setOutsideTouchable设置为true
      
  10.     // 点击PopupWindow 外的屏幕,PopupWindow依然不会消失
      
  11.     pw.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));   
  12.     pw.setOutsideTouchable(false); // 设置是否允许在外点击使其消失,到底有用没?
      
  13.     pw.setAnimationStyle(R.style.PopupAnimation); // 设置动画
      
  14.   
  15.     // 计算x轴方向的偏移量,使得PopupWindow在Title的正下方显示,此处的单位是pixels
      
  16.     int xoffInPixels = ScreenTools.getInstance(PopDemoActivity.this).getWidth() / 2 - titleName.getWidth() / 2;  
  17.     // 将pixels转为dip   
  18.     int xoffInDip = ScreenTools.getInstance(PopDemoActivity.this).px2dip(xoffInPixels);  
  19.     pw.showAsDropDown(titleName, -xoffInDip, 0);  
  20.     //pw.showAsDropDown(titleName);
      
  21.     pw.update();  
  22.   
  23.     TextView tv = (TextView) menuView.findViewById(R.id.tips_ok);  
  24.     tv.setOnClickListener(new View.OnClickListener() {  
  25.   
  26.         public void onClick(View v) {  
  27.             pw.dismiss();  
  28.         }  
  29.   
  30.     });  
  31.       
  32. }  
public void onClick(View v) {
	LayoutInflater mLayoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
	ViewGroup menuView = (ViewGroup) mLayoutInflater.inflate(
			R.layout.tips, null, true);
	pw = new PopupWindow(menuView, LayoutParams.WRAP_CONTENT,
			LayoutParams.WRAP_CONTENT, true);
	// 设置点击返回键使其消失,且不影响背景,此时setOutsideTouchable函数即使设置为false
	// 点击PopupWindow 外的屏幕,PopupWindow依然会消失;相反,如果不设置BackgroundDrawable
	// 则点击返回键PopupWindow不会消失,同时,即时setOutsideTouchable设置为true
	// 点击PopupWindow 外的屏幕,PopupWindow依然不会消失
	pw.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
	pw.setOutsideTouchable(false); // 设置是否允许在外点击使其消失,到底有用没?
	pw.setAnimationStyle(R.style.PopupAnimation); // 设置动画

	// 计算x轴方向的偏移量,使得PopupWindow在Title的正下方显示,此处的单位是pixels
	int xoffInPixels = ScreenTools.getInstance(PopDemoActivity.this).getWidth() / 2 - titleName.getWidth() / 2;
	// 将pixels转为dip
	int xoffInDip = ScreenTools.getInstance(PopDemoActivity.this).px2dip(xoffInPixels);
	pw.showAsDropDown(titleName, -xoffInDip, 0);
	//pw.showAsDropDown(titleName);
	pw.update();

	TextView tv = (TextView) menuView.findViewById(R.id.tips_ok);
	tv.setOnClickListener(new View.OnClickListener() {

		public void onClick(View v) {
			pw.dismiss();
		}

	});

}
时间: 2024-09-20 20:08:14

Android中PopupWindow自定义坐标实现的相关文章

Android中PopupWindow显示在指定位置

Android中PopupWindow位置的确定一般通过showAsDropDown函数来实现,该函数有两个重载函数,分别定义如下: public void showAsDropDown(View anchor) { showAsDropDown(anchor, 0, 0); } public void showAsDropDown(View anchor, int xoff, int yoff) { if (isShowing() || mContentView == null) { retu

Android 中TabLayout自定义选择背景滑块的实例代码_Android

 TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawab

Android 中TabLayout自定义选择背景滑块的实例代码

TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawabl

Android中DialogFragment自定义背景与宽高的方法

介绍 DialogFragment在android 3.0时被引入.是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框.典型的用于:展示警告框,输入框,确认框等等. 在DialogFragment产生之前,我们创建对话框:一般采用AlertDialog和Dialog.注:官方不推荐直接使用Dialog创建对话框. 本文主要给大家介绍了关于Android中DialogFragment自定义背景与宽高的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的

Android中制作自定义dialog对话框的实例分享_Android

自定义dialog基础版很多时候,我们在使用android sdk提供的alerdialog的时候,会因为你的系统的不同而产生不同的效果,就好比如你刷的是MIUI的系统,弹出框都会在顶部显示!这里简单的介绍自定义弹出框的应用. 首先创建布局文件dialog: 代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andr

解析Android中使用自定义字体的实现方法_Android

1.Android系统默认支持三种字体,分别为:"sans", "serif", "monospace 2.在Android中可以引入其他字体 . 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><TableLayout xmlns:Android="http://schemas.android.com/apk/res/android&qu

解析Android中使用自定义字体的实现方法

1.Android系统默认支持三种字体,分别为:"sans", "serif", "monospace 2.在Android中可以引入其他字体 .复制代码 代码如下:<?xml version="1.0" encoding="utf-8"?><TableLayout xmlns:Android="http://schemas.android.com/apk/res/android"

Android中制作自定义dialog对话框的实例分享

自定义dialog基础版 很多时候,我们在使用android sdk提供的alerdialog的时候,会因为你的系统的不同而产生不同的效果,就好比如你刷的是MIUI的系统,弹出框都会在顶部显示!这里简单的介绍自定义弹出框的应用. 首先创建布局文件dialog: 代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.and

Android中使用自定义View实现下载进度的显示

一般有下载功能的应用都会有这样一个场景,需要一个图标来标识不同的状态.之前在公司的项目中写过一个,今天抽空来整理一下. 一般下载都会有这么几种状态:未开始.等待.正在下载.下载结束,当然有时候会有下载出错的状态.等待状态是指用户点击开始下载,但是线程池中没有空闲的线程来处理该次下载,所以状态为等待. 效果图:     这里我只是演示了一下下载和暂停的状态,其他状态没有演示,在代码中设置就可以了. 实现代码: 1.自定义View 1 public class DownloadPercentView