最近在项目中用ListView实现了一个树形菜单,菜单层级可以无限,数据动态填充,写这个控件确实是花了不少的时间,而且代码逻辑也比较复杂。所以在这里并不是把整个源码贴出来,因为太多了,逻辑也比较难懂,我怕自己讲不清楚,所以这里只是记录一下在此过程中遇到的某方面的问题。
因为在项目中的数据是动态填充的,即每个树节点都是从服务器端请求,然后解析获取的。那这样的话就有一个问题就是listview的宽度跟高度问题。每一行的数据高度或者宽度都是不定的,所以想到用ScrollerView嵌套ListView,使之可以水平和垂直同时滚动。我第一次听到这个结构的时候很诧异,为什么ListView还要嵌套ScrollerView呢,怎么会有这么奇怪的需求呢?不过别诧异,现在想想还是有很多地方用到这种结构的,比如美团网中一个页面。在我的这个项目中,需求是这样的,从服务端获取数据,解析出来,显示在树形选择菜单中,因为数据宽高不定,所以需要水平与垂直同时滚动,滚动风格就是windows窗口垂直方向与水平方向的滚动条风格!就是下面图片的这种风格:
我们都知道,ScrollerView(垂直)和ListView都是带滚动的控件,其它比如GridView等同理。那么,用一个滚动控件嵌套另一个滚动控件会出现什么问题呢?在ScrollerView中嵌套ListView,该ListView只会显示第一行的高度,这是因为当ListView嵌套在ScrollerView中时,系统是无法计算出其高度的,只会显示第一行的高度,具体可以参照源码,反正关于这个得源码很多,我没有坚持下来看完。同理嵌套HorizontalScrollView只会显示第一行的宽度。所以就牵涉到了ListView动态设置宽高问题。总结一下需解决的问题:ListView同时双向滚动,ListView动态设置宽高。
下面是布局文件:
<!--ScrollView嵌套ListView注意事项:
ScrollView中只能包含一个子标签
需要动态代码计算设置ListView高度或宽度
listView宽高最好都设置为match-parent,否则数据多时会OOM
计算宽高时ListView子项item根布局必须得是LinearLayout,否则measure()时NullPointException
android:fillViewport="true" 水平滚动显示一个窗口大小-->
<ScrollView
android:id="@+id/vertical_scrollbar"
android:layout_width="450dp"
android:layout_height="475dp"
android:fadeScrollbars="false"
android:scrollbarFadeDuration="0"
android:layout_marginTop="5dp"
android:scrollbarThumbVertical="@drawable/tree_listview_vertical_scrollbar"
android:scrollbarTrackVertical="@drawable/tree_listview_vertical_scrollbar_bg"
android:scrollbars="vertical">
<HorizontalScrollView
android:id="@+id/horizontal_scrollbar"
android:layout_width="match_parent"
android:layout_height="460dp"
android:scrollbarThumbHorizontal="@drawable/tree_listview_horizontal_scrollbar"
android:scrollbarTrackHorizontal="@drawable/tree_listview_horizontal_scrollbar_bg"
android:fadeScrollbars="false"
android:fillViewport="true"
android:scrollbarFadeDuration="0">
<!--必须在listview外包裹一层线性布局,否则无法设置其宽度 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/list_resource_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="2dp"
android:cacheColorHint="#ffffffff"
android:divider="@drawable/listview_tree_divider"
android:dividerHeight="2.0dip"
android:drawSelectorOnTop="false"
android:fadingEdgeLength="0.0sp"
android:fastScrollEnabled="false"
android:fadeScrollbars="false"
android:scrollbarFadeDuration="0"
android:scrollbars="none"/>
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
之所以要嵌套一个垂直的ScrollerView而不用ListView自带的滚刀条,这是因为我需要固定滚动条在右边缘的位置,不随ListView的宽度而改变位置,如果用ListView在带的滚动条,它会始终在ListView的右边缘,当ListView的宽度改变后,其位置也改变了,这样不美观!嵌套需要注意的地方在代码中已经提出了。android:scrollbarThumbVertical这个属性是设置滚动条,android:scrollbarTrackVertical这是滚动轨迹。滚动都是有这个属性的,水平滚动对应改成android:scrollbarThumbHorizontal和android:scrollbarTrackHorizontal即可。还有一些属性不一一说明了。接下来就是在代码中设置宽跟高了。
/**
* 根据item设置listView宽度和高度
* @param listView
* @return
*/
public void setListViewSizeBaseChrildren(){
int items=resource_list.getAdapter().getCount();
int maxItemWidth=0;
int totalHeight=0;
int widthParams,heightParams;
for(int i=0;i<items;i++){
View itemView=resource_list.getAdapter().getView(i, null, resource_list);
itemView.measure(0, 0);
int itemWidth=itemView.getMeasuredWidth();
totalHeight+=itemView.getMeasuredHeight();
if(itemWidth>maxItemWidth){
maxItemWidth=itemWidth;
}
}
//保证listView最小宽度不小于450dp
if(maxItemWidth>450){
widthParams=maxItemWidth+(resource_list.getDividerHeight()*20);
}else{
widthParams=450;
}
//保证listView最小高度不小于475dp
if(totalHeight>475){
heightParams=totalHeight+(resource_list.getDividerHeight()*(resource_list.getAdapter().getCount()-1))+18;
}else{
heightParams=475;
}
ViewGroup.LayoutParams params=resource_list.getLayoutParams();
params.width=widthParams;
params.height=heightParams;
resource_list.setLayoutParams(params);
}
在需要设置的时候,调用该方法即可,方法中的一些大小数据是本身项目需要,可以自行调整。这样这个ListView就可以整体的水平和垂直滚动了,注意是整体滚动,有时网上说的横向滚动的ListView是指把Item横向排列,这种需要自定义了!
- 大小: 2.4 KB
分享到:
相关推荐
ListView嵌套GridView以及ListVIew嵌套ListVIew还有时间轴效果想要了解更多请前往http://blog.csdn.net/u014452224
利用android studio实现listview嵌套listview,技术含量不是特别高,希望能帮助大家,这里就意思一下,给1分算啦
listView嵌套listViewDemo,解决了listView嵌套listView后,子ListView不能显示全部内容的问题,通过自定义Listview解决
listview嵌套listview简单的小案例
ListView 嵌套ListView 的一个demo,可以实现二级列表。
ListView嵌套ListView,checkbox全选,多选,父item全选后,下面的子item全部选中
ListView嵌套ListView并且实现动态设置子ListView的高度,
android listview嵌套listview实现折叠列表
ExpandableListView (实现ListView嵌套ListView的效果)
ListView嵌套ListView带多选,全选,反选,选中数量,之前传过一个,只是上面没数量
listView嵌套listView
点击一级ListView,子级的ListView更新相应的条目内容。可实现win7开始菜单。
viewpage嵌套listview,效果:滑动listview删除,滑动非listview区域viewpage翻页
ScrollView,嵌套ListView,ListView并同时嵌套GridView
利用ListView嵌套ExpandableListView实现三级菜单
直接两个listView 布局文件,数据直接输入,获得 嵌套ListView 的适配效果
listview里嵌套了一个评论列表,可以动态添加评论 整体代码非常简洁,没有花哨的样式和布局以及其它多余代码。
解决Scrollview嵌套listview下拉刷新的一些问题
android中Listview嵌套Listview,androidStudio环境demo,
listView嵌套横向listView,参考http://blog.csdn.net/whitley_gong/article/details/48936689 的代码的,只是希望日后自己方便,希望作者不要介意。谢谢