From 8739bc2e059efb3c90c2735d9f65812e565dca4a Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Mon, 11 Apr 2022 21:53:49 +0800 Subject: [PATCH] =?UTF-8?q?[driver=20passenger=20]=20bus=20=E4=B9=98?= =?UTF-8?q?=E5=AE=A2=E5=B1=8FUI=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passenger/ui/BusBorderShadowLayout.java | 359 ++++++++++++++++++ .../com/mogo/och/bus/passenger/ui/IShadow.kt | 65 ++++ .../mogo/och/bus/passenger/utils/DimenUtil.kt | 13 + .../main/res/layout/bus_p_route_fragment.xml | 39 +- .../src/main/res/values/attrs.xml | 20 + 5 files changed, 476 insertions(+), 20 deletions(-) create mode 100644 OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusBorderShadowLayout.java create mode 100644 OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/IShadow.kt create mode 100644 OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/utils/DimenUtil.kt create mode 100644 OCH/mogo-och-bus-passenger/src/main/res/values/attrs.xml diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusBorderShadowLayout.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusBorderShadowLayout.java new file mode 100644 index 0000000000..6bde93ce05 --- /dev/null +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusBorderShadowLayout.java @@ -0,0 +1,359 @@ +package com.mogo.och.bus.passenger.ui; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.BlurMaskFilter; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.widget.LinearLayout; + +import com.mogo.och.bus.passenger.R; +import com.mogo.och.bus.passenger.utils.DimenUtil; + +/** + * @author: wangmingjun + * @date: 2022/1/21 + * 边框阴影 + */ +public class BusBorderShadowLayout extends LinearLayout { + + + private static final String TAG = "ShadowLayout"; + + //默认阴影半径 + public static final float SHADOW_DEFAULT_RADIUS = DimenUtil.INSTANCE.dp2px(5); + + //阴影最大偏移量 + public static final float SHADOW_MAX_OFFSET = DimenUtil.INSTANCE.dp2px(20); + + //阴影最大模糊半径 + public static final float SHADOW_MAX_BLUR = DimenUtil.INSTANCE.dp2px(20); + + + + //默认模糊半径 + public static final float SHADOW_DEFAULT_BLUR_RADIUS = DimenUtil.INSTANCE.dp2px(5); + + + //阴影颜色 + private int shadowColor = Color.parseColor("#333333"); + + //阴影类型,0:默认为单边 1:单边 2:邻边 3:四边所有 + private int shadowType; + + //阴影半径 + private float shadowRadius = 0f; + + //模糊度半径 + private float blurRadius = SHADOW_DEFAULT_BLUR_RADIUS ; + + //水平位移 + private float xOffset = DimenUtil.INSTANCE.dp2px(10); + + + //竖直方向位移 + private float yOffset = DimenUtil.INSTANCE.dp2px(0); + + //背景色 + private int bgColor = Color.WHITE; + + //是否有点击效果 + private boolean hasEffect = false ; + + + int left =0 ,right =0,top = 0,bottom = 0 ; + + //代理方式 + private IShadow shadow = new BusBorderShadowLayout.ShadowConfig(this); + + private float mWidthMode; + private float mHeightMode; + private Paint mPaint = new Paint(); + private Paint locationPaint = new Paint(); + + public BusBorderShadowLayout(Context context) { + super(context,null); + } + + public BusBorderShadowLayout(Context context, AttributeSet attrs) { + this(context, attrs,0); + } + + public BusBorderShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速 + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout); + shadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, Color.BLUE); + blurRadius = typedArray.getDimension(R.styleable.ShadowLayout_blurRadius, SHADOW_DEFAULT_BLUR_RADIUS); + shadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius,0); + hasEffect = typedArray.getBoolean(R.styleable.ShadowLayout_hasEffect, false); + xOffset = typedArray.getDimension(R.styleable.ShadowLayout_xOffset,DimenUtil.INSTANCE.dp2px(10)); + yOffset = typedArray.getDimension(R.styleable.ShadowLayout_yOffset,DimenUtil.INSTANCE.dp2px(10)); + bgColor = typedArray.getColor(R.styleable.ShadowLayout_bgColor,Color.WHITE); + typedArray.recycle(); + + if (shadowRadius<0){ + shadowRadius = -shadowRadius; + } + if (blurRadius < 0) { + blurRadius = -blurRadius; + } + + blurRadius = Math.min(SHADOW_MAX_BLUR,blurRadius); + + if (Math.abs(xOffset)> SHADOW_MAX_OFFSET){ + xOffset = xOffset/Math.abs(xOffset) * SHADOW_MAX_OFFSET; + } + + if (Math.abs(yOffset) > SHADOW_MAX_OFFSET){ + yOffset = yOffset/Math.abs(yOffset) * SHADOW_MAX_OFFSET; + } + + init(); + } + + private void init(){ + setBackgroundColor(Color.parseColor("#00ffffff")); + if (xOffset>0){ + //水平偏移量为正数,右侧有阴影,阴影长度为blurRadius+|xOffset| + right = (int)(blurRadius + Math.abs(xOffset)); + }else if (xOffset==0){ + //水平偏移为0,水平间距为blurRadius + left = (int)blurRadius; + right = (int)blurRadius; + }else { + //水平偏移为负数,左侧有阴影,阴影长度为blurRadius+|xOffset| + left = (int)(blurRadius + Math.abs(xOffset)); + } + if (yOffset>0){ + //竖直偏移量为正数,底部有阴影,阴影长度为blurRadius+|yOffset| + bottom = (int)(blurRadius + Math.abs(yOffset)); + }else if (yOffset==0){ + //竖直偏移量为0,竖直间距为blurRadius + top = (int)blurRadius; + bottom = (int)blurRadius; + }else { + //竖直偏移量为负数,顶部有阴影,阴影长度为blurRadius+|yOffset| + top = (int)(blurRadius + Math.abs(yOffset)); + } + setPadding(left,top,right,bottom); + } + + + + + + /** + * 获取阴影设置 + * @return 返回阴影设置配置 + */ + public IShadow getShadowConfig(){ + return shadow; + } + + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed,l,t,r,b); + } + + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + } + + + + @Override + protected void onDraw(Canvas canvas) { + drawBackground(canvas);//放在super前是后景,相反是前景,前景会覆盖子布局 + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + + + + //绘制背景色(在子view底部) + private void drawBackground(Canvas canvas){ + + mWidthMode = getMeasuredWidth(); + mHeightMode = getMeasuredHeight(); + float startX = 0; + float startY = 0; + float endX = 0; + float endY = 0; + + if (xOffset==0){ + startX = right; + endX = mWidthMode-blurRadius; + }else { + startX = right+blurRadius; + endX = mWidthMode-left-blurRadius; + } + + if (yOffset==0){ + startY = bottom; + endY = mHeightMode-blurRadius; + }else { + startY = bottom+blurRadius; + endY = mHeightMode-top-blurRadius; + } +// mPaint.setShadowLayer(blurRadius,0,0,shadowColor); + if (blurRadius>0){ + mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL)); + } + mPaint.setColor(shadowColor); + mPaint.setAntiAlias(true); + + RectF shadowRect = new RectF(startX,startY,endX,endY); + + RectF locationRectF = new RectF(left,top,mWidthMode-right,mHeightMode-bottom); + if (shadowRadius==0){ + //不是圆角 + canvas.drawRect(shadowRect,mPaint); + }else { + //圆角,角度为shadowRadius + canvas.drawRoundRect(shadowRect,shadowRadius,shadowRadius,mPaint); + } + + locationPaint.setColor(bgColor); + locationPaint.setAntiAlias(true); + + if (shadowRadius==0){ + //不是圆角 + canvas.drawRect(locationRectF,locationPaint); + }else { + //圆角,角度为shadowRadius + canvas.drawRoundRect(locationRectF,shadowRadius,shadowRadius,locationPaint); + } + } + + + + /** + * 阴影配置 + */ + class ShadowConfig implements IShadow { + + //代理 + private BusBorderShadowLayout shadow; + + private ShadowConfig(BusBorderShadowLayout shadow) { + this.shadow = shadow; + } + + @Override + public IShadow setShadowRadius(float radius) { + return setShadowRadius(TypedValue.COMPLEX_UNIT_DIP,radius); + } + + @Override + public IShadow setShadowRadius(int unit, float radius) { + Context c = getContext(); + Resources r; + + if (c == null) { + r = Resources.getSystem(); + } else { + r = c.getResources(); + } + shadow.shadowRadius = Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics())); + return this; + } + + @Override + public IShadow setShadowColor(int color) { + shadow.shadowColor = color; + return this; + } + + @Override + public IShadow setShadowColorRes(int colorRes) { + shadow.shadowColor = shadow.getResources().getColor(colorRes); + return this; + } + + @Override + public IShadow setBlurRadius(float radius) { + return setBlurRadius(TypedValue.COMPLEX_UNIT_DIP,radius); + } + + @Override + public IShadow setBlurRadius(int unit, float radius) { + Context c = getContext(); + Resources r; + if (c == null) { + r = Resources.getSystem(); + } else { + r = c.getResources(); + } + shadow.blurRadius = Math.min(SHADOW_MAX_BLUR,Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics()))); + return this; + } + + @Override + public IShadow setXOffset(float offset) { + return setXOffset(TypedValue.COMPLEX_UNIT_DIP,offset); + } + + @Override + public IShadow setXOffset(int unit, float offset) { + Context c = getContext(); + Resources r; + if (c == null) { + r = Resources.getSystem(); + } else { + r = c.getResources(); + } + + float x = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics()); + if (Math.abs(x)> SHADOW_MAX_OFFSET){ + x = x/Math.abs(x) * SHADOW_MAX_OFFSET; + } + shadow.xOffset = x; + return this; + } + + @Override + public IShadow setYOffset(float offset) { + return setYOffset(TypedValue.COMPLEX_UNIT_DIP,offset); + } + + @Override + public IShadow setYOffset(int unit, float offset) { + Context c = getContext(); + Resources r; + if (c == null) { + r = Resources.getSystem(); + } else { + r = c.getResources(); + } + + float y = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics()); + if (Math.abs(y)> SHADOW_MAX_OFFSET){ + y = y/Math.abs(y) * SHADOW_MAX_OFFSET; + } + shadow.yOffset = y; + return this; + } + + @Override + public void commit() { + shadow.init(); + shadow.requestLayout(); + shadow.postInvalidate(); + } + } + + +} diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/IShadow.kt b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/IShadow.kt new file mode 100644 index 0000000000..ef5d8fd4eb --- /dev/null +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/IShadow.kt @@ -0,0 +1,65 @@ +package com.mogo.och.bus.passenger.ui + +import androidx.annotation.ColorRes + +/** + * @author: wangmingjun + * @date: 2022/1/21 + */ +interface IShadow { + //设置阴影半径 + fun setShadowRadius(radius:Float):IShadow + + //添加单位设置 + fun setShadowRadius(unit:Int,radius: Float):IShadow + + //设置应用颜色 + fun setShadowColor(color:Int):IShadow + + //设置阴影颜色资源文件id + fun setShadowColorRes(@ColorRes color: Int):IShadow + /** + * 设置模糊半径 + * @param radius + */ + fun setBlurRadius(radius:Float):IShadow + + /** + * + * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION} + * @param radius 模糊半径 + */ + fun setBlurRadius(unit:Int,radius:Float):IShadow + + /** + * 设置水平方向的偏移量 + * @param offset x轴偏移 + */ + fun setXOffset(offset:Float):IShadow + + + /** + * 设置x方向的偏移量,设置单位 + * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION} + * @param offset x轴偏移 + */ + fun setXOffset(unit:Int,offset:Float):IShadow + + /** + * 设置竖直方向的偏移量 + * @param offset y轴偏移 + */ + fun setYOffset(offset:Float):IShadow + + /** + * 设置竖直方向的偏移量,带单位 + * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION} + * @param offset y轴偏移 + */ + fun setYOffset(unit:Int,offset:Float):IShadow + + /** + * 更新绘制 + */ + fun commit(); +} \ No newline at end of file diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/utils/DimenUtil.kt b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/utils/DimenUtil.kt new file mode 100644 index 0000000000..4ad4e9a2ba --- /dev/null +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/utils/DimenUtil.kt @@ -0,0 +1,13 @@ +package com.mogo.och.bus.passenger.utils + +import android.content.res.Resources + +/** + * @author: wangmingjun + * @date: 2022/1/21 + */ +object DimenUtil{ + fun dp2px(value:Float):Float{ + return (0.5f + value * Resources.getSystem().displayMetrics.density) + } +} \ No newline at end of file diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml index e6b489e0b5..c10f22862f 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml @@ -5,30 +5,28 @@ android:layout_height="match_parent" android:background="@android:color/transparent"> - - - - - - - - - - - - - - - - + + + + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent"> + \ No newline at end of file diff --git a/OCH/mogo-och-bus-passenger/src/main/res/values/attrs.xml b/OCH/mogo-och-bus-passenger/src/main/res/values/attrs.xml new file mode 100644 index 0000000000..c2af65cc03 --- /dev/null +++ b/OCH/mogo-och-bus-passenger/src/main/res/values/attrs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file