今天有朋友问到关于边框间距的GridView怎么定义,刚好之前有遇到类似的,在这篇博客里,除了带间距的GridView,也整理下关于GridView/ListView/ScrollView这些滚动控件的那些事。
1.自定义边框间距的GridView
a.老规矩,直接贴代码吧!
public class MyGridView extends GridView { public MyGridView(Context context) { super(context); } public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void dispatchDraw(Canvas canvas){ super.dispatchDraw(canvas); View localView1 = getChildAt(0); int column = getWidth() / localView1.getWidth(); int childCount = getChildCount(); //item个数 Paint localPaint; localPaint = new Paint(); localPaint.setStyle(Paint.Style.STROKE); localPaint.setColor(getContext().getResources().getColor(R.color.item_line)); for(int i = 0;i < childCount;i++){ View cellView = getChildAt(i); canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), localPaint); canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), localPaint); /* if(i==childCount-1){ canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), localPaint); }*/ } }
}
b.具体怎么定义可以看上面的代码,主要根据Item的位置来画出其边框。
2.关于GridView/ListView/ScrollView的那些事
1.看到GridView/ListView/ScrollView这三者,很容易就能想到这三个控件由于相互嵌套发生的问题,其实解决其嵌套导致的滚动冲突引起的内容显示不全这个问题,有多种方式可以解决:
1.自定义GridView,ListView/ScrollView也一样适用。
a.代码:
public class MyGridView extends GridView { public MyGridView(Context context) { super(context); } public MyGridView(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); } }
b.可以直接在布局中使用ScrollView或ListView嵌套该MyGridView控件了,不会有GridView显示不全的情况发生,是不是非常方便。
2.假如在项目中用到ScrollView嵌套ListView,我们也可以考虑是否能将ListView更换成LinearLayout,通过代码动态add其item到LinearLayout里。
3.主动计算和设置ListView的高度,通过计算其item的高度和+头部高度+底部高度,从而得到其填充内容后的高度,再将其设置成ListView的高度。
a.代码:
public class MeasureUtils{ public static void setListViewHeight(ListView listView) { if(listView == null) { return; } 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); } }
b.上面这段代码是从网上搜索到的,之前也有使用到,但是在该博客的下面提出了两点要注意的:
1.Adapter中getView方法返回的View的必须由LinearLayout组成,因为只有LinearLayout才 有measure()方法,如果使用其他的布局如RelativeLayout,在调用listItem.measure(0, 0); 时就会抛异常,因为除LinearLayout外的其他布局的这个方法就是直接抛异常的 2.需要手动把ScrollView滚动至最顶端,因为使用这个方法的话,默认在ScrollView顶端的项是ListViews
总结:在大多数时候,一般我会使用LinearLayout替代ListView这种方式,也较常使用自定义ListView/ScrollView/GridView这种方式,感觉非常快捷好用。