//第一部分
package com.mobile.common_library.custom_vIEw;import androID.content.Context;import androID.content.res.colorStateList;import androID.content.res.TypedArray;import androID.graphics.Bitmap;import androID.graphics.Canvas;import androID.graphics.color;import androID.graphics.linearGradIEnt;import androID.graphics.Paint;import androID.graphics.Path;import androID.graphics.RectF;import androID.graphics.Shader;import androID.graphics.drawable.BitmapDrawable;import androID.graphics.drawable.colorDrawable;import androID.graphics.drawable.Drawable;import androID.graphics.drawable.rippledrawable;import androID.graphics.drawable.ShapeDrawable;import androID.graphics.drawable.shapes.RoundRectShape;import androID.os.Build;import androID.text.TextUtils;import androID.util.AttributeSet;import androID.vIEw.MotionEvent;import androID.vIEw.VIEw;import androID.Widget.linearLayout;import androID.Widget.TextVIEw;import com.mobile.common_library.R;import com.mobile.common_library.manager.GlIDeRoundManager;import androIDx.annotation.Nullable;import androIDx.annotation.RequiresAPI;public class ShadowlinearLayout extends linearLayout { private Drawable clickAbleFalseDrawable; private int clickAbleFalsecolor = -101; private Drawable layoutBackground; private Drawable layoutBackground_true; private VIEw firstVIEw; private int mBackGroundcolor; private int mBackGroundcolor_true = -101; private int mShadowcolor; private float mShadowlimit; private float mCornerRadius; private float mDx; private float mDy; private boolean leftShow; private boolean rightShow; private boolean topShow; private boolean bottomShow; private Paint shadowPaint; private Paint paint; private int leftpadding; private int toppadding; private int rightpadding; private int bottompadding; //阴影布局子空间区域 private RectF rectf = new RectF(); //ShadowlinearLayout的样式,是只需要pressed还是selected。默认是pressed. private int selectorType = 1; private boolean isShowShadow = true; private boolean isSym; //增加各个圆角的属性 private float mCornerRadius_lefttop; private float mCornerRadius_righttop; private float mCornerRadius_leftBottom; private float mCornerRadius_rightBottom; //边框画笔 private Paint paint_stroke; private float stroke_with; private int stroke_color; private int stroke_color_true; private boolean isClickable; //关于控件填充渐变色 private int startcolor; private int centercolor; private int endcolor; private int angle; //在普遍情况,在点击或选中按钮时,很可能伴随着textVIEw的字体颜色变化 private int mTextVIEwResID = -1; private TextVIEw mTextVIEw; private int textcolor; private int textcolor_true; private String text; private String text_true; public ShadowlinearLayout(Context context) { this(context, null); } public ShadowlinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShadowlinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initVIEw(context, attrs); } public voID setClickable(boolean clickable) { super.setClickable(clickable); this.isClickable = clickable; changeSwitchClickable(); if (isClickable) { super.setonClickListener(onClickListener); } if (paint != null) { if (startcolor != -101 && endcolor != -101) { gradIEnt(paint); } } } //解决xml设置clickable = false时。代码设置true时,点击事件无效的BUG private OnClickListener onClickListener; @OverrIDe public voID setonClickListener(@Nullable OnClickListener l) { this.onClickListener = l; if (isClickable) { super.setonClickListener(l); } } public voID changeSwitchClickable() { //不可点击的状态只在press mode的模式下生效 if (selectorType == 1 && firstVIEw != null) { //press mode if (!isClickable) { //不可点击的状态。 if (clickAbleFalsecolor != -101) { //说明设置了颜色 if (layoutBackground != null) { //说明此时是设置了图片的模式 firstVIEw.getBackground().setAlpha(0); } paint.setcolor(clickAbleFalsecolor); postInvalIDate(); } else if (clickAbleFalseDrawable != null) { //说明设置了背景图 setmBackGround(clickAbleFalseDrawable); paint.setcolor(color.parsecolor("#00000000")); postInvalIDate(); } } else { //可点击的状态 if (layoutBackground != null) { setmBackGround(layoutBackground); } else { if (firstVIEw.getBackground() != null) { firstVIEw.getBackground().setAlpha(0); } } paint.setcolor(mBackGroundcolor); postInvalIDate(); } } } //增加selector样式 @OverrIDe public voID setSelected(boolean selected) { super.setSelected(selected); if (getWIDth() != 0) { if (selectorType == 2) { if (selected) { if (mBackGroundcolor_true != -101) { paint.setcolor(mBackGroundcolor_true); } paint.setShader(null); if (stroke_color_true != -101) { paint_stroke.setcolor(stroke_color_true); } if (layoutBackground_true != null) { setmBackGround(layoutBackground_true); } if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor_true); if (!TextUtils.isEmpty(text_true)) { mTextVIEw.setText(text_true); } } } else { paint.setcolor(mBackGroundcolor); if (startcolor != -101) { gradIEnt(paint); } if (stroke_color != -101) { paint_stroke.setcolor(stroke_color); } if (layoutBackground != null) { setmBackGround(layoutBackground); } if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor); if (!TextUtils.isEmpty(text)) { mTextVIEw.setText(text); } } } postInvalIDate(); } } else { addOnLayoutchangelistener(new OnLayoutchangelistener() { @OverrIDe public voID onLayoutChange(VIEw v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldRight, int oldBottom) { removeOnLayoutchangelistener(this); setSelected(isSelected()); } }); } } //是否隐藏阴影 public voID setShadowHIDden(boolean isShowShadow) { this.isShowShadow = !isShowShadow; if (getWIDth() != 0 && getHeight() != 0) { setBackgroundCompat(getWIDth(), getHeight()); } } //设置x轴偏移量 public voID setShadowOffsetX(float mDx) { if (isShowShadow) { if (Math.abs(mDx) > mShadowlimit) { if (mDx > 0) { this.mDx = mShadowlimit; } else { this.mDx = -mShadowlimit; } } else { this.mDx = mDx; } setpadding(); } } //动态设置y轴偏移量 public voID setShadowOffsetY(float mDy) { if (isShowShadow) { if (Math.abs(mDy) > mShadowlimit) { if (mDy > 0) { this.mDy = mShadowlimit; } else { this.mDy = -mShadowlimit; } } else { this.mDy = mDy; } setpadding(); } } public float getCornerRadius() { return mCornerRadius; } //动态设置 圆角属性 public voID setCornerRadius(int mCornerRadius) { this.mCornerRadius = mCornerRadius; if (getWIDth() != 0 && getHeight() != 0) { setBackgroundCompat(getWIDth(), getHeight()); } } public float getShadowlimit() { return mShadowlimit; } //动态设置阴影扩散区域 public voID setShadowlimit(int mShadowlimit) { if (isShowShadow) { int dip5 = (int) getContext().getResources().getDimension(R.dimen.dp_5); if (mShadowlimit >= dip5) { this.mShadowlimit = mShadowlimit; } else { this.mShadowlimit = dip5; } setpadding(); } } //动态设置阴影颜色值 public voID setShadowcolor(int mShadowcolor) { this.mShadowcolor = mShadowcolor; if (getWIDth() != 0 && getHeight() != 0) { setBackgroundCompat(getWIDth(), getHeight()); } } public voID setSpecialCorner(int lefttop, int righttop, int leftBottom, int rightBottom) { mCornerRadius_lefttop = lefttop; mCornerRadius_righttop = righttop; mCornerRadius_leftBottom = leftBottom; mCornerRadius_rightBottom = rightBottom; if (getWIDth() != 0 && getHeight() != 0) { setBackgroundCompat(getWIDth(), getHeight()); } } //是否隐藏阴影的上边部分 public voID setShadowHIDdentop(boolean topShow) { this.topShow = !topShow; setpadding(); } public voID setShadowHIDdenBottom(boolean bottomShow) { this.bottomShow = !bottomShow; setpadding(); } public voID setShadowHIDdenRight(boolean rightShow) { this.rightShow = !rightShow; setpadding(); } public voID setShadowHIDdenleft(boolean leftShow) { this.leftShow = !leftShow; setpadding(); } public voID setLayoutBackground(int color) { if (layoutBackground_true != null) { throw new UnsupportedOperationException("使用了ShadowlinearLayout_hl_layoutBackground_true属性,要与ShadowlinearLayout_hl_layoutBackground属性统一为颜色"); } mBackGroundcolor = color; if (selectorType == 2) { //select模式 if (!this.isSelected()) { paint.setcolor(mBackGroundcolor); } } else { paint.setcolor(mBackGroundcolor); } postInvalIDate(); } public voID setLayoutBackgroundTrue(int color) { if (layoutBackground != null) { throw new UnsupportedOperationException("使用了ShadowlinearLayout_hl_layoutBackground属性,要与ShadowlinearLayout_hl_layoutBackground_true属性统一为颜色"); } mBackGroundcolor_true = color; if (selectorType == 2) { //select模式 if (this.isSelected()) { paint.setcolor(mBackGroundcolor_true); } } postInvalIDate(); } public voID setstrokecolor(int color) { stroke_color = color; if (selectorType == 2) { //select模式 if (!this.isSelected()) { paint_stroke.setcolor(stroke_color); } } else { paint_stroke.setcolor(stroke_color); } postInvalIDate(); } public voID setstrokecolorTrue(int color) { stroke_color_true = color; if (selectorType == 2) { //select模式 if (this.isSelected()) { paint_stroke.setcolor(stroke_color_true); } } postInvalIDate(); } public voID setstrokeWIDth(int stokeWIDth) { this.stroke_with = stokeWIDth; if (stroke_with > dip2px(7)) { stroke_with = dip2px(5); } paint_stroke.setstrokeWIDth(stroke_with); postInvalIDate(); } @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe protected voID onFinishInflate() { super.onFinishInflate(); if (mTextVIEwResID != -1) { mTextVIEw = findVIEwByID(mTextVIEwResID); if (mTextVIEw == null) { throw new NullPointerException("ShadowlinearLayout找不到hl_bindTextVIEw,请确保绑定的资源ID在ShadowlinearLayout内"); } else { if (textcolor == -101) { textcolor = mTextVIEw.getCurrentTextcolor(); } if (textcolor_true == -101) { textcolor_true = mTextVIEw.getCurrentTextcolor(); } mTextVIEw.setTextcolor(textcolor); if (!TextUtils.isEmpty(text)) { mTextVIEw.setText(text); } } } firstVIEw = getChildAt(0); if (firstVIEw == null) { firstVIEw = ShadowlinearLayout.this; //当子VIEw都没有的时候。默认不使用阴影 isShowShadow = false; } if (firstVIEw != null) { //selector样式不受clickable的影响 if (selectorType == 2) { //if (this.isSelected()) { //这个方法内已经判断了是否为空 // setmBackGround(layoutBackground_true); //} else { // setmBackGround(layoutBackground); // } } else { if (isClickable) { setmBackGround(layoutBackground); } else { setmBackGround(clickAbleFalseDrawable); if (clickAbleFalsecolor != -101) { paint.setcolor(clickAbleFalsecolor); } } } } } @OverrIDe protected voID onSizeChanged(int w, int h, int olDW, int oldh) { super.onSizeChanged(w, h, olDW, oldh); if (w > 0 && h > 0) { setBackgroundCompat(w, h); if (startcolor != -101) { gradIEnt(paint); } } } private voID initVIEw(Context context, AttributeSet attrs) { initAttributes(attrs); shadowPaint = new Paint(); shadowPaint.setAntiAlias(true); shadowPaint.setStyle(Paint.Style.FILL); paint_stroke = new Paint(); paint_stroke.setAntiAlias(true); paint_stroke.setStyle(Paint.Style.stroke); paint_stroke.setstrokeWIDth(stroke_with); if (stroke_color != -101) { paint_stroke.setcolor(stroke_color); } //矩形画笔 paint = new Paint(Paint.ANTI_AliAS_FLAG); paint.setStyle(Paint.Style.FILL); //打个标记 paint.setcolor(mBackGroundcolor); setpadding(); } //将画笔附上 渐变色 public voID gradIEnt(Paint paint) { if (!isClickable) { paint.setShader(null); return; } //左上 x,y leftpadding, toppadding, //右下 x,y getWIDth() - rightpadding, getHeight() - bottompadding int[] colors; if (centercolor == -101) { colors = new int[]{startcolor, endcolor}; } else { colors = new int[]{startcolor, centercolor, endcolor}; } if (angle < 0) { int trueAngle = angle % 360; angle = trueAngle + 360; } //当设置的角度大于0的时候 //这个要算出每隔45度 int trueAngle = angle % 360; int angleFlag = trueAngle / 45; linearGradIEnt linearGradIEnt; switch (angleFlag) { case 0://0° linearGradIEnt = new linearGradIEnt(leftpadding, toppadding, getWIDth() - rightpadding, toppadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 1://45° linearGradIEnt = new linearGradIEnt(leftpadding, getHeight() - bottompadding, getWIDth() - rightpadding, toppadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 2://90° int x_ = (getWIDth() - rightpadding - leftpadding) / 2 + leftpadding; linearGradIEnt = new linearGradIEnt(x_, getHeight() - bottompadding, x_, toppadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 3://135° linearGradIEnt = new linearGradIEnt(getWIDth() - rightpadding, getHeight() - bottompadding, leftpadding, toppadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 4://180° linearGradIEnt = new linearGradIEnt(getWIDth() - rightpadding, toppadding, leftpadding, toppadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 5://225° linearGradIEnt = new linearGradIEnt(getWIDth() - rightpadding, toppadding, leftpadding, getHeight() - bottompadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 6://270° int x = (getWIDth() - rightpadding - leftpadding) / 2 + leftpadding; linearGradIEnt = new linearGradIEnt(x, toppadding, x, getHeight() - bottompadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; case 7://315° linearGradIEnt = new linearGradIEnt(leftpadding, toppadding, getWIDth() - rightpadding, getHeight() - bottompadding, colors, null, Shader.TileMode.CLAMP); paint.setShader(linearGradIEnt); break; } } public int dip2px(float dipValue) { float scale = getContext().getResources().getdisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } public voID setpadding() { if (isShowShadow && mShadowlimit > 0) { //控件区域是否对称,默认是对称。不对称的话,那么控件区域随着阴影区域走 if (isSym) { int xpadding = (int) (mShadowlimit + Math.abs(mDx)); int ypadding = (int) (mShadowlimit + Math.abs(mDy)); if (leftShow) { leftpadding = xpadding; } else { leftpadding = 0; } if (topShow) { toppadding = ypadding; } else { toppadding = 0; } if (rightShow) { rightpadding = xpadding; } else { rightpadding = 0; } if (bottomShow) { bottompadding = ypadding; } else { bottompadding = 0; } } else { if (Math.abs(mDy) > mShadowlimit) { if (mDy > 0) { mDy = mShadowlimit; } else { mDy = 0 - mShadowlimit; } } if (Math.abs(mDx) > mShadowlimit) { if (mDx > 0) { mDx = mShadowlimit; } else { mDx = 0 - mShadowlimit; } } if (topShow) { toppadding = (int) (mShadowlimit - mDy); } else { toppadding = 0; } if (bottomShow) { bottompadding = (int) (mShadowlimit + mDy); } else { bottompadding = 0; } if (rightShow) { rightpadding = (int) (mShadowlimit - mDx); } else { rightpadding = 0; } if (leftShow) { leftpadding = (int) (mShadowlimit + mDx); } else { leftpadding = 0; } } setpadding(leftpadding, toppadding, rightpadding, bottompadding);// setpadding(dip2px(leftpadding), dip2px(toppadding),// dip2px(rightpadding), dip2px(bottompadding)); } } @SuppressWarnings("deprecation") private voID setBackgroundCompat(int w, int h) { if (isShowShadow) { //判断传入的颜色值是否有透明度 isAddAlpha(mShadowcolor); Bitmap bitmap = createShadowBitmap(w, h, mCornerRadius, mShadowlimit, mDx, mDy, mShadowcolor, color.transparent); BitmapDrawable drawable = new BitmapDrawable(bitmap); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { setBackgroundDrawable(drawable); } else { setBackground(drawable); } } else { if (getChildAt(0) == null) { if (layoutBackground != null) { firstVIEw = ShadowlinearLayout.this; if (isClickable) { setmBackGround(layoutBackground); } else { changeSwitchClickable(); } } else { //解决不执行onDraw方法的BUG就是给其设置一个透明色 this.setBackgroundcolor(color.parsecolor("#00000000")); } } else { this.setBackgroundcolor(color.parsecolor("#00000000")); } } } private voID initAttributes(AttributeSet attrs) { TypedArray attr = getContext().obtainStyledAttributes(attrs, R.styleable.ShadowLayout); if (attr == null) { return; } try { //默认是显示 isShowShadow = !attr.getBoolean(R.styleable.ShadowLayout_hl_shadowHIDden, false); leftShow = !attr.getBoolean(R.styleable.ShadowLayout_hl_shadowHIDdenleft, false); rightShow = !attr.getBoolean(R.styleable.ShadowLayout_hl_shadowHIDdenRight, false); bottomShow = !attr.getBoolean(R.styleable.ShadowLayout_hl_shadowHIDdenBottom, false); topShow = !attr.getBoolean(R.styleable.ShadowLayout_hl_shadowHIDdentop, false); mCornerRadius = attr.getDimension(R.styleable.ShadowLayout_hl_cornerRadius, getResources().getDimension(R.dimen.dp_0)); mCornerRadius_lefttop = attr.getDimension(R.styleable.ShadowLayout_hl_cornerRadius_lefttop, -1); mCornerRadius_leftBottom = attr.getDimension(R.styleable.ShadowLayout_hl_cornerRadius_leftBottom, -1); mCornerRadius_righttop = attr.getDimension(R.styleable.ShadowLayout_hl_cornerRadius_righttop, -1); mCornerRadius_rightBottom = attr.getDimension(R.styleable.ShadowLayout_hl_cornerRadius_rightBottom, -1); //默认扩散区域宽度 mShadowlimit = attr.getDimension(R.styleable.ShadowLayout_hl_shadowlimit, 0); if (mShadowlimit == 0) { //如果阴影没有设置阴影扩散区域,那么默认隐藏阴影 isShowShadow = false; } else { int dip5 = (int) getContext().getResources().getDimension(R.dimen.dp_5); if (mShadowlimit < dip5) { mShadowlimit = dip5; } } //x轴偏移量 mDx = attr.getDimension(R.styleable.ShadowLayout_hl_shadowOffsetX, 0); //y轴偏移量 mDy = attr.getDimension(R.styleable.ShadowLayout_hl_shadowOffsetY, 0); mShadowcolor = attr.getcolor(R.styleable.ShadowLayout_hl_shadowcolor, getResources().getcolor(R.color.default_shadow_color)); selectorType = attr.getInt(R.styleable.ShadowLayout_hl_shapeMode, 1); isSym = attr.getBoolean(R.styleable.ShadowLayout_hl_shadowSymmetry, true); //背景颜色的点击(默认颜色为白色) mBackGroundcolor = getResources().getcolor(R.color.default_shadowback_color); Drawable background = attr.getDrawable(R.styleable.ShadowLayout_hl_layoutBackground); if (background != null) { if (background instanceof colorDrawable) { colorDrawable colorDrawable = (colorDrawable) background; mBackGroundcolor = colorDrawable.getcolor(); } else { layoutBackground = background; } } Drawable trueBackground = attr.getDrawable(R.styleable.ShadowLayout_hl_layoutBackground_true); if (trueBackground != null) { if (trueBackground instanceof colorDrawable) { colorDrawable colorDrawableTrue = (colorDrawable) trueBackground; mBackGroundcolor_true = colorDrawableTrue.getcolor(); } else { layoutBackground_true = trueBackground; } } if (mBackGroundcolor_true != -101 && layoutBackground != null) { throw new UnsupportedOperationException("使用了ShadowLayout_hl_layoutBackground_true属性,必须先设置ShadowLayout_hl_layoutBackground属性。且设置颜色时,必须保持都为颜色"); } if (layoutBackground == null && layoutBackground_true != null) { throw new UnsupportedOperationException("使用了ShadowLayout_hl_layoutBackground_true属性,必须先设置ShadowLayout_hl_layoutBackground属性。且设置图片时,必须保持都为图片"); } //边框颜色的点击 stroke_color = attr.getcolor(R.styleable.ShadowLayout_hl_strokecolor, -101); stroke_color_true = attr.getcolor(R.styleable.ShadowLayout_hl_strokecolor_true, -101); if (stroke_color == -101 && stroke_color_true != -101) { throw new UnsupportedOperationException("使用了ShadowLayout_hl_strokecolor_true属性,必须先设置ShadowLayout_hl_strokecolor属性"); } stroke_with = attr.getDimension(R.styleable.ShadowLayout_hl_strokeWith, dip2px(1)); //规定边框长度最大不错过7dp if (stroke_with > dip2px(7)) { stroke_with = dip2px(5); } Drawable clickAbleFalseBackground = attr.getDrawable(R.styleable.ShadowLayout_hl_layoutBackground_clickFalse); if (clickAbleFalseBackground != null) { if (clickAbleFalseBackground instanceof colorDrawable) { colorDrawable colorDrawableClickableFalse = (colorDrawable) clickAbleFalseBackground; clickAbleFalsecolor = colorDrawableClickableFalse.getcolor(); } else { clickAbleFalseDrawable = clickAbleFalseBackground; } } startcolor = attr.getcolor(R.styleable.ShadowLayout_hl_startcolor, -101); centercolor = attr.getcolor(R.styleable.ShadowLayout_hl_centercolor, -101); endcolor = attr.getcolor(R.styleable.ShadowLayout_hl_endcolor, -101); if (startcolor != -101) { //说明设置了渐变色的起始色 if (endcolor == -101) { throw new UnsupportedOperationException("使用了ShadowLayout_hl_startcolor渐变起始色,必须搭配终止色ShadowLayout_hl_endcolor"); } } angle = attr.getInt(R.styleable.ShadowLayout_hl_angle, 0); if (angle % 45 != 0) { throw new IllegalArgumentException("linear gradIEnt requires 'angle' attribute to be a multiple of 45"); } if (selectorType == 3) { //如果是ripple的话 if (mBackGroundcolor == -101 || mBackGroundcolor_true == -101) { throw new NullPointerException("使用了ShadowLayout的水波纹,必须设置使用了ShadowLayout_hl_layoutBackground和使用了ShadowLayout_hl_layoutBackground_true属性,且为颜色值"); } //如果是设置了图片的话,那么也不支持水波纹 if (layoutBackground != null) { selectorType = 1; } } mTextVIEwResID = attr.getResourceID(R.styleable.ShadowLayout_hl_bindTextVIEw, -1); textcolor = attr.getcolor(R.styleable.ShadowLayout_hl_textcolor, -101); textcolor_true = attr.getcolor(R.styleable.ShadowLayout_hl_textcolor_true, -101); text = attr.getString(R.styleable.ShadowLayout_hl_text); text_true = attr.getString(R.styleable.ShadowLayout_hl_text_true); isClickable = attr.getBoolean(R.styleable.ShadowLayout_clickable, true); setClickable(isClickable); } finally { attr.recycle(); } } private Bitmap createShadowBitmap(int shadowWIDth, int shadowHeight, float cornerRadius, float shadowRadius, float dx, float dy, int shadowcolor, int fillcolor) { //优化阴影bitmap大小,将尺寸缩小至原来的1/4。 dx = dx / 4; dy = dy / 4; shadowWIDth = shadowWIDth / 4 == 0 ? 1 : shadowWIDth / 4; shadowHeight = shadowHeight / 4 == 0 ? 1 : shadowHeight / 4; cornerRadius = cornerRadius / 4; shadowRadius = shadowRadius / 4; Bitmap output = Bitmap.createBitmap(shadowWIDth, shadowHeight, Bitmap.Config.ARGB_4444); Canvas canvas = new Canvas(output); //这里缩小limit的是因为,setShadowLayer后会将bitmap扩散到shadowWIDth,shadowHeight //同时也要根据某边的隐藏情况去改变 float rect_left = 0; float rect_right = 0; float rect_top = 0; float rect_bottom = 0; if (leftShow) { rect_left = shadowRadius; } else {// rect_left = 0; float maxlefttop = Math.max(cornerRadius, mCornerRadius_lefttop); float maxleftBottom = Math.max(cornerRadius, mCornerRadius_leftBottom); float maxleft = Math.max(maxlefttop, maxleftBottom); rect_left = maxleft; } if (topShow) { rect_top = shadowRadius; } else {// rect_top = 0; float maxlefttop = Math.max(cornerRadius, mCornerRadius_lefttop); float maxRighttop = Math.max(cornerRadius, mCornerRadius_righttop); float maxtop = Math.max(maxlefttop, maxRighttop); rect_top = maxtop; } if (rightShow) { rect_right = shadowWIDth - shadowRadius; } else {// rect_right = shadowWIDth; float maxRighttop = Math.max(cornerRadius, mCornerRadius_righttop); float maxRightBottom = Math.max(cornerRadius, mCornerRadius_rightBottom); float maxRight = Math.max(maxRighttop, maxRightBottom); rect_right = shadowWIDth - maxRight; } if (bottomShow) { rect_bottom = shadowHeight - shadowRadius; } else {// rect_bottom = shadowHeight; float maxleftBottom = Math.max(cornerRadius, mCornerRadius_leftBottom); float maxRightBottom = Math.max(cornerRadius, mCornerRadius_rightBottom); float maxBottom = Math.max(maxleftBottom, maxRightBottom); rect_bottom = shadowHeight - maxBottom; } RectF shadowRect = new RectF( rect_left, rect_top, rect_right, rect_bottom); if (isSym) { if (dy > 0) { shadowRect.top += dy; shadowRect.bottom -= dy; } else if (dy < 0) { shadowRect.top += Math.abs(dy); shadowRect.bottom -= Math.abs(dy); } if (dx > 0) { shadowRect.left += dx; shadowRect.right -= dx; } else if (dx < 0) { shadowRect.left += Math.abs(dx); shadowRect.right -= Math.abs(dx); } } else { shadowRect.top -= dy; shadowRect.bottom -= dy; shadowRect.right -= dx; shadowRect.left -= dx; } shadowPaint.setcolor(fillcolor); if (!isInEditMode()) {//dx dy shadowPaint.setShadowLayer(shadowRadius / 2, dx, dy, shadowcolor); } if (mCornerRadius_leftBottom == -1 && mCornerRadius_lefttop == -1 && mCornerRadius_righttop == -1 && mCornerRadius_rightBottom == -1) { //如果没有设置整个属性,那么按原始去画 canvas.drawRoundRect(shadowRect, cornerRadius, cornerRadius, shadowPaint); } else { //目前最佳的解决方案 rectf.left = leftpadding; rectf.top = toppadding; rectf.right = getWIDth() - rightpadding; rectf.bottom = getHeight() - bottompadding; shadowPaint.setAntiAlias(true); int lefttop; if (mCornerRadius_lefttop == -1) { lefttop = (int) mCornerRadius / 4; } else { lefttop = (int) mCornerRadius_lefttop / 4; } int leftBottom; if (mCornerRadius_leftBottom == -1) { leftBottom = (int) mCornerRadius / 4; } else { leftBottom = (int) mCornerRadius_leftBottom / 4; } int righttop; if (mCornerRadius_righttop == -1) { righttop = (int) mCornerRadius / 4; } else { righttop = (int) mCornerRadius_righttop / 4; } int rightBottom; if (mCornerRadius_rightBottom == -1) { rightBottom = (int) mCornerRadius / 4; } else { rightBottom = (int) mCornerRadius_rightBottom / 4; } float[] outerR = new float[]{lefttop, lefttop, righttop, righttop, rightBottom, rightBottom, leftBottom, leftBottom};//左上,右上,右下,左下 Path path = new Path(); path.addRoundRect(shadowRect, outerR, Path.Direction.CW); canvas.drawPath(path, shadowPaint); } return output; } @RequiresAPI(API = Build.VERSION_CODES.LolliPOP) @OverrIDe protected voID dispatchDraw(Canvas canvas) { int trueHeight = (int) (rectf.bottom - rectf.top); if (getChildAt(0) != null) { if (mCornerRadius_lefttop == -1 && mCornerRadius_leftBottom == -1 && mCornerRadius_righttop == -1 && mCornerRadius_rightBottom == -1) { //说明没有设置过任何特殊角、且是半圆。 if (mCornerRadius > trueHeight / 2) { Path path = new Path(); path.addRoundRect(rectf, trueHeight / 2, trueHeight / 2, Path.Direction.CW); canvas.clipPath(path); } else { Path path = new Path(); path.addRoundRect(rectf, mCornerRadius, mCornerRadius, Path.Direction.CW); canvas.clipPath(path); } } else { float[] outerR = getCornerValue(trueHeight); Path path = new Path(); path.addRoundRect(leftpadding, toppadding, getWIDth() - rightpadding, getHeight() - bottompadding, outerR, Path.Direction.CW); canvas.clipPath(path); } } super.dispatchDraw(canvas); } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); rectf.left = leftpadding; rectf.top = toppadding; rectf.right = getWIDth() - rightpadding; rectf.bottom = getHeight() - bottompadding; int trueHeight = (int) (rectf.bottom - rectf.top); //如果都为0说明,没有设置特定角,那么按正常绘制 if (getChildAt(0) != null) { if (mCornerRadius_lefttop == -1 && mCornerRadius_leftBottom == -1 && mCornerRadius_righttop == -1 && mCornerRadius_rightBottom == -1) { if (mCornerRadius > trueHeight / 2) { if (selectorType != 3) { if (layoutBackground == null && layoutBackground_true == null) { //画圆角矩形 canvas.drawRoundRect(rectf, trueHeight / 2, trueHeight / 2, paint); //解决边框线太洗时,四角的wIDth偏大和其他边不同 if (stroke_color != -101) { int the_height = (int) (rectf.bottom - rectf.top); int the_height_stoke = (int) (rectf.bottom - stroke_with / 2 - rectf.top - stroke_with / 2); int trueCorner = (int) (trueHeight * the_height_stoke / 2 / the_height); RectF rectFstroke = new RectF(rectf.left + stroke_with / 2, rectf.top + stroke_with / 2, rectf.right - stroke_with / 2, rectf.bottom - stroke_with / 2); canvas.drawRoundRect(rectFstroke, trueCorner, trueCorner, paint_stroke); } } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) { float[] outerR = getCornerValue(trueHeight); ripple(outerR); } } } else { if (selectorType != 3) { if (layoutBackground == null && layoutBackground_true == null) { canvas.drawRoundRect(rectf, mCornerRadius, mCornerRadius, paint); if (stroke_color != -101) { int the_height = (int) (rectf.bottom - rectf.top); int the_height_stoke = (int) (rectf.bottom - stroke_with / 2 - rectf.top - stroke_with / 2); int trueCorner = (int) (mCornerRadius * the_height_stoke / the_height); RectF rectFstroke = new RectF(rectf.left + stroke_with / 2, rectf.top + stroke_with / 2, rectf.right - stroke_with / 2, rectf.bottom - stroke_with / 2); canvas.drawRoundRect(rectFstroke, trueCorner, trueCorner, paint_stroke); } } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) { float[] outerR = getCornerValue(trueHeight); ripple(outerR); } } } } else { if (layoutBackground == null && layoutBackground_true == null) { setSpaceCorner(canvas, trueHeight); } } } } public float[] getCornerValue(int trueHeight) { int lefttop; int righttop; int rightBottom; int leftBottom; if (mCornerRadius_lefttop == -1) { lefttop = (int) mCornerRadius; } else { lefttop = (int) mCornerRadius_lefttop; } if (lefttop > trueHeight / 2) { lefttop = trueHeight / 2; } if (mCornerRadius_righttop == -1) { righttop = (int) mCornerRadius; } else { righttop = (int) mCornerRadius_righttop; } if (righttop > trueHeight / 2) { righttop = trueHeight / 2; } if (mCornerRadius_rightBottom == -1) { rightBottom = (int) mCornerRadius; } else { rightBottom = (int) mCornerRadius_rightBottom; } if (rightBottom > trueHeight / 2) { rightBottom = trueHeight / 2; } if (mCornerRadius_leftBottom == -1) { leftBottom = (int) mCornerRadius; } else { leftBottom = (int) mCornerRadius_leftBottom; } if (leftBottom > trueHeight / 2) { leftBottom = trueHeight / 2; } float[] outerR = new float[]{lefttop, lefttop, righttop, righttop, rightBottom, rightBottom, leftBottom, leftBottom};//左上,右上,右下,左下 return outerR; } //这里是为了解决stokeWith很大时,圆角盖不住底部四个角的BUG(issues #86) public float[] getCornerValueOther(int trueHeight, int stokeWith) { trueHeight = trueHeight - stokeWith * 2; int lefttop; int righttop; int rightBottom; int leftBottom; if (mCornerRadius_lefttop == -1) { lefttop = (int) mCornerRadius; } else { lefttop = (int) mCornerRadius_lefttop; } if (lefttop > trueHeight / 2) { lefttop = trueHeight / 2; } if (mCornerRadius_righttop == -1) { righttop = (int) mCornerRadius; } else { righttop = (int) mCornerRadius_righttop; } if (righttop > trueHeight / 2) { righttop = trueHeight / 2; } if (mCornerRadius_rightBottom == -1) { rightBottom = (int) mCornerRadius; } else { rightBottom = (int) mCornerRadius_rightBottom; } if (rightBottom > trueHeight / 2) { rightBottom = trueHeight / 2; } if (mCornerRadius_leftBottom == -1) { leftBottom = (int) mCornerRadius; } else { leftBottom = (int) mCornerRadius_leftBottom; } if (leftBottom > trueHeight / 2) { leftBottom = trueHeight / 2; } lefttop = lefttop - stokeWith; righttop = righttop - stokeWith; leftBottom = leftBottom - stokeWith; rightBottom = rightBottom - stokeWith; float[] outerR = new float[]{lefttop, lefttop, righttop, righttop, rightBottom, rightBottom, leftBottom, leftBottom};//左上,右上,右下,左下 return outerR; } //这是自定义四个角的方法。 private voID setSpaceCorner(Canvas canvas, int trueHeight) { float[] outerR = getCornerValue(trueHeight); if (stroke_color != -101) { if (selectorType != 3) { ShapeDrawable mDrawables = new ShapeDrawable(new RoundRectShape(outerR, null, null)); if (paint.getShader() != null) { mDrawables.getPaint().setShader(paint.getShader()); } else { mDrawables.getPaint().setcolor(paint.getcolor()); } mDrawables.setBounds(leftpadding, toppadding, getWIDth() - rightpadding, getHeight() - bottompadding); mDrawables.draw(canvas); float[] outerR_stroke = getCornerValueOther(trueHeight, (int) stroke_with); ShapeDrawable mDrawablesstroke = new ShapeDrawable(new RoundRectShape(outerR_stroke, null, null)); mDrawablesstroke.getPaint().setcolor(paint_stroke.getcolor()); mDrawablesstroke.getPaint().setStyle(Paint.Style.stroke); mDrawablesstroke.getPaint().setstrokeWIDth(stroke_with); mDrawablesstroke.setBounds((int) (leftpadding + stroke_with / 2), (int) (toppadding + stroke_with / 2), (int) (getWIDth() - rightpadding - stroke_with / 2), (int) (getHeight() - bottompadding - stroke_with / 2)); mDrawablesstroke.draw(canvas); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) { ripple(outerR); } } } else { if (selectorType != 3) { ShapeDrawable mDrawables = new ShapeDrawable(new RoundRectShape(outerR, null, null)); if (paint.getShader() != null) { mDrawables.getPaint().setShader(paint.getShader()); } else { mDrawables.getPaint().setcolor(paint.getcolor()); } mDrawables.setBounds(leftpadding, toppadding, getWIDth() - rightpadding, getHeight() - bottompadding); mDrawables.draw(canvas); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) { ripple(outerR); } } } } @RequiresAPI(API = Build.VERSION_CODES.LolliPOP) private voID ripple(float[] ouTradius) { int[][] stateList = new int[][]{ new int[]{androID.R.attr.state_pressed}, new int[]{androID.R.attr.state_focused}, new int[]{androID.R.attr.state_activated}, new int[]{} }; //深蓝 int normalcolor = mBackGroundcolor; //玫瑰红 int pressedcolor = mBackGroundcolor_true; int[] statecolorList = new int[]{ pressedcolor, pressedcolor, pressedcolor, normalcolor }; colorStateList colorStateList = new colorStateList(stateList, statecolorList); RoundRectShape roundRectShape = new RoundRectShape(ouTradius, null, null); ShapeDrawable maskDrawable = new ShapeDrawable(); maskDrawable.setShape(roundRectShape); maskDrawable.getPaint().setStyle(Paint.Style.FILL); if (startcolor != -101) { //如果设置了渐变色的话 gradIEnt(maskDrawable.getPaint()); } else { maskDrawable.getPaint().setcolor(normalcolor); } ShapeDrawable contentDrawable = new ShapeDrawable(); contentDrawable.setShape(roundRectShape); contentDrawable.getPaint().setStyle(Paint.Style.FILL); if (startcolor != -101) { //如果设置了渐变色的话 gradIEnt(contentDrawable.getPaint()); } else { contentDrawable.getPaint().setcolor(normalcolor); } //contentDrawable实际是默认初始化时展示的;maskDrawable 控制了rippledrawable的范围 rippledrawable rippledrawable = new rippledrawable(colorStateList, contentDrawable, maskDrawable); firstVIEw.setBackground(rippledrawable); } public voID isAddAlpha(int color) { //获取单签颜色值的透明度,如果没有设置透明度,默认加上#2a if (color.Alpha(color) == 255) { String red = Integer.toHexString(color.red(color)); String green = Integer.toHexString(color.green(color)); String blue = Integer.toHexString(color.blue(color)); if (red.length() == 1) { red = "0" + red; } if (green.length() == 1) { green = "0" + green; } if (blue.length() == 1) { blue = "0" + blue; } String endcolor = "#2a" + red + green + blue; mShadowcolor = convertTocolorInt(endcolor); } } public static int convertTocolorInt(String argb) throws IllegalArgumentException { if (!argb.startsWith("#")) { argb = "#" + argb; } return color.parsecolor(argb); } @OverrIDe public boolean ontouchEvent(MotionEvent event) { if (selectorType == 3) { //如果是水波纹模式,那么不需要进行下面的渲染,采用系统ripper即可 if (isClickable) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (selectorType == 3) { if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor_true); if (!TextUtils.isEmpty(text_true)) { mTextVIEw.setText(text_true); } } } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (selectorType == 3) { if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor); if (!TextUtils.isEmpty(text)) { mTextVIEw.setText(text); } } } break; } } return super.ontouchEvent(event); } if (mBackGroundcolor_true != -101 || stroke_color_true != -101 || layoutBackground_true != null) { if (isClickable) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (selectorType == 1) { if (mBackGroundcolor_true != -101) { paint.setcolor(mBackGroundcolor_true); //打个标记 paint.setShader(null); } if (stroke_color_true != -101) { paint_stroke.setcolor(stroke_color_true); } if (layoutBackground_true != null) { setmBackGround(layoutBackground_true); } postInvalIDate(); if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor_true); if (!TextUtils.isEmpty(text_true)) { mTextVIEw.setText(text_true); } } } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (selectorType == 1) { //打个标记 paint.setcolor(mBackGroundcolor); if (startcolor != -101) { gradIEnt(paint); } if (stroke_color != -101) { paint_stroke.setcolor(stroke_color); } if (layoutBackground != null) { setmBackGround(layoutBackground); } postInvalIDate(); if (mTextVIEw != null) { mTextVIEw.setTextcolor(textcolor); if (!TextUtils.isEmpty(text)) { mTextVIEw.setText(text); } } } break; } } } return super.ontouchEvent(event); } public voID setmBackGround(Drawable drawable) { if (firstVIEw != null && drawable != null) { if (mCornerRadius_lefttop == -1 && mCornerRadius_leftBottom == -1 && mCornerRadius_righttop == -1 && mCornerRadius_rightBottom == -1) { GlIDeRoundManager.setRoundCorner(firstVIEw, drawable, mCornerRadius); } else { int lefttop; if (mCornerRadius_lefttop == -1) { lefttop = (int) mCornerRadius; } else { lefttop = (int) mCornerRadius_lefttop; } int leftBottom; if (mCornerRadius_leftBottom == -1) { leftBottom = (int) mCornerRadius; } else { leftBottom = (int) mCornerRadius_leftBottom; } int righttop; if (mCornerRadius_righttop == -1) { righttop = (int) mCornerRadius; } else { righttop = (int) mCornerRadius_righttop; } int rightBottom; if (mCornerRadius_rightBottom == -1) { rightBottom = (int) mCornerRadius; } else { rightBottom = (int) mCornerRadius_rightBottom; } GlIDeRoundManager.setCorners(firstVIEw, drawable, lefttop, leftBottom, righttop, rightBottom); } } }}
//第二部分package com.mobile.common_library.manager;import androID.graphics.drawable.Drawable;import androID.os.Build;import androID.vIEw.VIEw;import com.bumptech.glIDe.GlIDe;import com.bumptech.glIDe.load.resource.bitmap.CenterCrop;import com.bumptech.glIDe.load.resource.bitmap.RoundedCorners;import com.bumptech.glIDe.request.target.CustomTarget;import com.bumptech.glIDe.request.Transition.Transition;import com.mobile.common_library.custom_vIEw.GlIDeRoundtransform;import androIDx.annotation.NonNull;import androIDx.annotation.Nullable;import androIDx.annotation.RequiresAPI;/** * author : Urasaki * e-mail : [email protected] * date : 2021/3/31 10:55 * introduce : */public class GlIDeRoundManager { public static voID setRoundCorner(final VIEw vIEw, final Drawable resourceID, final float cornerDipValue) { if (cornerDipValue == 0) { if (vIEw.getMeasureDWIDth() == 0 && vIEw.getMeasuredHeight() == 0) { vIEw.addOnLayoutchangelistener(new VIEw.OnLayoutchangelistener() { @OverrIDe public voID onLayoutChange(VIEw v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldRight, int oldBottom) { vIEw.removeOnLayoutchangelistener(this); GlIDe.with(vIEw) .asDrawable() .load(resourceID) .transform(new CenterCrop()) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } }); } else { GlIDe.with(vIEw) .asDrawable() .load(resourceID) .transform(new CenterCrop()) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } } else { if (vIEw.getMeasureDWIDth() == 0 && vIEw.getMeasuredHeight() == 0) { vIEw.addOnLayoutchangelistener(new VIEw.OnLayoutchangelistener() { @OverrIDe public voID onLayoutChange(VIEw v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldRight, int oldBottom) { vIEw.removeOnLayoutchangelistener(this); GlIDe.with(vIEw) .load(resourceID) .transform(new CenterCrop(), new RoundedCorners((int) cornerDipValue)) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } }); } else { GlIDe.with(vIEw) .load(resourceID) .transform(new CenterCrop(), new RoundedCorners((int) cornerDipValue)) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } } } public static voID setCorners(final VIEw vIEw, final Drawable resourceID, final float lefttop_corner, final float leftBottom_corner, final float righttop_corner, final float rightBottom_corner) { if (lefttop_corner == 0 && leftBottom_corner == 0 && righttop_corner == 0 && rightBottom_corner == 0) { if (vIEw.getMeasureDWIDth() == 0 && vIEw.getMeasuredHeight() == 0) { vIEw.addOnLayoutchangelistener(new VIEw.OnLayoutchangelistener() { @OverrIDe public voID onLayoutChange(VIEw v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldRight, int oldBottom) { vIEw.removeOnLayoutchangelistener(this); GlIDe.with(vIEw) .load(resourceID) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } }); } else { GlIDe.with(vIEw) .load(resourceID) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } } else { if (vIEw.getMeasureDWIDth() == 0 && vIEw.getMeasuredHeight() == 0) { vIEw.addOnLayoutchangelistener(new VIEw.OnLayoutchangelistener() { @OverrIDe public voID onLayoutChange(VIEw v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldRight, int oldBottom) { vIEw.removeOnLayoutchangelistener(this); GlIDeRoundtransform transform = new GlIDeRoundtransform(vIEw.getContext(), lefttop_corner, leftBottom_corner, righttop_corner, rightBottom_corner); GlIDe.with(vIEw) .load(resourceID) .transform(transform) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } }); } else { GlIDeRoundtransform transform = new GlIDeRoundtransform(vIEw.getContext(), lefttop_corner, leftBottom_corner, righttop_corner, rightBottom_corner); GlIDe.with(vIEw) .load(resourceID) .transform(transform) .overrIDe(vIEw.getMeasureDWIDth(), vIEw.getMeasuredHeight()) .into(new CustomTarget<Drawable>() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN) @OverrIDe public voID onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> Transition) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { vIEw.setBackgroundDrawable(resource); } else { vIEw.setBackground(resource); } } @OverrIDe public voID onl oadCleared(@Nullable Drawable placeholder) { } }); } } } }
2.使用。
<net.p5w.console.custom_vIEw.ShadowlinearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_gravity="center_horizontal" androID:layout_marginStart="@dimen/dp_2" androID:layout_marginEnd="@dimen/dp_2" androID:orIEntation="vertical" app:hl_cornerRadius="@dimen/dp_7" app:hl_shadowcolor="#2a000000" app:hl_shadowHIDdenBottom="false" app:hl_shadowHIDdenleft="false" app:hl_shadowHIDdenRight="false" app:hl_shadowHIDdentop="false" app:hl_shadowlimit="@dimen/dp_12"> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> <VIEw androID:layout_wIDth="@dimen/dp_8" androID:layout_height="@dimen/dp_10" /> <androIDx.recyclervIEw.Widget.RecyclerVIEw androID:ID="@+ID/rcv_sub_workbench" androID:layout_wIDth="@dimen/dp_316" androID:layout_height="wrap_content" /> <VIEw androID:layout_wIDth="@dimen/dp_8" androID:layout_height="@dimen/dp_10" /> </linearLayout> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="@dimen/dp_17" tools:ignore="UselessLeaf" /></net.p5w.console.custom_vIEw.ShadowlinearLayout>
如对此有疑问,请联系qq1164688204。
推荐完整AndroID开源项目
完整项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。
项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
总结
以上是内存溢出为你收集整理的Android阴影布局的实现全部内容,希望文章能够帮你解决Android阴影布局的实现所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)