zoukankan      html  css  js  c++  java
  • 给控件添加阴影

    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>
  • 相关阅读:
    uva 10369 Arctic Network
    uvalive 5834 Genghis Khan The Conqueror
    uvalive 4848 Tour Belt
    uvalive 4960 Sensor Network
    codeforces 798c Mike And Gcd Problem
    codeforces 796c Bank Hacking
    codeforces 768c Jon Snow And His Favourite Number
    hdu 1114 Piggy-Bank
    poj 1276 Cash Machine
    bzoj 2423 最长公共子序列
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/11899935.html
Copyright © 2011-2022 走看看