做项目的时候,遇到一个棘手的需求:
自定义Dialog的布局是上方TextView标题,中间ListView(或者RecyclerView)列表,下面Button按钮。需要中间列表根据服务器获取的数据动态改变高度。
难点就在于当服务器返回的数据条目过多的时候,无论设置列表的高度是match_parent还是wrap_content,Dialog的高度都会过大,导致看不见标题和按钮。如果设置列表高度为100dp或者200dp之类的常量。当服务器返回数据条目较少的时候,列表下面可能留白,用户体验较差。解决这个问题,就需要我们动态的改变列表的高度。
在解决这个问题的过程中,我走了很多弯路。好在最终问题完美的解决了,于是我打算记录下问题解决的过程。
开始,我打算在Dialog的show方法执行的过程中,重新测量和比较Dialog的高度和屏幕绘制区域高度之间的比值。但是空指针异常,原因是当show的时候Dialog的onCreate方法可能还未执行,控件还未绑定,所以列表和Dialog所在window在执行getLayoutParams的时候得到的高度不是0就是负值。我又把测量比较的方法移到onCreate方法最后去执行,还是一样空指针异常。
而且经过我之后的思考,如果控件都展示之后再进行测量,重新设置高度。代码的效率低下, 编码逻辑混乱,只能当做权宜之计。
最好的方法还是在控件测量的时候直接进行比较并赋值。
列表是ViewGroup的子类,而ViewGroup的工作流程中第一步就是在onMeasure方法中,执行控件自身的宽高测量。注意这个build tools version最好是23.0.1,否则会抛异常。
之后就是编码和优化算法。问题就解决了。。。