具有分割线效果的自定义控件LineGridView
一、LineGridView简介
LineGridView对官方的GridView控件进行了一些拓展,增加了分割线效果,但是不显示外框,最外部分不构成封闭效果,从而达到更美观的效果,具体的Demo如下图所示;另外,很好的解决了由于设置了verticalSpacing、horizontalSpacing后分割线断开、错乱的问题(网上有些这类自定义控件会出现此问题)。
二、LineGridView的快速使用
直接在android studio项目中添加依赖就可以了。
- 在外层build.gradle中添加如下代码:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
- 在项目build.gradle添加依赖:
dependencies {
...
implementation 'com.github.BillWang514:LineGridView:1.0'
}
三、基本使用方法
在介绍LineGridView的使用方法之前,先来了解一下GridView这个控件的一些常用属性与方法,熟悉的同学可以直接跳过GridView的介绍。
1. GridView的关键属性详解
XML 属性 | 值 | 描述 | 对应方法 |
---|---|---|---|
android:columnWidth | dimension类型(px,dp,sp,in,mm) | 定义每一列的固定宽度 | setColumnWidth(int) |
android:horizontalSpacing | dimension类型 | 定义两列之间的水平间隔 | setHorizontalSpacing(int) |
android:verticalSpacing | dimension类型 | 定义两行之间的垂直间隔 | setVerticalSpacing(int) |
android:numColumns | 整数、auto_fit | 定义展示的列数 | setNumColumns(int) |
android:stretchMode | none、spacingWidth、columnWidth、spacingWidthUniform | 定义列拓展填充有限闲置空间的方式 | setStretchMode(int) |
- android:numColumns中的“auto_fit”作用:在有效空间展示尽可能多的列数。
- android:stretchMode中的4常量解析:
常量 | 值 | 描述 |
---|---|---|
none | 0 | 扩展无效 |
spacingWidth | 1 | 列与列之间的空间被扩展 |
columnWidth | 2 | 每一列被相等的拓展 |
spacingWidthUniform | 3 | 列与列之间的空间被均匀的扩展 |
可能有的同学还是不知道它们的区别和显示效果是什么,通过下面的图你就能明白了;
2. GridView的常用方法
- ListAdapter:getAdapter()
返回关联的Adapter。 - int:getColumnWidth()
返回列的宽度。 - int:getGravity()
返回描述子视图被放置的方式的标识。 - int:getHorizontalSpacing()
返回列间的水平间隔大小。
仅会计算当前布局。如果调用了setHorizontalSpacing(int)来设置间隔,但布局还没有完成,这个方法会返回一个旧值。如果想要明确地获取这个间隔,使用getRequestedHorizontalSpacing()方法请求。 - int:getNumColumns()
返回列数。如果网格没有被布局,则返回AUTO_FIT。 - int:getRequestedColumnWidth()
返回请求的列宽度。
这可能不是真实的列宽度。使用getColumnWidth()获取当前真实的列宽度。 - int:getRequestedHorizontalSpacing()
返回请求的列间的水平间隔。
这个值可能是布局期间的局部样式,也可能是默认的样式,或是使用setHorizontalSpacing(int)方法设置的值。如果布局尚未完成或GridView计算得到了一个和请求的不同的水平间隔,它与getHorizontalSpacing()将有不同的返回值。 - int:getStretchMode()
返回扩展模式。 - int:getVerticalSpacing()
返回行间的垂直间隔。
onInitializeAccessibilityNodeInfoForItem(View view, int position, AccessibilityNodeInfo info)
使用列表中实际项的信息初始化一个AccessibilityNodeInfo。 - setAdapter(ListAdapter adapter)
为GridView设置适配器。 - setColumnWidth(int columnWidth)
设置宽度。 - setGravity(int gravity)
设置网格的中重心。重心描述了子视图的摆放方式。 - setHorizontalSpacing(int horizontalSpacing)
设置列间的水平间隔。 - setNumColumns(int numColumns)
设置列数。 - setRemoteViewsAdapter(Intent intent)
设置该AbsListView使用远程视图适配器,该适配器通过特定的Intent连接到一个RemoteViewsService。 - setSelection(int position)
设置当前选中项。 - setStretchMode(int stretchMode)
设置列表项如何拓展填充闲置空间的方式,有4个常量分别为:NO_STRETCH,STRETCH_SPACING,STRETCH_COLUMN_WIDTH,STRETCH_SPACING_UNIFORM。
3. LineGridView独有属性
XML 属性 | 值 | 描述 |
---|---|---|
app:lineColor | #开头颜色值或@引用 | 设置分割线的颜色 |
app:lineWidth | dimension类型 | 设置线条的粗细(默认0.8dp) |
app:linePadding | dimension类型 | 分割线开口值(默认0dp) |
app:lineType | full_line、dash_line | 设置分割线类型,有实线(默认)和虚线两种 |
app:dashGap | dimension类型 | 虚线中空白间隙 |
app:dashWidth | dimension类型 | 虚线中实线长度(及相邻间隙的距离) |
四、简单Demo实现
1. 布局设置
新建一个项目,在activity_main.xml中使用LineGridView控件。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.bluefire.widget.LineGridView
android:id="@+id/lineGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="10dp"
android:background="@drawable/shape_write_radius"
android:columnWidth="80dp"
android:numColumns="3"
android:stretchMode="columnWidth"
android:elevation="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lineColor="#CCC5C5"
app:lineWidth="0.8dp"
app:linePadding="15dp" />
</android.support.constraint.ConstraintLayout>
2. Adapter设置
自定义一个adapter继承自BaseAdapter。
public class LineGirdAdapter extends BaseAdapter {
private List<Map<String, Object>> dataList;
private LayoutInflater layoutInflater;
public LineGirdAdapter(Context context, List<Map<String, Object>> list) {
this.dataList = list;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.grid_view_item_layout, null);
holder.text = convertView.findViewById(R.id.textView);
holder.imageView = convertView.findViewById(R.id.imageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText((String)dataList.get(position).get("text"));
holder.imageView.setImageResource((int)dataList.get(position).get("img"));
return convertView;
}
class ViewHolder {
ImageView imageView;
TextView text;
}
}
3. 网格子布局
创建一个layout文件并命名为grid_view_item_layout,在上述自定义的adaper中引用,这里用了显示图片和文字的两个控件,上下排列。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/map"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:textSize="16sp"
tools:text="文字" />
</LinearLayout>
4. 在活动中获取控件
在MainActivity中获取控件,注入要显示的数据。
public class MainActivity extends AppCompatActivity {
@BindView(R.id.lineGridView)
LineGridView lineGridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
}
private void initView(){
LineGirdAdapter adapter = new LineGirdAdapter(this, getDataList());
lineGridView.setAdapter(adapter);
}
private List<Map<String,Object>> getDataList(){
String[] names = new String[]{"技术手册","维修记录","地图","出行","饮食","住宿","费用报销","审批","考勤"};
int[] images = new int[]{R.drawable.head_book,R.drawable.record,R.drawable.map,R.drawable.trip,
R.drawable.food,R.drawable.stay,R.drawable.apply_for_reimbursement,R.drawable.approval,R.drawable.attendance};
List<Map<String,Object>> list = new ArrayList<>();
for (int i = 0; i < names.length; i++){
Map<String, Object> map = new ArrayMap<>();
map.put("text",names[i]);
map.put("img",images[i]);
list.add(map);
}
return list;
}
}
做到这里,调试运行就能得到文章开头的第一幅图的效果了。
最后再附上demo源码地址:https://github.com/BillWang514/LineGridView.git