Android ListView (1) -- 使用自定义的分割线

ListView默认的分割线

ListView会在item之间添加一个默认的分割线。在XML中添加一个ListView,其对应的属性如下。

可以看到ListView默认样式中设置了一个Divider,使用的当前主题中的listDivider配置的Drawable对象来作为分割线。
查看Android SDK中data\res\values目录中的themesXXX.xml,可以找到六个不同Theme下的listDivider配置。分列如下。

文件名 主题名 listDivider配置
themes.xml Theme @drawable/divider_horizontal_dark
themes.xml Theme.Light @drawable/divider_horizontal_bright
themes_holo.xml Theme.Holo @drawable/list_divider_holo_dark
themes_holo.xml Theme.Holo.Light @drawable/list_divider_holo_light
themes_material.xml Theme.Material @drawable/list_divider_material
themes_material.xml Theme.Material.Light @drawable/list_divider_material

这六个listDivider配置对应五个文件,这五个文件都可以在data\res\values\drawableXXX目录中找到。其中list_divider_material对应一个xml文件,其他四个文件都是.9的png图片。
尽管Android为不同主题下的ListView提供了默认的分割线,通常在还是需要为ListView自定义分割线。

为何要自定义分割线

  1. 应用UI配色需要
    当应用使用的主题确定时,分割线对应的颜色也就确定了。例如在Theme.Light主题下,分割线通常是一个颜色为灰色,高度为1dp的线。如果应用希望分割线显示的更明显或者更不明显,或者是应用需要使用更加个性化的分割线,又或许是应用修改了默认的ListView的背景颜色,需要让分割线和背景色更加搭配等等,很多情况下都需要对ListView分割线进行自定义。
  2. 统一不同主题下的显示效果
    前面看到Android为不同主题下的ListView提供了不同的默认分割线,这在app开发时很方便,但是对第三方SDK开发来说是却是个缺点。因为主题是在app开发时在AndroidManifest.xml中配置的,对SDK来说,SDK在开发时无法确定集成该SDK的app应用的是哪个主题,这就会导致原本期望的显示效果,由于接入的app应用主题的不同而产生变化。这时就需要用自定义的分割线替换默认的分割线。
  3. 统一不同机型下的显示效果
    由于Android的开发性,部分设备厂家会修改原生的ListView分割线,这导致即使在相同主题下默认分割线的显示效果上也存在差异。
    下面两张图片中应用使用的是同一个主题,ListView也都是默认样式。左边是一般机型的显示效果,右边是Sony Z2某个ROM下的显示效果。可以看到右边的ListView分割线颜色更深。放大后还可以看到右边分割线的三个像素还存在颜色渐变效果。
    Android ListView (1) -- 使用自定义的分割线_第1张图片

自定义ListView分割线

自定义ListView分割线可以在XML中配置,也可以在代码中配置。
XML中配置方式如下。通过设置android:divider来设置分割线颜色,通过android:dividerHeight属性来设置分割线高度。

<ListView  android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#00000000" android:divider="#F1F1F1" android:dividerHeight="1dp" android:overScrollMode="never" >
</ListView>

代码中配置方法如下。通过setDivider()设置分割线颜色,通过setDividerHeight()设置分割线高度。

ListView listView = (ListView) view.findViewById(R.id.listView);
listView.setCacheColorHint(0x00000000);
listView.setDivider(new ColorDrawable(ContextUtil.getColor(R.color.divider)));
listView.setDividerHeight(context.getResources().getDimensionPixelSize(R.dimen.divider_height));

注意:如果android:divider配置的是一个颜色,或者setDivider()配置的是一个ColorDrawable对象,一定要通过android:dividerHeight或setDividerHeight()来设置分割线的高度。不能试图只设置分割线颜色,然后让ListView使用默认分割线高度。查看Android源码可以看到,在调用setDivider()时(通过XML的android:divider配置在读取后也会调用setDivider()),会执行传入的Drawable对象的getIntrinsicHeight()方法,用返回结果来设置分割线的高度,对ColorDrawable来说,其getIntrinsicHeight()方法返回结果始终是-1。所以,如果不通过android:dividerHeight或setDividerHeight()来设置分割线的高度,是无法看到分割线的。

实践建议

如果项目中需要多处用到ListView,每个ListView都单独设置分割线颜色和高度比较麻烦,也容易遗漏。可以从ListView派生一个类,在派生类的构造方法中添加如下几行代码。在XML中直接使用派生出来的新类即可。

this.setCacheColorHint(0x00000000);
this.setDivider(new ColorDrawable(ContextUtil.getColor(R.color.divider)));
this.setDividerHeight(context.getResources().getDimensionPixelSize(R.dimen.divider_height));

注意:这里除了设置分割线颜色和高度外,还调用setCacheColorHint()。这涉及到ListView的另外一个滑动后背景变黑的问题,也是建议所有用到ListView的地方都执行的。参见 http://blog.csdn.net/ccpat/article/details/46793031。

你可能感兴趣的:(Android ListView (1) -- 使用自定义的分割线)