Evil Mouth's Blog

AndroidX TabLayout点击效果兼容问题

October 24, 2018

近期升级了一波AndroidX,发现原先取消掉的TabLayout点击阴影效果又出现了,以为是改了主题遍翻了翻git改动,发现并没有可疑的修改导致,最后在源码里面发现真凶!

0x00 support-27.1.1

此前TabLayout的点击效果是通过设置app:tabBackground="@android:color/transparent"进行取消

0x01 support-28.0.0

升级到 28.0.0 后TabLayout加多了一个属性app:tabRippleColor,查看源码可知

this.tabBackgroundResId = a.getResourceId(styleable.TabLayout_tabBackground, 0);
this.tabRippleColorStateList = MaterialResources.getColorStateList(context, a, styleable.TabLayout_tabRippleColor);

private void updateBackgroundDrawable(Context context) {
    if (TabLayout.this.tabBackgroundResId != 0) {
        this.baseBackgroundDrawable = AppCompatResources.getDrawable(context, TabLayout.this.tabBackgroundResId);
        if (this.baseBackgroundDrawable != null && this.baseBackgroundDrawable.isStateful()) {
            this.baseBackgroundDrawable.setState(this.getDrawableState());
        }
    } else {
        this.baseBackgroundDrawable = null;
    }
    Drawable contentDrawable = new GradientDrawable();
    ((GradientDrawable)contentDrawable).setColor(0);
    Object background;
    if (TabLayout.this.tabRippleColorStateList != null) {
        GradientDrawable maskDrawable = new GradientDrawable();
        maskDrawable.setCornerRadius(1.0E-5F);
        maskDrawable.setColor(-1);
        ColorStateList rippleColor = RippleUtils.convertToRippleDrawableColor(TabLayout.this.tabRippleColorStateList);
        if (VERSION.SDK_INT >= 21) {
            background = new RippleDrawable(rippleColor, TabLayout.this.unboundedRipple ? null : contentDrawable, TabLayout.this.unboundedRipple ? null : maskDrawable);
        } else {
            Drawable rippleDrawable = DrawableCompat.wrap(maskDrawable);
            DrawableCompat.setTintList(rippleDrawable, rippleColor);
            background = new LayerDrawable(new Drawable[]{contentDrawable, rippleDrawable});
        }
    } else {
        background = contentDrawable;
    }
    ViewCompat.setBackground(this, (Drawable)background);
    TabLayout.this.invalidate();
}

TabViewbackground根据tabRippleColorStateList去包装从而实现点击效果,只要让tabRippleColorStateList = null即可取消,其中的unboundedRipple是设置水波纹效果的开关

0x03 兼容与结论

  • 通过设置app:tabRippleColor="@android:color/transparent"或者TabLayout.setTabRippleColor(null);即可取消点击阴影效果
  • 由于AndroidX基于28.0.0,所以出现兼容问题

— Evil Mouth