Android 中ScrollView嵌套GridView,ListView的实例
android 中scrollview嵌套gridview,listview的实例
在android开发中,经常有一些ui需要进行固定style的动态布局,然而由于现在的ui都喜欢把一个界面拉的很长,所以我们很多情况下需要使用scrollview来嵌套列表控件来实现ui。这样就导致了很多不顺心的问题。
问题一:列表控件显示不完全
原因是嵌套情况下,scrollview不能正确的计算列表控件的高度。
有两种解决方案
方案一
在适配器赋值完成后代码动态计算列表的高度。这里贴出listview的计算代码,gridview的计算方式类似,不过需要考虑列数,下面代码没有加上列表控件padding的计算,如果你设置了这个属性,需要加上计算代码
public void setlistviewheightbasedonchildren(listview listview) { // 获取listview对应的adapter listadapter listadapter = listview.getadapter(); if (listadapter == null) { return; } int totalheight = 0; for (int i = 0, len = listadapter.getcount(); i < len; i++) { // listadapter.getcount()返回数据项的数目 view listitem = listadapter.getview(i, null, listview); // 计算子项view 的宽高 listitem.measure(0, 0); // 统计所有子项的总高度 totalheight += listitem.getmeasuredheight(); } viewgroup.layoutparams params = listview.getlayoutparams(); params.height = totalheight+ (listview.getdividerheight() * (listadapter.getcount() - 1)); // listview.getdividerheight()获取子项间分隔符占用的高度 // params.height最后得到整个listview完整显示需要的高度 listview.setlayoutparams(params); }
方案二
重写列表控件的onmeasure方法,这种方案不会出现列表控件本身的滚动条,并且viewholder复用机制会失效
@override public void onmeasure(int widthmeasurespec, int heightmeasurespec) { int expandspec = measurespec.makemeasurespec(1 << 16, measurespec.at_most); super.onmeasure(widthmeasurespec, expandspec); }
方案一代码多,需要多次写,建议写成工具类方便调用;方案二在数据量大到不能一屏显示完的情况下会有性能问题,而且快速滑动的时候scrollview会不停的去计算列表控件的高度。贼影响绘制性能。
两种方案有利有弊,大家自己取舍
问题二:列表控件自动获取焦点,导致scrollview自动滚动到列表控件所在的位置
这个问题其实有很多种解决方案,归结起来是两种。
方案一
等待列表控件数据全部加载完成后(包括图片加载)调用scrollview.fullscroll(scrollview.focus_up);
方法让scrollview滚动到顶部。这个加载完成的时间不好控制,搞得不好会有滚动动画出现,很尴尬的事情。
方案二
重写列表控件的如下两个方法,使之固定返回false
@override public boolean isfocused() { return false; } @override public boolean requestfocus(int direction, rect previouslyfocusedrect) { return false; }
两种方案的优缺点很明显,喔,第二种方案的缺点我目前没发现。如果你这么使用发现了什么坑,请留言告知
问题三 滑动冲突
这问题就更操蛋了,根据ui的不同,操蛋程度也不同,涉及到view的事件传递知识,很难给出所有情况的解决代码
解决起来也离不开几个要点,不过首先你得熟悉view的事件传递
你需要根据情况决定重写列表控件与scrollview的如下几个方法,根据情况给方法返回不同的bool值来告诉控件是否拦截或者传递事件,需要哪个控件相应哪个方向的滚动事件就拦截哪个方向的事件传递,作为一个有追求的开发者,切记不要一通乱拦截
@override public boolean ontouchevent(motionevent ev) { return super.ontouchevent(ev); } @override public boolean onintercepttouchevent(motionevent ev) { return super.onintercepttouchevent(ev); } @override public boolean dispatchtouchevent(motionevent ev) { return super.dispatchtouchevent(ev); }
给个小彩蛋
getparent().requestdisallowintercepttouchevent(boolean b);
这一句代码可以在子控件里决定是否让父容器获取事件
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
上一篇: Vue脚手架的简单使用实例
下一篇: 5-20 网站代售代购精华推荐!
推荐阅读
-
Android 中ScrollView嵌套GridView,ListView的实例
-
Android解决ScrollView下嵌套ListView和GridView中内容显示不全的问题
-
Android中listview嵌套scrollveiw冲突的解决方法
-
Android编程开发之ScrollView嵌套GridView的方法
-
Android Listview中显示不同的视图布局详解及实例代码
-
Android编程开发之ScrollView嵌套GridView的方法
-
Android 中ScrollView与ListView冲突问题的解决办法
-
Android 中ScrollView与ListView冲突问题的解决办法
-
Android ListView中动态添加RaidoButton的实例详解
-
Android笔记之:在ScrollView中嵌套ListView的方法