ScrollView嵌套ListView或gridview

来源:互联网 发布:淘宝网一年的销售额 编辑:程序博客网 时间:2024/05/17 07:59

1.手动设置ListView高度
经过测试发现,在xml中直接指定ListView的高度,是可以解决这个问题的,但是ListView中的数据是可变的,实际高度还需要实际测量。于是手动代码设置ListView高度,在为ListView设置了Adapter之后使用,就可以解决问题了。
同时:mListview.setSelection(position);方法失效

public static 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);    }    public static void setGridViewHeightBasedOnChildren(GridView gridView) {        // 获取GridView对应的Adapter        ListAdapter listAdapter = gridView.getAdapter();        if (listAdapter == null) {            return;        }        int rows;        int columns = 0;        int horizontalBorderHeight = 0;        Class<?> clazz = gridView.getClass();        try {            // 利用反射,取得每行显示的个数            Field column = clazz.getDeclaredField("mRequestedNumColumns");            column.setAccessible(true);            columns = (Integer) column.get(gridView);            // 利用反射,取得横向分割线高度            Field horizontalSpacing = clazz                    .getDeclaredField("mRequestedHorizontalSpacing");            horizontalSpacing.setAccessible(true);            horizontalBorderHeight = (Integer) horizontalSpacing.get(gridView);        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        }        // 判断数据总数除以每行个数是否整除。不能整除代表有多余,需要加一行        if (listAdapter.getCount() % columns > 0) {            rows = listAdapter.getCount() / columns + 1;        } else {            rows = listAdapter.getCount() / columns;        }        int totalHeight = 0;        for (int i = 0; i < rows; i++) { // 只计算每项高度*行数            View listItem = listAdapter.getView(i, null, gridView);            listItem.measure(0, 0); // 计算子项View 的宽高            totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度        }        ViewGroup.LayoutParams params = gridView.getLayoutParams();        params.height = totalHeight + horizontalBorderHeight * (rows - 1);// 最后加上分割线总高度        gridView.setLayoutParams(params);    }

2.使用单个ListView取代ScrollView中所有内容
public View getView(int position, View convertView, ViewGroup parent) {
switch (position) {
case 1:

        break;    default:        break;    }    return convertView;}

3.自定义可适应ScrollView的ListView和gridview

public class NotRollListView extends ListView  {      public NotRollListView(android.content.Context context,              android.util.AttributeSet attrs)      {          super(context, attrs);      }    /**      * 重新计算高度     */      public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)      {          int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                  MeasureSpec.AT_MOST);          super.onMeasure(widthMeasureSpec, expandSpec);      }  }  public class NotRollGridView extends GridView  {      public NotRollGridView(android.content.Context context,              android.util.AttributeSet attrs)      {          super(context, attrs);      }    /**      * 重新计算高度     */      public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)      {          int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                  MeasureSpec.AT_MOST);          super.onMeasure(widthMeasureSpec, expandSpec);      }  }  

4.采用添加HeaderView的方式

mCityLocalView = mLayoutInflater.inflate(R.layout.select_city_item_local, mLvCitylist,false);mListview.addHeaderView(mCityLocalView);

注意:
1有点影响效率,3目前有不明问题,在有A~Z通讯录view的情况下,加载很慢
方法1和方法3会有一个问题:加载时默认显示的首项是ListView
2,4目前没什么问题,就是比较麻烦

解决方案:
1.手动滚动到顶端 mScrollView.smoothScrollTo(0, 0);
2.设置listview失去焦点 mListView.setFocusable(false);
注意:在xml布局里面设置android:focusable=“false”不生效
推荐方法2,4
1,3在加载多个item的时候会出现卡顿现象(因为每次渲染item都要计算在scrollview中的高度)

recycleview同样适用,数据不多的时候可以使用,数据多的话不建议

package com.jgw.supercode.ui.widget;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;/** * Created by zx on 2016/7/26. */public class NotRollRecyclerView extends RecyclerView {    public NotRollRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, expandSpec);    }}
0 0
原创粉丝点击