You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

StickyListHeadersAdapter复用同色ColorDrawable背景显示异常问题

问题

我通过se.emilsjolander.stickylistheaders.StickyListHeadersAdapter定义了自定义适配器MyCustomStickyListAdapter,用于展示筛选后的Movies列表。通过自定义方法setViewCompositeBackgroundColor,利用LayerDrawable为列表行设置分段背景色:条件不满足时用默认白色,满足时用绿色、红色、粉色等颜色。

相关实现代码如下:

  • 导入包:
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
  • 自定义适配器:
public class MyCustomStickyListAdapter extends BaseAdapter implements StickyListHeadersAdapter, Filterable
{ ... }
  • 设置背景色方法:
private void setViewCompositeBackgroundColor(View convertView, ColorDrawable[] colors){
        LayerDrawable background = new LayerDrawable(colors);

        for(int i = 0; i < colors.length; i++)
        {
            background.setLayerInsetLeft(i, (i * windowWidth) / colors.length);
            background.setLayerInsetRight(i, windowWidth - (((i + 1) * windowWidth) / colors.length));

        }

        convertView.setBackground(background);
    }
  • ColorDrawable类变量初始化:
colorDefault = new ColorDrawable(ContextCompat.getColor(context, R.color.colorDefault));
  • 颜色定义XML:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="green">@color/Green</color>
    <color name="red">@color/red</color>
    <color name="pink">@android:color/pink</color>
    <color name="default">@color/White</color>
</resources>

但遇到问题:当传入包含相同Color ID的ColorDrawable数组(比如两个默认白色)时,左侧同色层会偏移到最右侧同色层的位置,显示效果不符合预期。例如前两个条件为默认白色、第三个为粉色时,实际显示左侧是列表默认灰色,仅右侧显示深色白色和粉色,预期应该是左侧两段白色、右侧一段粉色。


解决方案

原因分析

问题核心是重复使用同一个ColorDrawable实例:LayerDrawable会将相同的Drawable实例视为同一个图层,后续设置的inset参数会覆盖之前的配置,导致前面的同色图层偏移到最后一个同色图层的位置。

修复步骤

  1. 避免复用ColorDrawable实例
    不要直接传递重复的colorDefault实例,每次需要默认色时,新建一个ColorDrawable对象,确保每个图层都是独立实例。

示例修改:

// 错误写法:重复使用同一个实例
// ColorDrawable[] colors = {colorDefault, colorDefault, pinkDrawable};

// 正确写法:每次新建独立实例
ColorDrawable[] colors = {
    new ColorDrawable(ContextCompat.getColor(context, R.color.colorDefault)),
    new ColorDrawable(ContextCompat.getColor(context, R.color.colorDefault)),
    new ColorDrawable(ContextCompat.getColor(context, R.color.pink))
};
  1. 封装工具方法简化调用
    可以封装一个获取独立ColorDrawable的工具方法,减少重复代码:
private ColorDrawable getColorDrawable(int colorResId) {
    return new ColorDrawable(ContextCompat.getColor(context, colorResId));
}

// 调用示例
ColorDrawable[] colors = {
    getColorDrawable(R.color.colorDefault),
    getColorDrawable(R.color.colorDefault),
    getColorDrawable(R.color.pink)
};
  1. 可选:带实例复制的缓存优化
    如果担心频繁创建实例的性能问题,可以维护颜色缓存,但返回时必须返回实例副本,避免复用:
private HashMap<Integer, ColorDrawable> colorCache = new HashMap<>();

private ColorDrawable getColorDrawable(int colorResId) {
    int colorValue = ContextCompat.getColor(context, colorResId);
    if (!colorCache.containsKey(colorValue)) {
        colorCache.put(colorValue, new ColorDrawable(colorValue));
    }
    // 返回副本,保证每个图层实例独立
    return new ColorDrawable(colorValue);
}

修改后,每个图层都是独立的ColorDrawable实例,LayerDrawable会正确应用每个图层的inset设置,实现预期的分段背景效果。


内容的提问来源于stack exchange,提问作者AMPIZBUD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:14:50