您的位置:首页 > 其它

自定义GridView实现分割线解析

2017-02-20 09:30 423 查看
前两天在些项目的时候碰到常用的GridView要实现一些分割线,之前就是用本方法利用listView和Item的背景颜色的不同线显示分割线。这是最low的一种做法。于是我就简单的写了一个自定义的 GridView。

我们可以先看List怎么设置分割线

android:divider
android:dividerHeight


然而我们都知道 GirdView默认是没有网格线的,那么该如何设置呢?

如何设置GridView的分割线

第一种通过设置背景颜色的不同来充当divier

首先设置GridView的背景颜色

设置item的背景颜色

设置item的宽高

<GridView
android:id="@+id/mgv_griview2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:background="@color/black3"
android:horizontalSpacing="1dp"
android:verticalSpacing="1dp"
android:padding="2dp"
android:numColumns="3" >


布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:gravity="center"
android:layout_margin="5dp"
android:layout_height="match_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/ic_launcher"
android:id="@+id/myitem_gv"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="10dp"
android:text="图片"/>
</LinearLayout>


自定义View来解决GridView的分割线

效果图



**
*  类功能描述:</br>
* Created by Administrator on 2017/2/19 0018.
* 博客地址: http://blog.csdn.net/androidstarjack * @author androidstar
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*  公众号: 终端研发部
*/

public class MyGridView extends GridView {
/**
* 默认的分割线的颜色
* 也可以在布局中设置
*/
private int diverColor = R.color.color1;
/**
* 默认的分割线的高度
* 也可以在布局中设置
*/
private int diverHeight = 1;
/**
* 所使用的画笔
*/
private Paint paint;

private  Context context;
public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context =context;
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.gv_acusttrs);
diverHeight = (int) typedArray.getDimension(R.styleable.gv_acusttrs_divierHeight,10);
diverColor = typedArray.getResourceId(R.styleable.gv_acusttrs_divierColor,R.drawable.editext_slelect_black4);
typedArray.recycle();
paint = new Paint();
paint.setColor(ContextCompat.getColor(context,diverColor));
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeWidth(diverHeight);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
/**
* 动态修改默认的分割线的颜色
*/
public void setDiverColor(int diverColor){
this.diverColor = diverColor;
invalidate();
}
/**
* 动态修改默认的分割线的颜色
*/
public void setDiverHeight(int diverHeight){
this.diverHeight = diverHeight;
invalidate();
}
/**
*
* @param canvas
*/

/*  @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
rect.left = DensityUtil.getScreenIntWidth(context) / 4;
rect.top = DensityUtil.getScreenIntHeight(context) / 4;
rect.right = DensityUtil.getScreenIntWidth(context)/ 4 * 3;
rect.bottom = DensityUtil.getScreenIntHeight(context)/ 4 * 3;
canvas.drawRect(rect,paint);
}*/
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
View localView1 = getChildAt(0);//得到第一个view
int column = getWidth() / localView1.getWidth();//列数
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View cellView = getChildAt(i);
if ((i + 1) % column == 0) {//每一行最后一个
canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), paint);
} else if ((i + 1) > (childCount - (childCount % column))) {//最后一行的item
canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), paint);
} else {
canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), paint);
canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), paint);
}
}
}
}


我们都知道这里用到了dispatchDraw方法

/**
* Called by draw to draw the child views. This may be overridden
* by derived classes to gain control just before its children are drawn
* (but after its own view has been drawn).
* @param canvas the canvas on which to draw the view
*/
protected void dispatchDraw(Canvas canvas) {

}


View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds()然后是draw(Canvas c)方法.有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小

画完背景后,draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法,

dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(),

相关demo现在地址:

MyGridViewApplication.rar

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809

微信公众号:终端研发部



(欢迎关注学习和交流)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: