关闭

ScrollView嵌套ListView或gridview

标签: gridviewlistview
446人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:83034次
    • 积分:1465
    • 等级:
    • 排名:千里之外
    • 原创:59篇
    • 转载:10篇
    • 译文:1篇
    • 评论:23条
    博客专栏
    文章分类