• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    3年前 (2015-10-05)  Android |   抢沙发  12 
    文章评分 0 次,平均分 0.0

    在之前的编程里,我还没有遇到过要在一个ListView中嵌套一个GridView或是在一个GridView中嵌套一个ListView。所以今天事儿来了!我花了一将近3个小时,找到了为什么我在一个ListView中添加一个GridView时,只显示一行GridView的原因;另外,这3个小时的付出,又让我学会了另一件事——在局部找不到原因的时候,要跳出来,从更大的范围寻找原因。废话了这么多,那么究竟是为什么只显示一行GridView呢?

    因为在Android中,有这样一个限制,两ScrollView型的控件不能相互嵌套。像ListView和GridView就都是ScrollView型的控件。因为嵌套后,两个ScrollView型控件的滑动效果就丧失了,同时被嵌套控件的高度也被限定为一行的高度。那我们还能不能嵌套两个ScrollView型的控件呢?肯定是可以的。方法有两种:一是我们去需要自定义ListView或是GridView,并重写其onMeasure()方法。

    如下:

    public class NoScrollGridView extends GridView { 
    	public NoScrollGridView(Context context) { 
    		super(context); 
    	} 
    	public NoScrollGridView(Context context, AttributeSet attrs) { 
    		super(context, attrs); 
    	}
    
    	@Override 
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); 
    		super.onMeasure(widthMeasureSpec, expandSpec); 
    	}
    }

    ListView也同理。
    还有一种方法是我们重新动态地计算我们现在需要的高度。在我们调用Adapter的时候,我们获得现在这个时候的GridView有多少个,单个GridView的高度,然后计算总高度。具体代码如下:

    /**
    	 * 重新计算listView高度
    	 * @param listView
    	 */
    	public static void setListViewHeightBasedOnChildren(ListView listView) {
    		// 获取ListView对应的Adapter
    		ListAdapter listAdapter = listView.getAdapter();
    		if (listAdapter == null) {
    			return;
    		}
    
    		int totalHeight = 0;
    		for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
    			View listItem = listAdapter.getView(i, null, listView);
    			listItem.measure(0, 0); // 计算子项View 的宽高
    			totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
    		}
    
    		ViewGroup.LayoutParams params = listView.getLayoutParams();
    		params.height = totalHeight
    				+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    		// listView.getDividerHeight()获取子项间分隔符占用的高度
    		// params.height最后得到整个ListView完整显示需要的高度
    		listView.setLayoutParams(params);
    	}

    在我们setAdapter()的之前,我们调用上面的方法,如setListViewHeightBasedOnChildren(accomplishmentStateListView);
    因为我是在ListView中嵌套GridView,所以重新计算GridView的总高度的时候,要放在setAdapter(...GridViewAdapter)这个BaseAdapter的衍生类里。代码如下:

    /**
    	 * 计算gridview高度
    	 * @param gridView
    	 */
    	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);
    	}

    这样我们就可以在ListView中添加GridView了。。。
    注:两个SrcollView型的控件可以是:
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ... ...

     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/4345.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享