MD3——SearchView自定义背景

MD3 – SearchView

介绍

官方描述:

SearchView组件提供了一个全屏查找视图的完成,该视图可用于显现返回导航、查找提示和文本、菜单项以及查找建议和成果。它还带有一个明晰的文本按钮,根据用户是否输入文本显现和躲藏。

作用如下:

MD3——SearchView自定义背景

可用特点如下:

Element Attribute Related method(s) Default value
Search text appearance android:textAppearance setTextAppearance getTextAppearance @style/TextAppearance.Material3.SearchBar
Search text android:text setText getText null
Search hint android:hint setHint getHint null
Color app:backgroundTint ?attr/colorSurfaceContainerHigh
Flag for navigation icon app:hideNavigationIcon true
Flag forDrawerArrowDrawable app:useDrawerArrowDrawable false
Flag for soft keyboard app:autoShowKeyboard true

需求

需求修正这个背景色,并且是动态修正。尝试过修正app:backgroundTint ,可是不起作用,所以在SearchView里翻呀翻,最后也算是找到了处理办法。

剖析SearchVIew

能够看到SearchView里有一个backgroundView,不难知道这个就是咱们需求修正色彩的View

// SearchView
...
final View backgroundView;
...
// 修正色彩的地方
private void setUpBackgroundViewElevationOverlay(float elevation) {
    if (elevationOverlayProvider == null || backgroundView == null) {
        return;
    }
    int backgroundColor =
            elevationOverlayProvider.compositeOverlayWithThemeSurfaceColorIfNeeded(elevation);
    backgroundView.setBackgroundColor(backgroundColor);
}

找到地方就好办了,直接复制一个SearchView,然后改成自己想要的色彩即可

MD3——SearchView自定义背景

留意:姓名不要和本来相同,会冲突;然后SearchView里有一个searchViewAnimationHelper参数是SearchView,所以咱们也需求复制一份把里面的SearchView换成CustomSearchView

看下作用:

MD3——SearchView自定义背景

改进

虽然成功改了色彩,可是和本来作用不相同呀,本来的色彩是基于colorPrimary的,并且也不是这样的纯色,对比下之前的:

MD3——SearchView自定义背景
能够看到似乎是colorPrimary的色彩叠加了白色,那咱们就继续看SearchView,能够知道色彩处理肯定是在这行代码:

int backgroundColor =
            elevationOverlayProvider.compositeOverlayWithThemeSurfaceColorIfNeeded(elevation);

那就继续看这个办法的完成:

// ElevationOverlayProvider
...
// 看到这个colorSurface就知道他的色彩是白/黑
// 根据主题改换,证实了之前的猜想
  @ColorInt
  public int compositeOverlayWithThemeSurfaceColorIfNeeded(float elevation) {
    return compositeOverlayIfNeeded(colorSurface, elevation);
  }
  ...
@ColorInt
public int compositeOverlayIfNeeded(@ColorInt int backgroundColor, float elevation) {
    if (elevationOverlayEnabled && isThemeSurfaceColor(backgroundColor)) {
        return compositeOverlay(backgroundColor, elevation);
    } else {
        return backgroundColor;
    }
}
...
// 要害代码完成
@ColorInt
public int compositeOverlay(@ColorInt int backgroundColor, float elevation) {
    float overlayAlphaFraction = calculateOverlayAlphaFraction(elevation);
    int backgroundAlpha = Color.alpha(backgroundColor);
    int backgroundColorOpaque = ColorUtils.setAlphaComponent(backgroundColor, 255);
    int overlayColorOpaque =
        MaterialColors.layer(backgroundColorOpaque, elevationOverlayColor, overlayAlphaFraction);
    if (overlayAlphaFraction > 0 && elevationOverlayAccentColor != Color.TRANSPARENT) {
        int overlayAccentColor =
            ColorUtils.setAlphaComponent(elevationOverlayAccentColor, OVERLAY_ACCENT_COLOR_ALPHA);
        overlayColorOpaque = MaterialColors.layer(overlayColorOpaque, overlayAccentColor);
    }
    return ColorUtils.setAlphaComponent(overlayColorOpaque, backgroundAlpha);
}

这儿的elevationOverlayColorelevationOverlayAccentColor默许是和colorPrimary是同色,到这儿就现已知道怎么修正色彩了,具体内部做了什么计算就不管了,在咱们的SearchView里增加一个修正背景色的办法,把上面compositeOverlay办法的要害完成复制过来:

public void setBackgroundViewColor(@ColorInt int color) {
    int backgroundColor = MaterialColors.getColor(getContext(), R.attr.colorSurface, Color.WHITE);
    float elevation = getOverlayElevation();
    float overlayAlphaFraction = elevationOverlayProvider.calculateOverlayAlphaFraction(elevation);
    int backgroundAlpha = Color.alpha(backgroundColor);
    int backgroundColorOpaque = ColorUtils.setAlphaComponent(backgroundColor, 255);
    int overlayColorOpaque =
            MaterialColors.layer(backgroundColorOpaque, color, overlayAlphaFraction);
    if (overlayAlphaFraction > 0 && color != Color.TRANSPARENT) {
        int overlayAccentColor =
                ColorUtils.setAlphaComponent(color, (int) Math.round(0.02 * 255));
        overlayColorOpaque = MaterialColors.layer(overlayColorOpaque, overlayAccentColor);
    }
    int overlayColor = ColorUtils.setAlphaComponent(overlayColorOpaque, backgroundAlpha);
    backgroundView.setBackgroundColor(overlayColor);
}
// 调用(kotlin)
binding.colorSearchView.setBackgroundViewColor(themeColor)

这儿要留意: elevationOverlayColorelevationOverlayAccentColor替换成咱们需求设置的色彩(color),原因前面剖析过了哈。如果需求让色彩更深一点,能够修正elevation的值,看看作用吧:

MD3——SearchView自定义背景

补充:怎么需求设置背景图片也是能够的

backgroundView.setBackgroundResource(int resid)

总结

为了改这个,网上一顿查,愣是没找到处理办法,还好处理了,不然我可能直接强行改成是非了