MaterialShadows


Source link: https://github.com/harjot-oberai/MaterialShadows/

MaterialShadows

A library for seamlessly integrating Material shadows. The library takes existing material shadows to next level by adding the following features :

  • Convex shadows : The shadows are not only rectangular or circular, they can take any convex shape depending on the view and its content.
  • Support for shadow offsets : The library allows developers to set X and Y offset for the shadows.
  • Support for shadow intensity : The library also has support for setting shadow intensity via shadowAlpha attribute.
  • Shadows for semi-transparent views : The library allows shadows for semi-transparent views.
  • Support for Async Shadow calculations : The library allows the operations to be async to avoid blocking the UI thread for long calculations.
  • Shadow animations : The library supports fade out animation for shadow.

Usage

Just add the following dependency in your app's build.gradle

dependencies {

 compile 'com.sdsmdg.harjot:materialshadows:1.2.5' 
}

How does this work ?

The MaterialShadowViewWrapper is an extension of Relative Layout. The MaterialShadowFrameLayoutWrapper is an extension of FrameLayout. Use any one of them as per your convenience.

All the child views go through the same process of generating shadow as given below :

  1. First a bitmap is generated from the drawing cache of the view.
  2. 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.
  3. 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.
  4. A path is created from the points of the resulting convex hull.
  5. This path is passed to a CustomViewOutlineProvider object that is later attached to the view itself.
  6. 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!)

Example Usage 1 (Simple)

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

Example Usage 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>

Result

Example Usage 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>

Result

Example Usage 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>

Result

Using MaterialShadows with custom ViewGroups

Since the ShadowGenerator.java encapsulates all the code related to the generation of convex shadows, it is really easy to plug in convex shadows with any custom ViewGroup or some platform ViewGroup like LinearLayout etc.

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();

  
}

 
}

  
}

Note : Make sure to define all the 7 parameters required for ShadowGenerator, namely offsetX, offsetY, shadowAlpha, shouldShowWhenAllReady, shouldCalculateAsync, shouldAnimateShadow, animationDuration in the custom wrapper and handle changes in their values.

In case any parameter value changes, say OffsetX, add the following code inside the setter method for OffsetX :

public void setOffsetX(float offsetX) {

 this.offsetX = offsetX;

 if (shadowGenerator != null) {

 shadowGenerator.setOffsetX(offsetX);

 
}
 
}

If you want to add custom XML attributes with your CustomShadowWrapper class, add this to attrs.xml ( here) and handle them in your CustomShadowWrapper class accordingly.

<declare-styleable name="CustomShadowWrapper">

<attr name="shadowOffsetX" />

<attr name="shadowOffsetY" />

<attr name="shadowAlpha" />

 <attr name="calculateAsync" />

<attr name="showWhenAllReady" />

<attr name="animateShadow" />

<attr name="animationDuration" />
  </declare-styleable>

See MaterialShadowViewWrapper for more details.

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

Limitations

  1. Since the bitmap is traversed pixel by pixel, the performance for large views is bad. Hence the use of the library is limited to small views.
  2. Currently the shadow is generated only for direct children of the MaterialShadowViewWrapper. Hence if the desired views are placed inside a Linear Layout or some other view group, then each view must be wrapped by a seperate MaterialShadowViewWrapper or MaterialShadowFrameLayoutWrapper or a custom view group wrapper may be implemented.
  3. Each child of MaterialShadowViewWrapper or custom view group wrapper is assigned the same offset and shadow intensity. If fine control over every view's shadow is required then it must be wrapped inside its own MaterialShadowViewWrapper or MaterialShadowFrameLayoutWrapper.

Credits

  1. Yaroslav : Implementation of asynchronous calculations and shadow animations.

License

MaterialShadows is licensed under MIT license. View license.

Resources

Output per-package method counts.

Secure and easy storage for Android.

Hawk uses:

  • AES for the crypto
  • SharedPreferences for the storage
  • Gson

Hawk provides:

  • Secure data persistence
  • Save any type
  • Save list of any type

A SharedPreferences injection library for Android. Using annotation processing, this library makes it easy to load SharedPreferences values and listen for changes.

WearPrefs allows you to easily sync SharedPreferences files between an Android app and a paired Android Wear app. Useful for creating settings that apply across devices.

Separating data and state handling from Fragments or Activities without lots of boilerplate-code. Reducing them to simple dumb views.

A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes