正 常来说,在ScrollView添加一个ListView后在真机上只会显示ListView的一行多一点,我也不理解为什么会这样,后来我把 ListView的layout_height改成400dip,而不是用match_parent和wrap_content,我发现这样的话 ListView就显示的多了很多。所以就产生了把ListView所有的item的高度算出来给ListView设置的想法。下面是代码:

源码:http://www.jinhusns.com/Products/Download/?type=xcj

Java代码  

  1. public void setListViewHeightBasedOnChildren(ListView listView) {

  2. ListAdapter listAdapter = listView.getAdapter();

  3. if (listAdapter == null) {

  4. return;

  5. }

  6. int totalHeight = 0;

  7. for (int i = 0; i < listAdapter.getCount(); i++) {

  8. View listItem = listAdapter.getView(i, null, listView);

  9. listItem.measure(0, 0);

  10. totalHeight += listItem.getMeasuredHeight();

  11. }

  12. ViewGroup.LayoutParams params = listView.getLayoutParams();

  13. params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));

  14. params.height += 5;//if without this statement,the listview will be a little short

  15. listView.setLayoutParams(params);

  16. }

在代码的倒数第二行二我又给加了5个像素,这是因为我在listview的属性里面添加了padding=5dip。 
然后每次ListView的数据一有变化就用这个函数设置一下就好了,不过这样总感觉效率很低,希望有达人给指点一下。

简单来说就是把layout_height写死,这种办法也很适用于GridView(如果能估计得出GridView的高度的话)。

listview与ScrollView老问题的另类解法 
http://www.eoeandroid.com/thread-42893-1-1.html 

几天一直被listview怎么合理的放进scorllview中的问题困扰,尝试过把listview放入scorllview中的朋友都知
道,被放入的listview显示是有问题的,无论怎么设置layout都只显示大概2行的高度,看起来很郁闷,更别说美观了,后来上网查询了一下,解决

方法有的是用linearlayout替换listview,还有修改onmeasure的,我比较懒个人感觉很麻烦不喜欢,终于想出了一个还算和谐的解
决方法:xml中的textlist设置如下:

Java代码  

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="fill_parent"

  4. android:layout_height="wrap_content"

  5. android:orientation="vertical"

  6. android:background="#44444444">

  7. <ScrollView

  8. android:layout_width="fill_parent"

  9. android:layout_height="wrap_content">

  10. <LinearLayout

  11. android:id="@+id/ll1"

  12. android:layout_width="fill_parent"

  13. android:layout_height="wrap_content"

  14. android:scrollbars="vertical"

  15. android:orientation="vertical"

  16. android:paddingLeft="15dp"

  17. android:paddingRight="15dp"

  18. android:paddingTop="30dp"

  19. android:paddingBottom="30dp"

  20. android:background="#ff888888">

  21. <TextView

  22. android:text="あ"

  23. android:textColor="#ffeeeeee"

  24. android:textSize="18sp"

  25. android:layout_width="fill_parent"

  26. android:layout_height="wrap_content"></TextView>

  27. <ListView

  28. android:scrollbars="none"

  29. android:stackFromBottom="true"

  30. android:id="@+id/lv0"

  31. android:layout_width="fill_parent"

  32. android:layout_height="20dp"></ListView>

  33. </LinearLayout>

  34. </ScrollView>

  35. </LinearLayout>

其中的textview是我做的东西要用到的,和方法无关可以不看,然后就是在java中重新设置listview的高度了,目的是把listview“撑”开: 
LinearLayout.LayoutParams  lp5 =new LinearLayout.LayoutParam(LayoutParams.FILL_PARENT, listItem.size()*51-1); 

中第一个属性不必说了,第二个是为了计算listview要设置的总高度用的,51是我事先设置好的一行的高度(50)+每行之间的间隔(1)
而得来的,listItem.size()是我要显示的行数,用.setLayoutParams(lp5);来重新设置高度,其他别的设置跟以前一样,
想要源码我整理完之后贴出来

如果不想写死 ,Android 解决ListView 和 ScrollView 共存冲突的问题 
http://labs.chinamobile.com/mblog/532767_72693?wralxianxrnx 
http://blog.liaoxiaoqi.com/?p=503

下面是我的一个实现 步骤:

  • 1、继承LinearLayout,既然会冲突那就不用ListView 改成线性布局做动态布局效果

  • 2、继承BaseAdapter ,可以参照一下Android app源码中 Widget 目录下的SimpleAdapter 为前面扩展的LinearLayout做数据。

  • 3、模拟数据填充扩展后的BaseAdapter 为扩展后的LinearLayout 加载数据

第一步:新建LinearLayoutForListView 类使其扩展LinearLayout重写以下两个方法:

Java代码  

  1. public LinearLayoutForListView(Context context) {

  2. super(context);

  3. }

  4. public LinearLayoutForListView(Context context, AttributeSet attrs) {

  5. super(context, attrs);

  6. }

这两个方法可选,不过建议都写上,第一个方法可以让我们通过 编程的方式 实例化出来,第二个方法可以允许我们通过 XML的方式注册 控件,可以在第二个方法里面为扩展的复合组件加属性。为其添加get / set 方法

Java代码  

  1. /**

  2. * 获取Adapter

  3. *

  4. * @return adapter

  5. */

  6. public AdapterForLinearLayout getAdpater() {

  7. return adapter;

  8. }

  9. /**

  10. * 设置数据

  11. *

  12. * @param adpater

  13. */

  14. public void setAdapter(AdapterForLinearLayout adpater) {

  15. this.adapter = adpater;

  16. bindLinearLayout();

  17. }

  18. /**

  19. * 获取点击事件

  20. *

  21. * @return

  22. */

  23. public OnClickListener getOnclickListner() {

  24. return onClickListener;

  25. }

  26. /**

  27. * 设置点击事件

  28. *

  29. * @param onClickListener

  30. */

  31. public void setOnclickLinstener(OnClickListener onClickListener) {

  32. this.onClickListener = onClickListener;

  33. }

  34. sp;

第二步:新建AdapterForLinearLayout 类继承自BaseAdapter,并为其添加构造函数

Java代码  

  1. private LayoutInflater mInflater;

  2. private int resource;

  3. private List<? extends Map<String, ?>> data;

  4. private String[] from;

  5. private int[] to;

  6. public AdapterForLinearLayout(Context context,

  7. List<? extends Map<String, ?>> data, int resouce, String[] from,

  8. int[] to) {

  9. this.data = data;

  10. this.resource = resouce;

  11. this.data = data;

  12. this.from = from;

  13. this.to = to;

  14. this.mInflater = (LayoutInflater) context

  15. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  16. }


构造函数模仿 simpleAdapter 通过传进来的resouce 为布局设置数据。通过继承BaseAdapter
重要的实现方法在下面getView ,此方法判断通过传进来的 String[] from 与 int[] to 为分别查找出View
并为View 设置相应的Text,代码如下:

Java代码  

  1. @Override

  2. public View getView(int position, View convertView, ViewGroup parent) {

  3. // TODO Auto-generated method stub

  4. convertView = mInflater.inflate(resource, null);

  5. Map<String, ?> item = data.get(position);

  6. int count = to.length;

  7. for (int i = 0; i < count; i++) {

  8. View v = convertView.findViewById(to[i]);

  9. bindView(v, item, from[i]);

  10. }

  11. convertView.setTag(position);

  12. return convertView;

  13. }

  14. /**

  15. * 绑定视图

  16. * @param view

  17. * @param item

  18. * @param from

  19. */

  20. private void bindView(View view, Map<String, ?> item, String from) {

  21. Object data = item.get(from);

  22. if (view instanceof TextView) {

  23. ((TextView) view).setText(data == null ? "" : data.toString());

  24. }

  25. }

Tip:

  • BindView 方法是一个自定义方法,在方法体内可以为通过判断使本类更具灵活性,如上,你不仅可以判断是TextView 并且可以传入任何你想要的View 只要在方法体内加入相应判断即可,数据可以通过data 做相应处理,具体如何操作读者可另行测试。

  • convertView.setTag(position); 此句代码为View 设置tag 在以后我们可以通过 getTag 找出下标,后文有介绍如何通过下标操作数据。

下面是两个类的全部代码,读者可以无须更改直接使用:

Java代码  

  1. LinearLayoutForListView

  2. package  com.terry.widget;

  3. import  android.content.Context;

  4. import  android.util.AttributeSet;

  5. import  android.util.Log;

  6. import  android.view.View;

  7. import  android.widget.LinearLayout;

  8. public   class  LinearLayoutForListView  extends  LinearLayout {

  9. private  AdapterForLinearLayout adapter;

  10. private  OnClickListener onClickListener  =   null ;

  11. /**

  12. * 绑定布局

  13. */

  14. public   void  bindLinearLayout() {

  15. int  count  =  adapter.getCount();

  16. for  ( int  i  =   0 ; i  <  count; i ++ ) {

  17. View v  =  adapter.getView(i,  null ,  null );

  18. v.setOnClickListener( this .onClickListener);

  19. if  (i  ==  count  -   1 ) {

  20. LinearLayout ly  =  (LinearLayout) v;

  21. ly.removeViewAt( 2 );

  22. }

  23. addView(v, i);

  24. }

  25. Log.v( " countTAG " ,  ""   +  count);

  26. }

  27. public  LinearLayoutForListView(Context context) {

  28. super (context);

  29. }

  30. public  LinearLayoutForListView(Context context, AttributeSet attrs) {

  31. super (context, attrs);

  32. }

  33. /**

  34. * 获取Adapter

  35. *

  36. *  @ return  adapter

  37. */

  38. public  AdapterForLinearLayout getAdpater() {

  39. return  adapter;

  40. }

  41. /**

  42. * 设置数据

  43. *

  44. *  @ param  adpater

  45. */

  46. public   void  setAdapter(AdapterForLinearLayout adpater) {

  47. this .adapter  =  adpater;

  48. bindLinearLayout();

  49. }

  50. /**

  51. * 获取点击事件

  52. *

  53. *  @ return

  54. */

  55. public  OnClickListener getOnclickListner() {

  56. return  onClickListener;

  57. }

  58. /**

  59. * 设置点击事件

  60. *

  61. *  @ param  onClickListener

  62. */

  63. public   void  setOnclickLinstener(OnClickListener onClickListener) {

  64. this .onClickListener  =  onClickListener;

  65. }

  66. }

Java代码  

  1. AdapterForLinearLayout

  2. package  com.terry.widget;

  3. import  java.util.List;

  4. import  java.util.Map;

  5. import  android.content.Context;

  6. import  android.view.LayoutInflater;

  7. import  android.view.View;

  8. import  android.view.ViewGroup;

  9. import  android.widget.BaseAdapter;

  10. import  android.widget.TextView;

  11. public   class  AdapterForLinearLayout  extends  BaseAdapter {

  12. private  LayoutInflater mInflater;

  13. private   int  resource;

  14. private  List <?   extends  Map < String,  ?>>  data;

  15. private  String[] from;

  16. private   int [] to;

  17. public  AdapterForLinearLayout(Context context,

  18. List <?   extends  Map < String,  ?>>  data,  int  resouce, String[] from,

  19. int [] to) {

  20. this .data  =  data;

  21. this .resource  =  resouce;

  22. this .data  =  data;

  23. this .from  =  from;

  24. this .to  =  to;

  25. this .mInflater  =  (LayoutInflater) context

  26. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  27. }

  28. @ Override

  29. public   int  getCount() {

  30. //  TODO Auto-generated method stub

  31. return  data.size();

  32. }

  33. @ Override

  34. public  Object getItem( int  position) {

  35. //  TODO Auto-generated method stub

  36. return  data.get(position);

  37. }

  38. @ SuppressWarnings( " unchecked " )

  39. public  String get( int  position, Object key) {

  40. Map < String,  ?>  map  =  (Map < String,  ?> ) getItem(position);

  41. return  map.get(key).toString();

  42. }

  43. @ Override

  44. public   long  getItemId( int  position) {

  45. //  TODO Auto-generated method stub

  46. return  position;

  47. }

  48. @ Override

  49. public  View getView( int  position, View convertView, ViewGroup parent) {

  50. //  TODO Auto-generated method stub

  51. convertView  =  mInflater.inflate(resource,  null );

  52. Map < String,  ?>  item  =  data.get(position);

  53. int  count  =  to.length;

  54. for  ( int  i  =   0 ; i  <  count; i ++ ) {

  55. View v  =  convertView.findViewById(to[i]);

  56. bindView(v, item, from[i]);

  57. }

  58. convertView.setTag(position);

  59. return  convertView;

  60. }

  61. /**

  62. * 绑定视图

  63. *  @ param  view

  64. *  @ param  item

  65. *  @ param  from

  66. */

  67. private   void  bindView(View view, Map < String,  ?>  item, String from) {

  68. Object data  =  item.get(from);

  69. if  (view  instanceof  TextView) {

  70. ((TextView) view).setText(data  ==   null   ?   ""  : data.toString());

  71. }

  72. }

  73. }

对应的XML 如下:

Java代码  

  1. <? xml version="1.0" encoding="UTF-8" ?>

  2. < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"

  3. android:orientation ="vertical"  android:layout_width ="fill_parent"

  4. android:layout_height ="fill_parent" >

  5. < TextView  android:id ="@ +id/TextView01"

  6. android:layout_marginLeft ="10px"  android:textAppearance ="?android:attr/textAppearanceLarge"

  7. android:layout_width ="wrap_content"  android:layout_height ="wrap_content" >

  8. </ TextView >

  9. < TextView  android:id ="@ +id/TextView02"  android:layout_width ="wrap_content"

  10. android:textAppearance ="?android:attr/textAppearanceSmall"

  11. android:layout_marginLeft ="10px"  android:layout_height ="wrap_content" >

  12. </ TextView >

  13. < View  android:layout_height ="1px"  android:background ="#FFFFFF"

  14. android:layout_width ="fill_parent" ></ View >

  15. </ LinearLayout >

第三步:主页面使用控件并为其设置数据

  • XML如下:

    Java代码  

    1. < com.terry.widget.LinearLayoutForListView

    2. android:orientation ="vertical"  android:layout_width ="450px"

    3. android:layout_height ="fill_parent"  android:id ="@ +id/ListView01" >

    4. </ com.terry.widget.LinearLayoutForListView >

  • 加载数据如下:

    Java代码  

    1. lv  =  (LinearLayoutForListView) findViewById(R.id.ListView01);

    2. for  ( int  i  =   0 ; i  <   10 ; i ++ ) {

    3. HashMap < String, Object >  map  =   new  HashMap < String, Object > ();

    4. map.put( " key_name " ,  " name "   +  i);

    5. map.put( " value_name " ,  " value "   +  i);

    6. list.add(map);

    7. }

    8. final  AdapterForLinearLayout Layoutadpater  =   new  AdapterForLinearLayout(

    9. this , list, R.layout.test,  new  String[] {  " key_name " ,

    10. " value_name "  },  new   int [] { R.id.TextView01,

    11. R.id.TextView02 });

  • 事件操作,并通过下标得到数据源:

    Java代码  

    Tip:get方法是在Layoutadpater 封装的一个通过下标获取相应数据的方法请参考上文。

    1. lv.setOnclickLinstener( new  OnClickListener() {

    2. @ Override

    3. public   void  onClick(View v) {

    4. //  TODO Auto-generated method stub

    5. Toast.makeText(

    6. BlueToothActivity. this ,

    7. Layoutadpater.get(Integer.parseInt(v.getTag()

    8. .toString()),  " key_name " ),  1000 ).show();

    9. }

    10. });

    11. lv.setAdapter(Layoutadpater);

至此完成。有碰到这个问题的朋友可以试试。

有人的总结如下:

只要在设置ListView的Adapter后调用此静态方法即可让ListView正确的显示在其父ListView的ListItem中。但是要注意

的是,子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有
重写onMeasure(),所以会在onMeasure()时抛出异常。
  在ScrollView中嵌套ListView(或者
ScrollView)的另外一个问题就是,子ScrollView中无法滑动的(如果它没有显
示完全的话),因为滑动事件会被父ScrollView吃掉,如果想要让子ScrollView也可以滑动,只能强行截取滑动事件,有牛人在论坛 中发过代码说可以。虽然我没有亲自试过,但估计是可行的。
 
 虽然在ScrollView中显示ScrollView在技术上的难题可以攻破,但是这样的设计却是非常差的用户体验因为用户会不容易看到和操作子
ScrollView中的内容。比如好的设计是,父ListView的每个Item只显示概括性的描述,然后点击其Item会进入另外一个页面来详细描述
和展示以及对这个Item的操作。
 源码:http://www.jinhusns.com/Products/Download/?type=xcj
于是找到另外两种比较简单的方法,而且又没有影响的:
1.在ScrollView中添加一属性 android:fillViewport="true" ,这样就可以让ListView全屏显示了
2.指定ListView的高度 android:layout_height="420dp" ;

ScrollView与ListView冲突解决的更多相关文章

  1. ScrollView 和 ListView 冲突解决方案

    网上说了很多阿,什么linearLayout 实现listView 什么的.还设置高什么的. 其实,你们可能忘记了,如果出现 ScrollView 和 ListView 同时出现,那就是设计错误了. ...

  2. Android ScrollView 嵌套 ListView、 ListView 嵌套ScrollView Scroll事件冲突解决办法

    本人菜鸟一名,最近工作了,开始学习Android. 最近在做项目的时候,UX给了个design,大概就是下拉刷新的ListView中嵌套了ScrollView,而且还要在ScrollView中添加动画 ...

  3. Android之ScrollView嵌套ListView冲突

    在ScrollView中嵌套使用ListView,ListView只会显示一行多一点.两者进行嵌套,即会发生冲突.由于ListView本身都继承于ScrollView,一旦在ScrollView中嵌套 ...

  4. 冲突--ScrollView嵌套ListView冲突问题的最优解决方案

    项目做多了之后,会发现其实 ScrollView嵌套ListVew或者GridView等很常用,但是你也会发现各种奇怪问题产生.根据个人经验现在列出常见问题以及代码最少最简单的解决方法. 问题一 :  ...

  5. ScrollView嵌套ListView冲突问题的最优解决方式

    项目做多了之后.会发现事实上ScrollView嵌套ListVew或者GridView等非经常常使用,可是你也会发现各种奇怪问题产生.依据个人经验如今列出常见问题以及代码最少最简单的解决方法. 问题一 ...

  6. Android之ScrollView嵌套ListView冲突 (listView只显示一行)

    在ScrollView中嵌套使用ListView,ListView只会显示一行多一点.两者进行嵌套,即会发生冲突.由于ListView本身都继承于ScrollView,一旦在ScrollView中嵌套 ...

  7. 解决ScrollView嵌到listView冲突问题

    方法一: 把下面的方法放在绑定适配器操作的下面就行. /** * 重新计算ListView的高度,解决ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起冲突的问题 * @ ...

  8. Android——MeasureSpec学习 - 解决ScrollView嵌套ListView和GridView冲突的方法

      原文地址:http://blog.csdn.net/yuhailong626/article/details/20639217   在自定义View和ViewGroup的时候,我们经常会遇到int ...

  9. ScrollView嵌套使用ListView冲突的解决与分析

    因为ScrollView与ListView都是具有滚动条的控件,所以嵌套在一起使用的时候可能会出现事件的冲突,比如我就遇见了ListView中只显示一条数据的问题.解决的办法,就是自定义了一个List ...

随机推荐

  1. Unity3d使用经验总结 数据驱动篇

    我这里说的数据驱动,不是指某种框架,某种结构,或者某种编码方式. 我要说的,是一种开发方式. 大家都知道,U3D中,我们可以为某个对象编写一个脚本,然后将这个脚本挂在对象上,那这个对象就拥有了相应的能 ...

  2. linux下目录操作

    1. 常用函数 #include <dirent.h> //open a directory //failed-NULL, other-return a DIR stream DIR *o ...

  3. 趣味C程序-HelloWord

    说明:刚才写了一个基础的helloWord程序(很早以前从其他地方收集的.),本以为群里面的人是可以答对了,但是我错了,没有人.他们的错误往往被程序的外表给蒙蔽了. 很多人的回答是0.如果你仔细看的话 ...

  4. xamarin误删vEthernet(internal Ethernet Port Windows Phone Emulator) 网络设备的处理。

    昨天一不小心误删了xamarin 开发环境下的虚拟设备网络设备.名称为:vEthernet(internal Ethernet Port Windows Phone Emulator).导致原来能正确 ...

  5. js笔记——call,apply,bind使用笔记

    call和apply obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1, arg2, ...]); 两者作用一致,都是把obj( ...

  6. Java程序员的日常 —— 多进程开发

    最近再弄进程管理相关的工作,因此必要的就涉及到各种系统下关于进程的管理. 这里简单的介绍下: 如何在Java中执行命令 在windows下肯定是dos命令了,而在linux则为shell命令.执行的方 ...

  7. 数据库MySQL开篇

    作为一名前端,后天方面的知识虽说不一定要精通后台但是对后台方面的知识有一定了解是非常必要的. 今天先说一些概念方面的,因本人才疏学浅,对于数据库这方面的自学相当于摸着石头过河,有什么写的不对的地方,希 ...

  8. try-catch和throw,throws的区别

    java里的异常多种多样,这是一种非常有用的机制,它能帮助我们处理那些我们未知的错误,在java里,关于异常的有throw throws,还有一个try catch 程序块.接下来我们挨个看看这几个的 ...

  9. Mybatis 缓存

    1. 一级缓存:其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相同,不同在于其存 ...

  10. ng-表单验证

    表单验证<AngularJs>   常用的表单验证指令 1. 必填项验证 某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: <input type ...