总结:在ScrollView中嵌套ListView

本文深入探讨了在Android应用中如何解决ScrollView和ListView嵌套时的布局冲突问题,包括调整ListView高度、自定义ListView以及优化布局策略等方法。详细介绍了如何避免页面跳转至ListView第一条项的问题,提供了实用的代码片段和解决方案。
一、分析
1、最简单的布局:只有一个ListView
如果整个页面只有一个ListView的话,那么由于ListView本身带有滚动效果,所以当加载的数据超过页面显示的范围时,可以通过上下滑动来查看所有的item。
因此这种情况下,不需要添加ScrollView。
2、其它布局A+ListView
这种情况下,如果布局A定义在ListView的前面,那么当布局A所占的比例较大,或者ListView加载的数据较多时,都会导致ListView显示不完全。同样,由于ListView自身可以滚动,因此仍然可以通过上下滚动来查看ListView的所有item。
如图所示:

3、其它布局B+ListView
这种情况下,假设布局B定义在ListView的后面,那么就会出现两种情况:
(1)、ListView加载的数据不多,可以完全显示ListView的每一项,那么如果后面还有足够剩余的空间的话,布局B能正常显示;
(2)、ListView加载的数据加多,那么就会导致留给布局B的空间不足,或者根本就没有,布局B将会显示不完全或者完全不显示。
而不管怎么,ListView本身的内容,都可以通过滑动来查看。
对于第三种情况,如果不重新考虑布局的话,那么就需要添加ScrollView,用于查看剩余页面内容。
二、ScrollView和ListView的冲突问题
1、给ListView指定一个高度
例如设置android:layout_height="240dip",那么可以解决,可能会影响美观。
如图所示:

2、外面再添加个ScrollView
这种情况下,会出现问题。如图所示:

3、给ScrollView设置属性:android:fillViewport="true"
测试的时候发现,如果ListView加载的数据不多的话,确实可以解决,但是当ListView加载的数据较多的时候,仍旧无法显示完全,并且这个时候ListView自身也无法滚动了。

三、解决办法有两种

1、在计算listview总高度并设置

ListView listView = (ListView) findViewById(id);
YourAdapter adapter = new MyAdapter("初始化你的适配器");
listView.setAdapter(adapter);
setListViewHeightBasedOnChildren(listView);(在setAdapter后调用自定义的方法)


?
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @param listView
*/
private void setListViewHeightBasedOnChildren(ListView listView) {
  
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null ) {
return ;
}
  
int totalHeight = 0 ;
for ( int i = 0 ; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null , listView);
listItem.measure( 0 , 0 );
totalHeight += listItem.getMeasuredHeight();
}
  
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1 ));
listView.setLayoutParams(params);
}



使用该方法需要注意: 子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。
2、 自定义ListView,重载onMeasure()方法,设置全部显示
?
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.meiya.ui;
  
import android.widget.ListView;
  
/**
* @Description: scrollview中内嵌listview的简单实现
* @File: ScrollViewWithListView.java
* @Paceage com.meiya.ui
* @Date 下午03:02:38
* @Version
*/
public class ScrollViewWithListView extends ListView {
  
public ScrollViewWithListView(android.content.Context context,
android.util.AttributeSet attrs) {
super (context, attrs);
}
  
/**
* Integer.MAX_VALUE >> 2,如果不设置,系统默认设置是显示两条
*/
public void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 ,
MeasureSpec.AT_MOST);
super .onMeasure(widthMeasureSpec, expandSpec);
  
}
  
}

以上可以解决scrollView内嵌listView,但是有一个问题是第一次进入界面时动态加载listview的items后页面会跳转到listview的第一个子项,这很蛋疼,
无奈又不知道怎么解决,就先用
scrollView.post(new Runnable() {  
      //让scrollview跳转到顶部,必须放在runnable()方法中
    @Override  
    public void run() {  
     scrollView.scrollTo(0, 0);  
     }  
   }); 这个方法过度下,希望有知道的朋友还给点解决方案

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值