先看看效果
1.在布局文件中定义ListView和它的父控件RelativeLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.vieboo.ltline.MainActivity"
android:padding="10dp"
android:id="@+id/layout_main">
<include
android:id="@+id/layout_top"
layout="@layout/layout_list_item" />
<ListView
android:id="@+id/list_view"
android:layout_below="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</RelativeLayout>
2.自定义一个继承自View的LineCanvasView类,来实现画线
- 将标题行View(也就是ListView的itemView)传入LineCanvasView中
- 重写onDraw(Canvas canvas)方法,根据标题行View的宽高和ListView的宽高来计算线的位置,最后绘制边框线
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
//listview的item的高度(标题行的高度)
int childHeight = layout_title.getHeight();
//listview加标题总高度
int totalHeight = listView.getHeight() + childHeight;
//listview宽度
int width = listView.getWidth();
//横向子view的数量
int countHorizontal = layout_title.getChildCount();
//纵向最大行数
int countVerticalLine = totalHeight / childHeight;
//listview当前显示列表数量
int itemCount = listView.getChildCount();
/**
* listview数据不够填满整页时
*/
if(itemCount < countVerticalLine) {
totalHeight = countVerticalLine * childHeight;
//竖线
canvas.drawLine(0, 0, 1, totalHeight, mPaint);
for(int i=0; i<countHorizontal; i++) {
View childView = layout_title.getChildAt(i);
float startX = childView.getX() + childView.getWidth();
canvas.drawLine(startX - 1, 0, startX, totalHeight, mPaint);
}
//横线
canvas.drawLine(0, 0, width, 1, mPaint);
int tempHeight = 0;
for(int i=0; i<countVerticalLine; i++) {
tempHeight += childHeight;
canvas.drawLine(0, tempHeight - 1, width, tempHeight, mPaint);
}
}
/**
* listview数据超过整页可以显示的数据时
*/
else {
//竖线
canvas.drawLine(0, 0, 1, totalHeight, mPaint);
for(int i=0; i<countHorizontal; i++) {
View childView = layout_title.getChildAt(i);
float startX = childView.getX() + childView.getWidth();
canvas.drawLine(startX - 1, 0, startX, totalHeight, mPaint);
}
//横线
canvas.drawLine(0, 0, width, 1, mPaint);
canvas.drawLine(0, childHeight - 1, width, childHeight, mPaint);
float draw_position = 0;
int i=itemCount-countVerticalLine;
for ( ; i < countVerticalLine; i++) {
View itemView = listView.getChildAt(i);
float startY = itemView.getY();
int itemHeight = itemView.getHeight();
draw_position = startY + itemHeight + childHeight - 1;
canvas.drawLine(0, draw_position, width, draw_position, mPaint);
}
}
}
3.在Activity中监听ListView的滑动事件,事实更新LineCanvasView的绘制方法
//当listview数据超过整页可以显示的数据时,需要动态绘制line
list_view.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(null != lineCanvasView) lineCanvasView.invalidate();
}
});
如果不需要标题行可以先拿到ListView的Item高度然后在onDraw()方法里计算,但是绘制算法需要改动一下这里就不尝试了,有需求的同学可以自己尝试一下。
版权声明:本文为sjzx3142原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。