2019-11-20 19:15:56

代码来自github,忘记是谁写的了,底子不错,适当做了点修改

===================================================

ShadowContainer

 

 

  1 package com.example.android_research;
  2 
  3 import android.content.Context;
  4 import android.content.res.TypedArray;
  5 import android.graphics.Canvas;
  6 import android.graphics.Color;
  7 import android.graphics.Paint;
  8 import android.graphics.Path;
  9 import android.graphics.RectF;
 10 import android.os.Build;
 11 import android.util.AttributeSet;
 12 import android.view.View;
 13 import android.view.ViewGroup;
 14 
 15 /**
 16  * <p>
 17  * Created by weiwei22 on 2019-11-20.
 18  */
 19 public class ShadowContainer extends ViewGroup {
 20     private final float topDeltaLength;
 21     private final float bottomDeltaLength;
 22     private final float leftDeltaLength;
 23     private final float rightDeltaLength;
 24     private final float cornerRadius;
 25     private final Paint mShadowPaint;
 26     private boolean drawShadow;
 27 
 28     public ShadowContainer(Context context) {
 29         this(context, null);
 30     }
 31 
 32     public ShadowContainer(Context context, AttributeSet attrs) {
 33         this(context, attrs, 0);
 34     }
 35 
 36     public ShadowContainer(Context context, AttributeSet attrs, int defStyleAttr) {
 37         super(context, attrs, defStyleAttr);
 38 
 39         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShadowContainer);
 40         topDeltaLength = a.getDimension(R.styleable.ShadowContainer_topDeltaLength, 0);
 41         bottomDeltaLength = a.getDimension(R.styleable.ShadowContainer_bottomDeltaLength, 0);
 42         leftDeltaLength = a.getDimension(R.styleable.ShadowContainer_leftDeltaLength, 0);
 43         rightDeltaLength = a.getDimension(R.styleable.ShadowContainer_rightDeltaLength, 0);
 44         cornerRadius = a.getDimension(R.styleable.ShadowContainer_containerCornerRadius, 0);
 45         drawShadow = a.getBoolean(R.styleable.ShadowContainer_enable, true);
 46         float dx = a.getDimension(R.styleable.ShadowContainer_deltaX, 0);
 47         float dy = a.getDimension(R.styleable.ShadowContainer_deltaY, 0);
 48         float shadowRadius = a.getDimension(R.styleable.ShadowContainer_containerShadowRadius, 0);
 49         int shadowColor = a.getColor(R.styleable.ShadowContainer_containerShadowColor, Color.RED);
 50         a.recycle();
 51 
 52         mShadowPaint = new Paint();
 53         mShadowPaint.setStyle(Paint.Style.FILL);
 54         mShadowPaint.setAntiAlias(true);
 55         mShadowPaint.setColor(shadowColor);
 56         mShadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor);
 57     }
 58 
 59     @Override
 60     protected void onFinishInflate() {
 61         super.onFinishInflate();
 62     }
 63 
 64     @Override
 65     protected void dispatchDraw(Canvas canvas) {
 66         if (drawShadow) {
 67             if (getLayerType() != LAYER_TYPE_SOFTWARE) {
 68                 setLayerType(LAYER_TYPE_SOFTWARE, null);
 69             }
 70             View child = getChildAt(0);
 71             int left = child.getLeft();
 72             int top = child.getTop();
 73             int right = child.getRight();
 74             int bottom = child.getBottom();
 75             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 76                 canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius, mShadowPaint);
 77             } else {
 78                 Path drawablePath = new Path();
 79                 drawablePath.moveTo(left + cornerRadius, top);
 80                 drawablePath.arcTo(new RectF(left, top, left + 2 * cornerRadius, top + 2 * cornerRadius), -90, -90, false);
 81                 drawablePath.lineTo(left, bottom - cornerRadius);
 82                 drawablePath.arcTo(new RectF(left, bottom - 2 * cornerRadius, left + 2 * cornerRadius, bottom), 180, -90, false);
 83                 drawablePath.lineTo(right - cornerRadius, bottom);
 84                 drawablePath.arcTo(new RectF(right - 2 * cornerRadius, bottom - 2 * cornerRadius, right, bottom), 90, -90, false);
 85                 drawablePath.lineTo(right, top + cornerRadius);
 86                 drawablePath.arcTo(new RectF(right - 2 * cornerRadius, top, right, top + 2 * cornerRadius), 0, -90, false);
 87                 drawablePath.close();
 88                 canvas.drawPath(drawablePath, mShadowPaint);
 89             }
 90         }
 91         super.dispatchDraw(canvas);
 92     }
 93 
 94     public void setDrawShadow(boolean drawShadow) {
 95         if (this.drawShadow == drawShadow) {
 96             return;
 97         }
 98         this.drawShadow = drawShadow;
 99         postInvalidate();
100     }
101 
102     @Override
103     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
104         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
105         if (getChildCount() != 1) {
106             throw new IllegalStateException("Child view must be ony one!");
107         }
108         int measuredWidth = getMeasuredWidth();
109         int measuredHeight = getMeasuredHeight();
110         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
111         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
112         View child = getChildAt(0);
113         ShadowLayoutParams layoutParams = (ShadowLayoutParams) child.getLayoutParams();
114         int childBottomMargin = (int) bottomDeltaLength;
115         int childLeftMargin = (int) leftDeltaLength;
116         int childRightMargin = (int) rightDeltaLength;
117         int childTopMargin = (int) topDeltaLength;
118         int widthMeasureSpecMode;
119         int widthMeasureSpecSize;
120         int heightMeasureSpecMode;
121         int heightMeasureSpecSize;
122         if (widthMode == MeasureSpec.UNSPECIFIED) {
123             widthMeasureSpecMode = MeasureSpec.UNSPECIFIED;
124             widthMeasureSpecSize = MeasureSpec.getSize(widthMeasureSpec);
125         } else {
126             if (layoutParams.width == ShadowLayoutParams.MATCH_PARENT) {
127                 widthMeasureSpecMode = MeasureSpec.EXACTLY;
128                 widthMeasureSpecSize = measuredWidth - childLeftMargin - childRightMargin;
129             } else if (ShadowLayoutParams.WRAP_CONTENT == layoutParams.width) {
130                 widthMeasureSpecMode = MeasureSpec.AT_MOST;
131                 widthMeasureSpecSize = measuredWidth - childLeftMargin - childRightMargin;
132             } else {
133                 widthMeasureSpecMode = MeasureSpec.EXACTLY;
134                 widthMeasureSpecSize = layoutParams.width;
135             }
136         }
137         if (heightMode == MeasureSpec.UNSPECIFIED) {
138             heightMeasureSpecMode = MeasureSpec.UNSPECIFIED;
139             heightMeasureSpecSize = MeasureSpec.getSize(heightMeasureSpec);
140         } else {
141             if (layoutParams.height == ShadowLayoutParams.MATCH_PARENT) {
142                 heightMeasureSpecMode = MeasureSpec.EXACTLY;
143                 heightMeasureSpecSize = measuredHeight - childBottomMargin - childTopMargin;
144             } else if (ShadowLayoutParams.WRAP_CONTENT == layoutParams.height) {
145                 heightMeasureSpecMode = MeasureSpec.AT_MOST;
146                 heightMeasureSpecSize = measuredHeight - childBottomMargin - childTopMargin;
147             } else {
148                 heightMeasureSpecMode = MeasureSpec.EXACTLY;
149                 heightMeasureSpecSize = layoutParams.height;
150             }
151         }
152         measureChild(child, MeasureSpec.makeMeasureSpec(widthMeasureSpecSize, widthMeasureSpecMode), MeasureSpec.makeMeasureSpec(heightMeasureSpecSize, heightMeasureSpecMode));
153         int parentWidthMeasureSpec = MeasureSpec.getMode(widthMeasureSpec);
154         int parentHeightMeasureSpec = MeasureSpec.getMode(heightMeasureSpec);
155         int height = measuredHeight;
156         int width = measuredWidth;
157         int childHeight = child.getMeasuredHeight();
158         int childWidth = child.getMeasuredWidth();
159         if (parentHeightMeasureSpec == MeasureSpec.AT_MOST) {
160             height = childHeight + childTopMargin + childBottomMargin;
161         }
162         if (parentWidthMeasureSpec == MeasureSpec.AT_MOST) {
163             width = childWidth + childRightMargin + childLeftMargin;
164         }
165         if (width < childWidth + leftDeltaLength + rightDeltaLength) {
166             width = (int) (childWidth + leftDeltaLength + rightDeltaLength);
167         }
168         if (height < childHeight + topDeltaLength + bottomDeltaLength) {
169             height = (int) (childHeight + topDeltaLength + bottomDeltaLength);
170         }
171         if (height != measuredHeight || width != measuredWidth) {
172             setMeasuredDimension(width, height);
173         }
174     }
175 
176     public static class ShadowLayoutParams extends MarginLayoutParams {
177 
178         public ShadowLayoutParams(Context c, AttributeSet attrs) {
179             super(c, attrs);
180         }
181 
182         public ShadowLayoutParams(int width, int height) {
183             super(width, height);
184         }
185 
186         public ShadowLayoutParams(MarginLayoutParams source) {
187             super(source);
188         }
189 
190         public ShadowLayoutParams(ViewGroup.LayoutParams source) {
191             super(source);
192         }
193     }
194 
195     @Override
196     protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
197         return new ShadowLayoutParams(ShadowLayoutParams.WRAP_CONTENT, ShadowLayoutParams.WRAP_CONTENT);
198     }
199 
200     @Override
201     protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
202         return new ShadowLayoutParams(p);
203     }
204 
205     @Override
206     public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
207         return new ShadowLayoutParams(getContext(), attrs);
208     }
209 
210     @Override
211     protected void onLayout(boolean changed, int l, int t, int r, int b) {
212         View child = getChildAt(0);
213         int measuredWidth = getMeasuredWidth();
214         int measuredHeight = getMeasuredHeight();
215         int childMeasureWidth = child.getMeasuredWidth();
216         int childMeasureHeight = child.getMeasuredHeight();
217 //        child.layout((measuredWidth - childMeasureWidth) / 2, (measuredHeight - childMeasureHeight) / 2, (measuredWidth + childMeasureWidth) / 2, (measuredHeight + childMeasureHeight) / 2);
218         child.layout((int) leftDeltaLength, (int) topDeltaLength, (int) (leftDeltaLength + childMeasureWidth), (int) (topDeltaLength + childMeasureHeight));
219     }
220 }
View Code

 

使用方式:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3     xmlns:app="http://schemas.android.com/apk/res-auto"
  4     xmlns:tools="http://schemas.android.com/tools"
  5     android:layout_width="match_parent"
  6     android:layout_height="match_parent"
  7     android:orientation="vertical">
  8 
  9     <FrameLayout
 10         android:id="@+id/top"
 11         android:layout_width="wrap_content"
 12         android:layout_height="wrap_content"
 13         android:layout_marginTop="10dp"
 14         android:layout_marginRight="10dp"
 15         android:visibility="gone">
 16 
 17         <View
 18             android:id="@+id/layer"
 19             android:layout_width="match_parent"
 20             android:layout_height="200dp"
 21             android:background="#7fff00ff" />
 22 
 23         <TextView
 24             android:id="@+id/tv"
 25             android:layout_width="wrap_content"
 26             android:layout_height="wrap_content"
 27             android:layout_marginLeft="10dp"
 28             android:layout_marginTop="10dp"
 29             android:text="默认竖屏"
 30             android:textColor="#00ff00"
 31             android:textSize="23sp" />
 32 
 33         <TextView
 34             android:layout_width="wrap_content"
 35             android:layout_height="wrap_content"
 36             android:layout_gravity="top|right"
 37             android:layout_marginTop="10dp"
 38             android:layout_marginRight="10dp"
 39             android:text="右上角"
 40             android:textColor="#00ff00"
 41             android:textSize="23sp" />
 42 
 43         <TextView
 44             android:id="@+id/btn"
 45             android:layout_width="wrap_content"
 46             android:layout_height="wrap_content"
 47             android:layout_gravity="bottom|right"
 48             android:layout_marginRight="10dp"
 49             android:layout_marginBottom="10dp"
 50             android:text="点击"
 51             android:textColor="#00ff00"
 52             android:textSize="23sp" />
 53     </FrameLayout>
 54 
 55     <LinearLayout
 56         android:layout_width="wrap_content"
 57         android:layout_height="wrap_content"
 58         android:layout_alignParentBottom="true"
 59         android:layout_centerHorizontal="true"
 60         android:background="@drawable/ala_wish_list_bg"
 61         android:orientation="vertical"
 62         android:padding="30dp">
 63 
 64         <TextView
 65             android:layout_width="wrap_content"
 66             android:layout_height="wrap_content"
 67             android:text="四周等距离发散阴影" />
 68 
 69         <com.example.android_research.ShadowContainer
 70             android:layout_width="wrap_content"
 71             android:layout_height="wrap_content"
 72             app:bottomDeltaLength="12dp"
 73             app:containerCornerRadius="13dp"
 74             app:containerShadowColor="#70B5041A"
 75             app:containerShadowRadius="6dp"
 76             app:leftDeltaLength="12dp"
 77             app:rightDeltaLength="12dp"
 78             app:topDeltaLength="12dp">
 79 
 80             <TextView
 81                 android:layout_width="match_parent"
 82                 android:layout_height="100dp"
 83                 android:background="@drawable/ala_my_wish_list_item_bg" />
 84         </com.example.android_research.ShadowContainer>
 85 
 86         <TextView
 87             android:layout_width="wrap_content"
 88             android:layout_height="wrap_content"
 89             android:layout_marginTop="30dp"
 90             android:text="底部阴影区较大,顶部及两侧较小" />
 91 
 92         <com.example.android_research.ShadowContainer
 93             android:layout_width="wrap_content"
 94             android:layout_height="wrap_content"
 95             app:bottomDeltaLength="12dp"
 96             app:containerCornerRadius="13dp"
 97             app:containerShadowColor="#70B5041A"
 98             app:containerShadowRadius="6dp"
 99             app:deltaY="3dp"
100             app:leftDeltaLength="4dp"
101             app:rightDeltaLength="4dp"
102             app:topDeltaLength="4dp">
103 
104             <TextView
105                 android:layout_width="match_parent"
106                 android:layout_height="100dp"
107                 android:background="@drawable/ala_my_wish_list_item_bg" />
108         </com.example.android_research.ShadowContainer>
109 
110 
111         <TextView
112             android:layout_width="wrap_content"
113             android:layout_height="wrap_content"
114             android:layout_marginTop="30dp"
115             android:text="圆形右下角运营区" />
116 
117         <com.example.android_research.ShadowContainer
118             android:layout_width="wrap_content"
119             android:layout_height="wrap_content"
120             app:bottomDeltaLength="10dp"
121             app:containerCornerRadius="80dp"
122             app:containerShadowColor="#ffff00"
123             app:containerShadowRadius="6dp"
124             app:deltaX="3dp"
125             app:deltaY="6dp"
126             app:rightDeltaLength="10dp"
127             app:topDeltaLength="0dp">
128 
129             <TextView
130                 android:layout_width="100dp"
131                 android:layout_height="100dp"
132                 android:background="@drawable/circle" />
133         </com.example.android_research.ShadowContainer>
134     </LinearLayout>
135 
136 
137 </RelativeLayout>

 

 posted on 2019-11-20 19:18  wlrhnh  阅读(310)  评论(0编辑  收藏  举报