Android L Ripple effect wrapper for Views

Overview

Material Ripple Layout

Ripple effect wrapper for Android Views

Demo Image

Including in your project

compile 'com.balysv:material-ripple:1.0.2'

Check for latest version number on the widget below or visit Releases

Maven Central

Usage

Use static initializer on your View (see xml attributes below for customization)

MaterialRippleLayout.on(view)
           .rippleColor(Color.BLACK)
           .create();

Or wrap your View with MaterialRippleLayout in your layout file:

<com.balysv.materialripple.MaterialRippleLayout
    android:id="@+id/ripple"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Button inside a ripple"/>

</com.balysv.materialripple.MaterialRippleLayout>

If using in an AdapterView you must set rippleInAdapter to true

Configure using xml attributes or setters in code:

app:mrl_rippleOverlay="true"              // if true, ripple is drawn in foreground; false - background
app:mrl_rippleColor="#ff0000"             // color of ripple
app:mrl_rippleAlpha="0.1"                 // alpha of ripple
app:mrl_rippleDimension="10dp"            // radius of hover and starting ripple
app:mrl_rippleHover="true"                // if true, a hover effect is drawn when view is touched
app:mrl_rippleRoundedCorners="10dp"       // radius of corners of ripples. Note: it uses software rendering pipeline for API 17 and below
app:mrl_rippleInAdapter="true"            // if true, MaterialRippleLayout will optimize for use in AdapterViews
app:mrl_rippleDuration="350"              // duration of ripple animation
app:mrl_rippleFadeDuration="75"           // duration of fade out effect on ripple
app:mrl_rippleDelayClick="true"           // if true, delays calls to OnClickListeners until ripple effect ends
app:mrl_rippleBackground="#FFFFFF"        // background under ripple drawable; used with rippleOverlay="false"
app:mrl_ripplePersistent="true"           // if true, ripple background color persists after animation, until setRadius(0) is called

Set an OnClickListener to MaterialRippleLayout:

findViewById(R.id.ripple).setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        // handle me 
    }
});

Or if using in an AdapterView, simply use OnItemClickListener

Support for Android api versions < 14

For those unlucky developers that need to support older versions than 14, there's a way to do it.

You can use this library in addition with Jake Wharton's animation backport (http://nineoldandroids.com/) changing the imports from import android.animation.*; to: import com.nineoldandroids.animation.*; , import android.util.Property; to import com.nineoldandroids.util.Property; and in MaterialRippleLayout.java file, calling function shouldDelayChildPressedState() only if you're using api greater than 14.

Developed By

Balys Valentukevicius

License

Copyright 2015 Balys Valentukevicius

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • OnClickListener never called when DelayClick is true

    OnClickListener never called when DelayClick is true

    Hi, I'm starting to use your lib and I got this issue. By default, the DelayClick is true, but when I tap on the view the ripple works great, but the ClickListener of my view isn't triggered. When I set the Delay to false works fine.

    I take a look in your lib code and I found an IF that test if delay is false to run the click on child view, but if the test is true I didn't found the code to run the click on child when the animation finish.

    If it is a real bug and you don't have time to fix, I can try to fork and fix to you.

    Thanks

    bug 
    opened by joaogouveia 14
  • endless loop in rippleInAdapter

    endless loop in rippleInAdapter

    line 687 cause endless loop in MaterialRippleLayout.java

    code: public RippleBuilder rippleInAdapter(boolean inAdapter) { this.rippleInAdapter(inAdapter); //687 return this; }

    this.rippleInAdapter(inAdapter); maybe this.rippleSearchAdapter=inAdapter;

    opened by 3c 7
  • Crash when apply ripple builder on view holder

    Crash when apply ripple builder on view holder

    I'm trying your library on my view holder but when I run the project the application crash, these happend when I scroll the listView.

    The code is:

    public class CategoryViewCell extends AbstractAdapter {

    public CategoryViewCell(List<HashMap<String, Object>> dataModel){
        super(dataModel);
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup){
    
        ViewHolder viewHolder;
        if(convertView == null)
        {
            viewHolder = new ViewHolder();
            convertView = ApplicationLoader.mainLayoutInflater.inflate(R.layout.lsta_pral_item, null);
            viewHolder.imageView = (ImageView)convertView.findViewById(R.id.lstaPralItem);
            convertView.setTag(viewHolder);
        }
        else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }
    
        HashMap<String, Object> information = dataModel.get(position);
        String imagen = information.get("imagen").toString();
    
        Bitmap bitmapFromFile = ImageLoaderService.getInstance().getBitmapFromFile(imagen);
        if (bitmapFromFile != null)
        {
            viewHolder.imageView.setImageBitmap(bitmapFromFile);
        }
        else
        {
            viewHolder.imageView.setImageResource(R.drawable.no_found_image);
        }
    
        MaterialRippleLayout.on(viewHolder.imageView).rippleColor(Color.RED).create();
    
    
        return convertView;
    }
    
    private static class ViewHolder
    {
        ImageView imageView;
    }
    

    }

    And the crash is:

    java.lang.IllegalStateException: MaterialRippleLayout could not be created: parent of the view already is a MaterialRippleLayout
            at org.pademobile.widgets.MaterialRippleLayout$RippleBuilder.create(MaterialRippleLayout.java:701)
            at org.pademobile.bills.artifacts.CategoryViewCell.getView(CategoryViewCell.java:60)
            at android.widget.AbsListView.obtainView(AbsListView.java:2255)
            at android.widget.ListView.makeAndAddView(ListView.java:1790)
            at android.widget.ListView.fillDown(ListView.java:691)
            at android.widget.ListView.fillGap(ListView.java:655)
            at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5143)
            at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3243)
            at android.widget.AbsListView.onTouchMove(AbsListView.java:3587)
            at android.widget.AbsListView.onTouchEvent(AbsListView.java:3431)
            at android.view.View.dispatchTouchEvent(View.java:7736)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2212)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2466)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
            at android.view.View.dispatchPointerEvent(View.java:7916)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4023)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3902)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3452)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3471)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3479)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3452)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3471)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3479)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3452)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5657)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5588)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5559)
            at androi
    
    opened by cbedoy 5
  • Backport to older android versions

    Backport to older android versions

    I noticed minSdk is set to 14, so some users like me which are forced to support older versions can't use your library.

    As an enhancement, if you do not want to support older android versions, you can add a section in the readme.md explaining that you can use this library using the Jake Wharton's animation backport (http://nineoldandroids.com/) changing the imports from import android.animation.*; to: import com.nineoldandroids.animation.*; , import android.util.Property; to import com.nineoldandroids.util.Property; and calling function shouldDelayChildPressedState() only if you're using api greater than 14.

    Thank and congrats for the great job! David.

    opened by dlazaro66 5
  • Child view's onClickListener within MaterialRippleLayout doesn't work

    Child view's onClickListener within MaterialRippleLayout doesn't work

    Hi, I have custom list adapter of list view where each row is instantiated within "getView(int position, View convertView, ViewGroup parent)" method. The root view of each row is "MaterialRippleLayout" and it has some child views. There I set some click listener of child views. But "onClick(View v)" method is not being called when child view is clicked.

    opened by shahidul2k9 4
  • get AnimationEnd to perform Custom Action after that?

    get AnimationEnd to perform Custom Action after that?

    Is it possible to get the End of the Rippleanimation. I want to make the RippleAnimation to fill the screen and when it is filled( animation ended) the activity should be closed or anotherone should start.

    so an ripplelayout.onAnimationEnd with returntype of boolean or something similar would be great

    enhancement 
    opened by csaq7151 4
  • onItemClick is called after onItemLongClick in ListView

    onItemClick is called after onItemLongClick in ListView

    Hi,

    At first, thank you for the awesome library! I tried it in a ListView with setting app:rippleInAdapter="true", When I long click on an item in the list, the listener correctly called but immediately after releasing touch (MotionEvent.ACTION_UP) the onItemClick method of OnItemClickListener get called! even if returning true in onItemLongClick method!

    I've tested it with a normal FrameLayout and it hasn't any problem...

    I suggest you forget about LongClick in your click handling mechanism for the layout...

    bug 
    opened by semsamot 4
  • TODO List

    TODO List

    Feature backlog:

    • [x] Implement a callback or post onClick() when Ripple animation ends so one can start heavy UI operations after. For example ListView item click and a transition to another screen.
    • [x] Persistent Ripple effect flag (does not fade out and remains coloured)
    • [x] Fix AdapterView onItemClickListener when MaterialRippleLayout is a item container
    • [x] rippleFade attributes to control duration and strength of fade out effect
    enhancement 
    opened by balysv 4
  • LongClick not firing when moving finger.

    LongClick not firing when moving finger.

    When the LongClick listener is set to the view on which the MaterialRippleLayout is statically applied the event fires only when you don't move your finger while holding. It is the only place from which it is possible to consume the event. It behaves like this even in the demo application.

    enhancement 
    opened by RhavoX 3
  • Avoid create a MaterialRippleLayout when the view parent already is one

    Avoid create a MaterialRippleLayout when the view parent already is one

    Hi balysv, it's me again.

    This is a suggestion. Check if view parent already is a MaterialRiplleLayout before create a new one, to prevent stackoverflow. I got this error in an adapter that I create the ripple on my code. But, as an adapter reuse the view, my code insert an MaterialRippleLayout inside another and this cause stackoverflow. I fix the issue in my code, but I suggest this fix on the create method.

    Thanks

    opened by joaogouveia 3
  • Rendering Problems in AndroidStudio Layout Preview

    Rendering Problems in AndroidStudio Layout Preview

    The following classes could not be instantiated:
    - com.balysv.materialripple.MaterialRippleLayout (Open Class, Show Exception)
     Tip: Use View.isInEditMode() in your custom views to skip code or show sample data when shown in the IDE
    

    Inside AndroidStudio. Maybe add view.isInEditMode() support?

    I also keep getting:

    Exception Details 
    java.lang.ClassNotFoundException: com.nineoldandroids.util.Property
    

    It's just in layout preview from AndroidStudio. App is running fine, though. It's just quite annoying since you can't see your layout anymore from the editor.

    Or maybe anyone have any trick to "fix" this?

    bug 
    opened by ardok 2
  • setOnClickListener doesn't work when MaterialRippleLayout is used from a Custom View

    setOnClickListener doesn't work when MaterialRippleLayout is used from a Custom View

    This is the Layout I am using which works perfectly when I use it inside the .xml of my Fragment:

             <com.balysv.materialripple.MaterialRippleLayout
                    android:id="@+id/orderByFilterBtn"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:mrl_rippleColor="@color/gray_light"
                    android:layout_margin="2dp">
    
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="horizontal">
    
                        <TextView
                            android:id="@+id/orderByFilterTxt"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:text="@string/popular"
                            android:layout_marginStart="10dp"
                            />
    
                        <ImageView
                            android:id="@+id/orderByFilterDown"
                            android:layout_width="15dp"
                            android:layout_height="15dp"
                            android:layout_marginEnd="10dp"
                            android:layout_marginStart="4dp"
                            android:layout_gravity="center_vertical"
                            android:src="@drawable/baseline_arrow_drop_down_gray_24dp"
                            />
    
                    </LinearLayout> 
    
                </com.balysv.materialripple.MaterialRippleLayout>
    

    But when I try to use it from a Custom View with exactly the same code, the click event never gets called.

    view.findViewById(R.id.orderByFilterBtn).setOnClickListener(s->{ //Click Event });

    Any ideas why?

    opened by spapapan 0
  • RecycleView inside not width

    RecycleView inside not width"match_parent"

    I applied the example in the demo. It works smoothly. although the width of the list items is match_parent, the Ripple width value is wrap_content. How do I fix this?

    opened by volkanciloglu 0
  • delay in taking action at the end of timing

    delay in taking action at the end of timing

    I have a button and when I clicked it goes to another activity. I entered the time value in this button for example app: I used mrl_rippleDuration. But it doesn't take action for about 1 second after the animation ends.

    my xml :

    <com.balysv.materialripple.MaterialRippleLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:mrl_rippleBackground="@color/colorRed"
                app:mrl_rippleDuration="200">
       <Button
                    android:id="@+id/other_activity"
                    android:layout_width="350dp"
                    android:layout_height="wrap_content"
                    android:background="@color/transparent"/>
    </com.balysv.materialripple.MaterialRippleLayout>
    

    activity Class

         btn_other_activity = findViewById(R.id.other_activity);
         btn_other_activity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(context, OtherActivity.class);
                    startActivity(intent);
                }
            });
    
    opened by volkanciloglu 0
  • Child view's onClickListener within MaterialRippleLayout doesn't work

    Child view's onClickListener within MaterialRippleLayout doesn't work

    Hi, I have custom list adapter of list view the root view of each row is "MaterialRippleLayout" and it has some child views. There I set some click listener of child views. But "onClick(View v)" method is not being called when child view is clicked.

    Can you please provide example of ListView with root view is MaterialRippleLayout with child onclicklistener.

    opened by chetan2609 1
Releases(v1.0.2)
Owner
Balys Valentukevicius
Balys Valentukevicius
Android ripple animation helper, easy to create Circular Reveal. | Android水波动画帮助类,轻松实现View show/hide/startActivity()特效。(0.4.6)

CircularAnim English | 中文 首先来看一个UI动效图。 效果图是是Dribbble上看到的,原作品在此。 我所实现的效果如下: Watch on YouTube Compile 最新可用版本 So,你可以如下compile该项目,也可以直接把这个类 CircularAnim 拷

ice 2k Nov 19, 2022
A beautiful ripple animation for your app

Android Ripple Background A beautiful ripple animation for your app. You can easily change its color, speed of wave, one ripple or multiple ripples. S

Yao Yu 2.2k Dec 31, 2022
create your custom themes and change them dynamically with ripple animation

Android Animated Theme Manager create your custom themes and change them dynamically with ripple animation Features support java and kotlin projects.

Iman Dolatkia 601 Dec 22, 2022
[] Easily have blurred and transparent background effect on your Android views.

##[DEPRECATED] BlurBehind Easily have blurred and transparent background effect on your Android views. Before API level 14 there was a Window flag cal

Gokberk Ergun 516 Nov 25, 2022
explosive dust effect for views

ExplosionField explosive dust effect for views Getting started In your build.gradle: dependencies { compile 'tyrantgit:explosionfield:1.0.1' } Ex

null 3.6k Dec 29, 2022
Glass-break effect for views

BrokenView Glass-break effect for views. Demo Download APK Usage Android Studio dependencies { compile 'com.zys:brokenview:1.0.3' } Eclipse Just pu

null 859 Dec 30, 2022
A component for flip animation on Android, which is similar to the effect in Flipboard iPhone/Android

android-flip Aphid FlipView is a UI component to accomplish the flipping animation like Flipboard does. A pre-built demo APK file for Android OS 2.2+

Bo 2.8k Dec 21, 2022
Android ImageViews animated by Ken Burns Effect

KenBurnsView Android library that provides an extension to ImageView that creates an immersive experience by animating its drawable using the Ken Burn

Flávio Faria 2.7k Jan 2, 2023
EtsyBlur is an Android library that allows developers to easily add a glass-like blur effect implemented in the Etsy app.

EtsyBlur EtsyBlur is an Android library that allows developers to easily add a glass-like blur effect implemented in the past Etsy app. Try out the sa

Manabu S. 755 Dec 29, 2022
Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. The library is based on the code of Mario Klingemann.

Android StackBlur Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. Th

Enrique López Mañas 3.6k Dec 29, 2022
:sparkles: An easy way to implement an elastic touch effect for Android.

ElasticViews ✨ An easy way to implement an elastic touch effect for Android. Including in your project Gradle Add below codes to your root build.gradl

Jaewoong Eum 763 Dec 29, 2022
An easy, flexible way to add a shimmering effect to any view in an Android app.

Shimmer for Android Shimmer is an Android library that provides an easy way to add a shimmer effect to any view in your Android app. It is useful as a

Facebook 5.1k Dec 26, 2022
Memory efficient shimmering effect for Android applications by Supercharge.

DEPRECATED - ShimmerLayout Attention: This tool is now deprecated. Please switch to Shimmer for Android or any other shimmer effect solution. ShimmerL

Supercharge 2.5k Jan 4, 2023
A pager for Android with parallax effect

ParallaxPagerTransformer A pager transformer for Android with parallax effect Installation in your build.gradle file dependencies { // ... com

Javier Gonzalez 654 Dec 29, 2022
Library provides an easy way to a add shimmer effect in Android Compose project.

Add a shimmer effect to the layout in Android Compose

Valery 66 Dec 14, 2022
"Gooey-Effect" for android-compose

Gooey effect for android-compose "Gooey" is a library made to use "gooey-effect" that exists as a CSS trick in android-compose. Download repositories

SeokHo-Im 5 Oct 12, 2022
ViewAnimator view with a lollipop style reveal effect

ViewRevealAnimator Widget ViewAnimator view with a lollipop style reveal effect. Regular animation can be set (just like the default ViewAnimator) for

Alessandro Crugnola 339 Jun 3, 2022
Library project to display DialogFragment with a blur effect.

BlurDialogFragment This project allows to display DialogFragment with a burring effect behind. The blurring part is achieved through FastBlur algorith

tvbarthel 2.1k Dec 29, 2022
Wave effect of activity animation

WaveCompat Wave effect of activity animation How to use 1. Bind wave touch helper to a view which will start an activity when it clicked: WaveTouchHel

WangJie 348 Nov 29, 2022