现在有一个需求:
有一个Activity,Z方向内层是一张全屏图片,外层的屏幕上部有一个ViewGroup,包含了一些子控件,
子控件大体上从上按下排列,根据设计图,子控件之间有稍大的间隙,其中有一个子控件是EditText。
在大部分手机上,这个ViewGroup基本上占到屏幕高度的一半。
问题来了,产品要求:输入法弹出后,任意调整输入法高度都能动态调整ViewGroup的高度使其完整可见。
阅读之前,了解输入法的挤压方式枚举:
SOFT_INPUT_ADJUST_UNSPECIFIED
SOFT_INPUT_ADJUST_RESIZE
SOFT_INPUT_ADJUST_PAN
SOFT_INPUT_ADJUST_NOTHING
乍一看不知道怎么实现,我们先看一个简单的需求:
一个Activity在Z方向上有两层,内层是一个全屏ImageView,外层是一个EditText,EditText靠屏幕底部。
要求:输入法弹出时,图片不发生变化,而EditText随输入法弹出而被顶起。
解1:
对于输入法挤压,活动在manifest文件中可以配置softInputMode属性来决定挤压的行为。
对此,Activity可以配置成SOFT_INPUT_ADJUST_RESIZE来根据剩余高度动态决定布局的高度;
而对于ImageView,可以重新实现一个类继承ImageView,在onMeasure中重新决定ImageView的高度,将其设为屏幕区域高度。
解2:
其实不仅Activity,输入法挤压属性在WindowManager.LayoutParams中有拥有,所以,一个window对应一种解压方式。
我们可以把ImageView放在Activity布局中,再新建一个窗口,将EditText放在窗口的布局中,
将窗口的布局设为SOFT_INPUT_ADJUST_RESIZE,
而Activity的挤压属性设为SOFT_INPUT_ADJUST_NOTHING。
Dialog就是用窗口来封装的,我们新建一个Dialog即可。
有了上面的两种解法,原先的需求实现也明朗了:
解:
将全屏图片放入Activity的布局中,挤压方式设为SOFT_INPUT_ADJUST_NOTHING;
新建一个Dialog,将需求中的ViewGroup按照设计图提供的尺寸完成布局,放入Dialog中;
Dialog挤压方式设置为SOFT_INPUT_ADJUST_RESIZE,为了实现ViewGroup自己的高度动态调整,
使用纵向LinearLayout布局需求中的ViewGroup:
其子视图间的间距不要用margin和padding,使用空View替代他们,空View的高度为0dp,weight使用
设计图中子视图间的间距,通过weight动态调整ViewGroup的高度。
最终效果图: