Android加阴影 -(一键无脑引入,无兼容问题)
程序员文章站
2024-02-29 12:18:10
...
老规矩,无图言 × ,先上图
好像看不清,换个颜色再来一张吧,再加宽点
这颜色好丑哈哈哈哈哈哈,这是从黑到白色,你们用的时候一定要用有透明度的色值啊哈哈哈
接下来上代码!
/**
* 示例用法 这里涉及到的一个 dip2px 方法就是把 8dp 转成对应的像素值而已
*/
public static View setViewBoundShadow(View view) {
int shadowSize = dip2px(view.getContext(), 8);
int startColor = Color.parseColor("#001795FF");
int endColor = Color.parseColor("#1A1795FF");
return setViewBoundShadow(view, shadowSize, startColor, endColor);
}
/**
* @param view 需要设置阴影的 view
* @param shadowSize 阴影宽度
* @param startColor 贴近 view 一侧的色值
* @param endColor 远离 view 一侧的色值
* @return 失败 null ; 成功则返回阴影 所属的 parentView,可通过设置 visibility 控制是否显示
* @author lzd
* 为 view 设置阴影
* #Note 使用此方法后 viewTree的父容器 的 ClipChildren 属性会置true
* 这里可能会导致某些父布局里的元素超出容器,后期需要优化
*/
public static View setViewBoundShadow(View view, int shadowSize, int startColor, int endColor) {
if (view == null || shadowSize < 0) {
return null;
}
ViewGroup parentView = new ConstraintLayout(view.getContext());
if (view instanceof ViewGroup) {
parentView.setLayoutParams(new ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
((ViewGroup) view).addView(parentView);
} else {
parentView.setLayoutParams(new ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
setViewFamilyClipChildren(parentView, false);
class childValue {
int width;
int height;
int horPos;
int verPos;
GradientDrawable.Orientation orientation;
public childValue(int width, int height, int horPos, int verPos, GradientDrawable.Orientation orientation) {
this.width = width;
this.height = height;
this.horPos = horPos;
this.verPos = verPos;
this.orientation = orientation;
}
}
childValue[] childValues = new childValue[]{
new childValue(shadowSize, ViewGroup.LayoutParams.MATCH_PARENT, 1, 0
, GradientDrawable.Orientation.RIGHT_LEFT),
new childValue(shadowSize, ViewGroup.LayoutParams.MATCH_PARENT, -1, 0
, GradientDrawable.Orientation.LEFT_RIGHT),
new childValue(ViewGroup.LayoutParams.MATCH_PARENT, shadowSize, 0, -1
, GradientDrawable.Orientation.TOP_BOTTOM),
new childValue(ViewGroup.LayoutParams.MATCH_PARENT, shadowSize, 0, 1
, GradientDrawable.Orientation.BOTTOM_TOP),
new childValue(shadowSize, shadowSize, 1, 1, null),
new childValue(shadowSize, shadowSize, -1, 1, null),
new childValue(shadowSize, shadowSize, -1, -1, null),
new childValue(shadowSize, shadowSize, 1, -1, null),
};
for (childValue childValue : childValues) {
ConstraintLayout.LayoutParams childParams
= new ConstraintLayout.LayoutParams(childValue.width, childValue.height);
View child = new View(view.getContext());
// 位置
if (childValue.horPos == 1) {
childParams.startToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
} else if (childValue.horPos == -1) {
childParams.endToStart = ConstraintLayout.LayoutParams.PARENT_ID;
}
if (childValue.verPos == 1) {
childParams.topToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
} else if (childValue.verPos == -1) {
childParams.bottomToTop = ConstraintLayout.LayoutParams.PARENT_ID;
}
// 背景图
GradientDrawable childBg = new GradientDrawable();
if (childValue.orientation != null) {
childBg.setColors(new int[]{startColor, endColor});
childBg.setOrientation(childValue.orientation);
} else {
childBg.setColors(new int[]{endColor, startColor});
childBg.setGradientRadius(shadowSize);
childBg.setGradientCenter(Math.max(0, -childValue.horPos)
, Math.max(0, -childValue.verPos));
childBg.setGradientType(GradientDrawable.RADIAL_GRADIENT);
childBg.setCornerRadii(new float[]{
childValue.horPos + childValue.verPos == -2 ? shadowSize : 0,
childValue.horPos + childValue.verPos == -2 ? shadowSize : 0,
childValue.horPos == 1 && childValue.verPos == -1 ? shadowSize : 0,
childValue.horPos == 1 && childValue.verPos == -1 ? shadowSize : 0,
childValue.horPos + childValue.verPos == 2 ? shadowSize : 0,
childValue.horPos + childValue.verPos == 2 ? shadowSize : 0,
childValue.horPos == -1 && childValue.verPos == 1 ? shadowSize : 0,
childValue.horPos == -1 && childValue.verPos == 1 ? shadowSize : 0
});
}
child.setBackground(childBg);
child.setLayoutParams(childParams);
parentView.addView(child);
}
parentView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
setViewFamilyClipChildren(parentView, false);
});
return parentView;
}
public static void setViewFamilyClipChildren(ViewGroup view, boolean clipChildren) {
if (view == null) {
return;
}
view.setClipChildren(clipChildren);
ViewParent rooter = view.getParent();
while (rooter instanceof ViewGroup) {
((ViewGroup) rooter).setClipChildren(false);
rooter = rooter.getParent();
}
}
导致就这样吧,好累了上了一天班,关于注释里提到的 “可能会导致某些父布局里的元素超出容器” 的问题,如果各位有什么解决方案的话,请务必留言交流!!!
上一篇: 什么是栈?
下一篇: C++ Primer 第八章学习笔记