PopupWindow setOutsideTouchable(false)无效问题完美解决方案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PopupWindow setOutsideTouchable(false)无效问题完美解决方案相关的知识,希望对你有一定的参考价值。
参考技术A 最近遇到一个问题,在PopupWindow上有一个Edittext 需要设置setfocus(true) 才可以打开键盘输入,但是呢setOutsideTouchable(false) 设置点击外部不可关闭时又必须得setfocus(false) 这样就比较尴尬了,查了很多资料最后发现可以设置拦截的方式来解决如下Android PopupWindow全屏
很多应用中经常可以看到弹出这种PopupWindow的效果,做了一个小demo分享一下。demo的思路是通过遍历文件,找到图片以及图片文件夹放置在PopupWindow上面。点击按钮可以弹出这个PopupWindow,这里为PopupWindow设置了动画。
PopupWindow全屏代码提要
受限需要自定义Popupwindow,这里不看Popupwindow里面要展示的内容,主要是设置Popupwindow的高度。
public class PopupwindowList extends PopupWindow
private int mWidth;
private int mHeight;
private View mContentView;
private List<FileBean> mFileBeans;
private ListView mListView;
public PopupwindowList(Context context,List<FileBean> mFileBeans)
super(context);
this.mFileBeans=mFileBeans;
//计算宽度和高度
calWidthAndHeight(context);
setWidth(mWidth);
setHeight(mHeight);
mContentView= LayoutInflater.from(context).inflate(R.layout.popupwidow,null);
//设置布局与相关属性
setContentView(mContentView);
setFocusable(true);
setTouchable(true);
setTouchable(true);
setTouchInterceptor(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
//点击PopupWindow以外区域时PopupWindow消失
if (event.getAction() == MotionEvent.ACTION_OUTSIDE)
dismiss();
return false;
);
/**
* 设置PopupWindow的大小
* @param context
*/
private void calWidthAndHeight(Context context)
WindowManager wm= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics= new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
mWidth=metrics.widthPixels;
//设置高度为全屏高度的70%
mHeight= (int) (metrics.heightPixels*0.7);
点击按钮弹出PopupWindow
mButtonShowPopup.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
//点击时弹出PopupWindow,屏幕变暗
popupwindowList.setAnimationStyle(R.style.ListphotoSelect);
popupwindowList.showAsDropDown(mButtonShowPopup, 0, 0);
lightoff();
);
private void lightoff()
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=0.3f;
getWindow().setAttributes(lp);
一、FileBean类保存信息
FileBean如上图PopupWindow所示,需要保存文件的路径,文件夹的名称,文件夹中文件的数量,文件夹中第一张图片的路径。基本全部为set、get方法
/**
* this class is used to record file information like the name of the file 、the path of the file……
*
*/
public class FileBean
private String mFileName;
private String mFilePath;
private String mFistImgPath;
private int mPhotoCount;
public String getmFileName()
return mFileName;
public void setmFileName(String mFileName)
this.mFileName = mFileName;
public String getmFilePath()
return mFilePath;
public void setmFilePath(String mFilePath)
this.mFilePath = mFilePath;
int index=this.mFilePath.lastIndexOf(File.separator);
mFileName=this.mFilePath.substring(index);
public String getmFistImgPath()
return mFistImgPath;
public void setmFistImgPath(String mFistImgPath)
this.mFistImgPath = mFistImgPath;
public int getmPhotoCount()
return mPhotoCount;
public void setmPhotoCount(int mPhotoCount)
this.mPhotoCount = mPhotoCount;
二、PopupWidow界面设置
自定义PopupWindow,
public class PopupwindowList extends PopupWindow
private int mWidth;
private int mHeight;
private View mContentView;
private List<FileBean> mFileBeans;
private ListView mListView;
//观察者模式
public interface OnSeletedListener
void onselected(FileBean bean);
private OnSeletedListener listener;
public void setOnSelecterListener(OnSeletedListener listener)
this.listener=listener;
public PopupwindowList(Context context,List<FileBean> mFileBeans)
super(context);
this.mFileBeans=mFileBeans;
calWidthAndHeight(context);
setWidth(mWidth);
setHeight(mHeight);
mContentView= LayoutInflater.from(context).inflate(R.layout.popupwidow,null);
setContentView(mContentView);
setFocusable(true);
setTouchable(true);
setTouchable(true);
setTouchInterceptor(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
//点击PopupWindow以外区域时PopupWindow消失
if (event.getAction() == MotionEvent.ACTION_OUTSIDE)
dismiss();
return false;
);
initListView(context);
initEvent();
private void initEvent()
//初始化PopupWindow的listview
private void initListView(Context context)
MyListViewAdapter adapter=new MyListViewAdapter(context,0,mFileBeans);
mListView= (ListView) mContentView.findViewById(R.id.listview);
mListView.setAdapter(adapter);
/**
* 设置PopupWindow的大小
* @param context
*/
private void calWidthAndHeight(Context context)
WindowManager wm= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics= new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
mWidth=metrics.widthPixels;
mHeight= (int) (metrics.heightPixels*0.7);
三、点击按钮弹出PopupWindow
public class PopupWindowTest extends AppCompatActivity
private Button mButtonShowPopup;
private Set<String> mFilePath;
private List<FileBean> mFileBeans;
PopupwindowList popupwindowList;
private Handler mHandler=new Handler()
@Override
public void handleMessage(Message msg)
super.handleMessage(msg);
initPopupWindow();
;
private void initPopupWindow()
popupwindowList=new PopupwindowList(this,mFileBeans);
popupwindowList.setOnDismissListener(new PopupWindow.OnDismissListener()
@Override
public void onDismiss()
lighton();
);
//PopupWindow消失时,使屏幕恢复正常
private void lighton()
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=1.0f;
getWindow().setAttributes(lp);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.popupwindowtestlayout);
mButtonShowPopup= (Button) findViewById(R.id.button_showpopup);
mFileBeans=new ArrayList<>();
initData();
initEvent();
private void initEvent()
mButtonShowPopup.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
//点击时弹出PopupWindow,屏幕变暗
popupwindowList.setAnimationStyle(R.style.ListphotoSelect);
popupwindowList.showAsDropDown(mButtonShowPopup, 0, 0);
lightoff();
);
private void lightoff()
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=0.3f;
getWindow().setAttributes(lp);
//开启线程初始化数据,遍历文件找到所有图片文件,及其文件夹与路径进行保存。
private void initData()
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
ToastUtils.showToast(this,"当前sdcard不用使用");
new Thread()
@Override
public void run()
super.run();
Uri imgsUri= MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver=getContentResolver();
Cursor cursor=contentResolver.query(imgsUri,null,MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?",new String[]"image/jpeg","image/png",MediaStore.Images.Media.DATA);
mFilePath=new HashSet<>();
while (cursor.moveToNext())
String path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
File parentfile=new File(path).getParentFile();
if(parentfile==null) continue;
String filePath=parentfile.getAbsolutePath();
FileBean fileBean=null;
if(mFilePath.contains(filePath))
continue;
else
mFilePath.add(filePath);
fileBean=new FileBean();
fileBean.setmFilePath(filePath);
fileBean.setmFistImgPath(path);
if(parentfile.list()==null) continue;
int count=parentfile.list(new FilenameFilter()
@Override
public boolean accept(File dir, String filename)
if(filename.endsWith(".jpg")||filename.endsWith(".png")||filename.endsWith(".jpeg"))
return true;
return false;
).length;
fileBean.setmPhotoCount(count);
mFileBeans.add(fileBean);
cursor.close();
//将mFilePath置空,发送消息,初始化PopupWindow。
mFilePath=null;
mHandler.sendEmptyMessage(0x110);
.start();
四、PopupWindow动画设置。
(1)编写弹出与消失动画
①弹出动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="100%"
android:toYDelta="0"
android:duration="1000"></translate>
</set>
②消失动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="100%"
android:duration="1000"></translate>
</set>
(2)设置style与调用style
①设置style
在style中进行添加
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
</style>
<style name="ListphotoSelect">
<item name="android:windowEnterAnimation">@anim/animshow</item>
<item name="android:windowExitAnimation">@anim/animdismiss</item>
</style>
</resources>
②调用style
为PopupWindow设置动画style
popupwindowList.setAnimationStyle(R.style.ListphotoSelect);
备注:布局很简单不再展示。
以上是关于PopupWindow setOutsideTouchable(false)无效问题完美解决方案的主要内容,如果未能解决你的问题,请参考以下文章