PopupWindow自定义键盘

来源:互联网 发布:2016淘宝如何收藏店铺 编辑:程序博客网 时间:2024/06/14 06:39

功能需求描述:页面中点击一个按钮,底部弹出带有EditText的布局,点击EditText弹出自定义键盘,此布局与自定义键盘同步上移。键盘显示时,外部区域可操作。

一、技术选型
1.不使用popupwindow,直接在布局中使用visible和gone显示隐藏自定义键盘
问题:自定义键盘本身也属于布局的一部分,visible后自定义键盘外区域不能操作,不符合项目的图表操作需求
2.第1个popupwindow弹出EditText布局,点击EditText弹出第2个带有自定义键盘的popupwindow
问题:popupwindow没有update移动动画,难以做到2个popupwindow同步移动
3.只有一个popupwindow,自定义键盘先是gone,点击EditText再让自定义键盘visible,加上gone动画效果

二、PopupWindow和自定义键盘遇到的问题
1.popupWindow.showAtLocation(rootview, Gravity.TOP, 0, 1850);
第一个参数需要是popupwindow所依附的父视图中的任意控件,在做第2种情况调研时,传入的是第1个popupwindow中的EditText,报WindowManager$BadTokenException,原因是popupwindow是动态创建的,不能作为showAtLocation()方法的显示位置
2.keyboardWindow.setBackgroundDrawable(new ColorDrawable());
如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
原因:
public void showAtLocation(IBinder token, int gravity, int x, int y) {
…….
final WindowManager.LayoutParams p = createPopupLayoutParams(token);
preparePopup(p);//准备窗体
…….
invokePopup(p);//显示窗体
}
private void preparePopup(WindowManager.LayoutParams p) {
…….
if (mBackground != null) {
mBackgroundView = createBackgroundView(mContentView);
mBackgroundView.setBackground(mBackground);
} else {
mBackgroundView = mContentView;
}
…….
}
preparePopup方法中,如果给PopupWindow设置了背景,则mBackground != null,此时会在PopupWindow的View对象外嵌套一层PopupViewContainer,而PopupViewContainer继承自FrameLayout并重写了按键和触摸事件拦截方法。因此需要给PopupWindow设置一个背景。
3.popupWindow.showAtLocation(rootview, Gravity.TOP, 0, 1850);
底部弹出的popupwindow也可以设置top,由于popupwindow不能超出屏幕外,会自己把自定义键盘用动画显示出来。
4.PopupWindow popupWindow = new PopupWindow(contentView,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
xml中我们已经设置为了”match_parent”;为什么非要我们在代码中还要再设置一遍
原因:控件的大小,是建立在父控件大小确定的基础上的。
我们的contentView是怎么来的呢?
contentView = LayoutInflater.from(this).inflate( R.layout.pop, null);
直接inflate出来的,我们对它没有设置根结点!
那问题来了?它的大小由谁来解决呢?
好像没有谁能决定了,因为他没有父结点。那它到底是多大呢?未知!
所以只有通过代码让用户去手动设置了!所以这就是为什么非要用户设置width和height的原因了。
5. contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
//动态获取控件高度 在android系统版本在17级以下(包含17的时候)根目录是relativelayout时报空指针,需使用LInearLayout
6.获取底部导航栏navigation bar的高度
Resources resources = MainActivity.this.getApplicationContext().getResources();
int resourceId = resources.getIdentifier(“navigation_bar_height”, “dimen”, “android”);
int barHeight = resources.getDimensionPixelSize(resourceId); 7.mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
这个可以解决底部导航栏导致popupwindow显示位置出错问题,不需要去获取底部导航栏高度
8.如果同时设置onClickListener和onTouchListener,onTouchListener会抢占onClickListener事件

阅读全文
0 0
原创粉丝点击