• 给控件添加阴影


    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>
  • 相关阅读:
    服务器管理注意事项
    帮朋友发个招聘信息
    tcp/ip协议简介
    程序员的本质(转)
    不同部门员工吃饭时聊些什么
    IE用户比Opera和Chrome用户的IQ低
    有一天,程序猿们突然发现他们要涨的工资掉到井里啦!大家都很害怕,连忙一个吊着一个,从树上伸到井里去捞工资。正好他们摸到工资的时候,一个老程序员忽然兴奋的大叫:别蠢了,要涨的工资还好好的挂在天上呢!
    asp.net使用缓存造成iis重启的问题
    Win批量修改文件名&扩展名
    引用变量位于Java虚拟机的运行时数据区的情况分析
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/11899935.html
Copyright © 2020-2023  润新知