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
Ripple effect for Android 14+

RippleDrawable Port of Android <ripple> effect for pre lollipop devices with android 14 + (ICS+) (well, since NineOldAndroids is deprecated, this libr

Ozodrukh 516 Nov 25, 2022
This is a library with components of Android L to you use in android 2.2

Material Design Android Library How to use Components Buttons Flat Button Rectangle Button Float Button Float small button Switches CheckBox Switch Pr

Ivan Navas 9.1k Jan 5, 2023
📱Android Library to implement animated, 😍beautiful, 🎨stylish Material Dialog in android apps easily.

Material Dialogs for Android ?? ?? Android Library to implement animated, ?? beautiful, ?? stylish Material Dialog in android apps easily. 1. Material

Shreyas Patil 875 Dec 28, 2022
MaterialPickers-in-android - A simple android project that shows how to create material pickers for date and time

MaterialPickers-in-android A simple android project that shows how to create mat

Segun Francis 2 Apr 28, 2022
Material Shadows for android : A library for supporting convex material shadows

MaterialShadows A library for seamlessly integrating Material shadows. The library takes existing material shadows to next level by adding the followi

Harjot Singh Oberai 2.2k Dec 19, 2022
A library to bring fully animated Material Design components to pre-Lolipop Android.

Material MaterialLibrary is an Open Source Android library that back-port Material Design components to pre-Lolipop Android. MaterialLibrary's origina

Rey Pham 6k Dec 21, 2022
😍 A beautiful, fluid, and extensible dialogs API for Kotlin & Android.

Material Dialogs View Releases and Changelogs Modules The core module is the fundamental module that you need in order to use this library. The others

Aidan Follestad 19.5k Dec 31, 2022
The flexible, easy to use, all in one drawer library for your Android project. Now brand new with material 2 design.

MaterialDrawer ... the flexible, easy to use, all in one drawer library for your Android project. What's included ?? • Setup ??️ • Migration Guide ??

Mike Penz 11.6k Dec 27, 2022
Floating Action Button for Android based on Material Design specification

FloatingActionButton Yet another library for drawing Material Design promoted actions. Features Support for normal 56dp and mini 40dp buttons. Customi

Zendesk 6.4k Dec 26, 2022
Material Design implementation for Android 4.0+. Shadows, ripples, vectors, fonts, animations, widgets, rounded corners and more.

Carbon Material Design implementation for Android 4.0 and newer. This is not the exact copy of the Lollipop's API and features. It's a custom implemen

null 3k Jan 9, 2023
Animations for Android L drawer, back, dismiss and check icons

Material Menu Morphing Android menu, back, dismiss and check buttons Have full control of the animation: Including in your project compile 'com.balysv

Balys Valentukevicius 2.5k Jan 3, 2023
An Android library aimed to get the beautiful CardViews that Google shows at its official design specifications

MaterialList Discontinued This library will not receive any updates, as I do not have the time or knowledge to improve it. If anyone forks it and want

null 1.6k Nov 29, 2022
Android widget for selecting a range of values.

MaterialRangeBar MaterialRangeBar is a fork from https://github.com/edmodo/range-bar that adds some basic material styling, as well as start and end v

null 1.7k Dec 30, 2022
Android drawer icon with material design animation

LDrawer Android drawer icon with material design animation Note Basically same as appcompat_v7 version 21, you can use appcompat_v7 compile 'com.andro

Hasan Keklik 1.4k Dec 25, 2022
[] Android Library that implements Snackbars from Google's Material Design documentation.

DEPRECATED This lib is deprecated in favor of Google's Design Support Library which includes a Snackbar and is no longer being developed. Thanks for a

null 1.5k Dec 16, 2022
A material horizontal calendar view for Android based on RecyclerView

Horizontal Calendar A material horizontal calendar view for Android based on RecyclerView. Installation The library is hosted on jcenter, add this to

Mulham Raee 1.2k Dec 15, 2022
Android Sample Project with Material Design and Toolbar.

AndroidMaterialDesignToolbar -- PROJECT IS NOT SUPPORTED Android Sample Project with Material Design and Toolbar. Project use Appcompat library for ma

kemal selim tekinarslan 713 Nov 11, 2022
Material style circular progress bar for Android

Material CircularProgressView Indeterminate Determinate Description This CircularProgressView is a (surprisingly) circular progress bar Android View t

Rahat Ahmed 760 Nov 30, 2022
Android - draw z-depth shadow of MaterialDesign

ZDepthShadowLayout Android - draw z-depth shadow of MaterialDesign Demo Screen Capture Download apply plugin: 'com.android.application' repositories

sho5nn 573 Nov 28, 2022