MaterialShadows
介绍:
一个支持不规则形状的阴影效果库。
运行效果:
使用说明:
dependency
dependencies {
compile 'com.sdsmdg.harjot:materialshadows:1.2.0'
}
MaterialShadowViewWrapper继承自 Relative Layout,MaterialShadowFrameLayoutWrapper继承自FrameLayout,根据个人喜好使用任意一个。
All the child views go through the same process of generating shadow as given below :
-
First a bitmap is generated from the drawing cache of the view.
-
The bitmap is traversed pixel by pixel to remove all transparent pixels and get a list of points corresponding to the actual outline of the content of the view.
-
Since the points corresponding to outline may give a concave path, hence GrahamScan algorithm is used to generate a convex hull of the outline points.
-
A path is created from the points of the resulting convex hull.
-
This path is passed to a CustomViewOutlineProvider object that is later attached to the view itself.
-
Hence we get a convex shadow for any type of view based on its content.
P.S. : All the calculations related to graham scan are done asynchronously by default. This behavior can be controlled by calculateAsync parameter. (Thanks Yaroslav!)
示例1(基本)
XML
<com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="130dp"
android:layout_height="130dp"
android:elevation="5dp"
android:src="@drawable/poly" />
</com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper>
Result
示例2(offset)
XML
<com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper
android:layout_width="match_parent"
android:layout_height="match_parent"
app:shadowOffsetX="-15"
app:shadowOffsetY="30">
<ImageView
android:layout_width="130dp"
android:layout_height="130dp"
android:elevation="10dp"
android:src="@drawable/poly" />
</com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper>
效果
示例3(Shadow intensity)
xml
<com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper
android:layout_width="match_parent"
android:layout_height="match_parent"
app:shadowOffsetX="-15"
app:shadowOffsetY="30"
app:shadowAlpha="0.9">
<ImageView
android:layout_width="130dp"
android:layout_height="130dp"
android:elevation="10dp"
android:src="@drawable/poly" />
</com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper>
效果
示例4(Semi-transparent views)
xml
<com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper
android:layout_width="match_parent"
android:layout_height="match_parent"
app:shadowOffsetX="-30"
app:shadowOffsetY="30">
<ImageView
android:layout_width="130dp"
android:layout_height="130dp"
android:elevation="10dp"
android:background="#55000000" />
</com.sdsmdg.harjot.materialshadows.MaterialShadowViewWrapper>
效果
Using MaterialShadows with custom ViewGroups
因为 ShadowGenerator.java包括了产生阴影的所有相关代码,所以很容易把它应用到自定义的ViewGroup中:
public class CustomShadowWrapper extends CustomViewGroup {
ShadowGenerator shadowGenerator;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (shadowGenerator == null) {
shadowGenerator = new ShadowGenerator(this, offsetX, offsetY, shadowAlpha, shouldShowWhenAllReady, shouldCalculateAsync, shouldAnimateShadow, animationDuration);
}
shadowGenerator.generate();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (shadowGenerator != null) {
shadowGenerator.releaseResources();
}
}
}
注 : 确保定义了ShadowGenerator需要的所有7个参数 offsetX, offsetY, shadowAlpha, shouldShowWhenAllReady, shouldCalculateAsync, shouldAnimateShadow, animationDuration。并处理参数值的变化。
假如某个参数发生了变化,比如OffsetX,在OffsetX的setter方法中添加如下代码:
public void setOffsetX(float offsetX) {
this.offsetX = offsetX;
if (shadowGenerator != null) {
shadowGenerator.setOffsetX(offsetX);
}
}
详细做法见 MaterialShadowViewWrapper。
Documentation
XML attribute | Java set methods | Description | Default Value |
---|---|---|---|
shadowOffsetX | setOffsetX(...) | Set the X-offset of the shadow | 0.0f |
shadowOffsetY | setOffsetX(...) | Set the Y-offset of the shadow | 0.0f |
shadowAlpha | setShadowAlpha(...) | Set the value of shadow intensity (alpha) | 1.0f |
calculateAsync | setShouldCalculateAsync(...) | Set the flag for async shadow calculations. | true |
showWhenAllReady | setShowShadowsWhenAllReady(...) | Set the flag for showing all shadows after all calculations are over | true |
animateShadow | setShouldAnimateShadow(...) | Set the flag for shadow animation | true |
animationDuration | setAnimationDuration(...) | Set the value of shadow animation duration. | 300ms |
限制
-
因为bitmap是按像素遍历的,对于大的view性能可能不是很好。因此这个库主要用于小型的view。
-
目前只对MaterialShadowViewWrapper的直接子view生成阴影。因此如果一个view是在Linear Layout或者其它的 view group中,需要把每个view都用MaterialShadowViewWrapper或者MaterialShadowFrameLayoutWrapper包裹一遍,或者你也可以自定义view group 。
-
MaterialShadowViewWrapper或者自定义的 view group wrapper 中的子view都使用相同的阴影,所以如果你要为每个子view单独使用阴影,必需把每个子view都放在MaterialShadowViewWrapper中。