├── Sample ├── Resources │ ├── drawable │ │ ├── ic_profil_plus.png │ │ └── shape_example.xml │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ ├── values │ │ ├── styles.xml │ │ ├── dimens.xml │ │ └── strings.xml │ ├── menu │ │ └── main.xml │ ├── values-w820dp │ │ └── dimens.xml │ ├── layout │ │ ├── activity_main.axml │ │ └── activity_main.xml │ └── Resource.Designer.cs ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Assets │ └── AboutAssets.txt ├── MainActivity.cs └── Sample.csproj ├── .gitmodules ├── RippleView ├── Resources │ ├── values │ │ ├── colors.xml │ │ └── attrs.xml │ ├── drawable │ │ └── shape_rounded.xml │ ├── anim │ │ └── zoom.xml │ ├── AboutResources.txt │ └── Resource.Designer.cs ├── Properties │ └── AssemblyInfo.cs ├── RippleView.csproj └── RippleView.cs ├── LICENSE ├── RippleView.sln ├── README.md └── .gitignore /Sample/Resources/drawable/ic_profil_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cheesebaron/RippleEffect/HEAD/Sample/Resources/drawable/ic_profil_plus.png -------------------------------------------------------------------------------- /Sample/Resources/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cheesebaron/RippleEffect/HEAD/Sample/Resources/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/Resources/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cheesebaron/RippleEffect/HEAD/Sample/Resources/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/Resources/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cheesebaron/RippleEffect/HEAD/Sample/Resources/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/Resources/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cheesebaron/RippleEffect/HEAD/Sample/Resources/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/FloatingActionButton"] 2 | path = submodules/FloatingActionButton 3 | url = git@github.com:Cheesebaron/FloatingActionButton.git 4 | -------------------------------------------------------------------------------- /RippleView/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /Sample/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sample/Resources/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /Sample/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RippleEffect 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sample/Resources/menu/main.xml: -------------------------------------------------------------------------------- 1 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /Sample/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Sample/Resources/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /Sample/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); -------------------------------------------------------------------------------- /RippleView/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("RippleView")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("RippleView")] 12 | [assembly: AssemblyCopyright("Copyright © Tomasz Cielecki 2014")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | [assembly: ComVisible(false)] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | -------------------------------------------------------------------------------- /Sample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("Sample")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Sample")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Robin Chutaux 4 | Copyright (c) 2014 Tomasz Cielecki 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /Sample/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Graphics; 3 | using Android.Views; 4 | using Android.OS; 5 | using DK.Ostebaronen.FloatingActionButton; 6 | 7 | namespace Sample 8 | { 9 | [Activity(Label = "Sample", MainLauncher = true, Icon = "@drawable/ic_launcher", Theme = "@style/AppTheme")] 10 | public class MainActivity : Activity 11 | { 12 | private Fab _fab; 13 | 14 | protected override void OnCreate(Bundle bundle) 15 | { 16 | base.OnCreate(bundle); 17 | 18 | // Set our view from the "main" layout resource 19 | SetContentView(Resource.Layout.activity_main); 20 | 21 | _fab = FindViewById(Resource.Id.button_floating_action); 22 | _fab.FabColor = Color.Purple; 23 | _fab.FabDrawable = Resources.GetDrawable(Resource.Drawable.ic_profil_plus); 24 | } 25 | 26 | public override bool OnCreateOptionsMenu(IMenu menu) 27 | { 28 | MenuInflater.Inflate(Resource.Menu.main, menu); 29 | return true; 30 | } 31 | 32 | public override bool OnOptionsItemSelected(IMenuItem item) 33 | { 34 | if (item.ItemId == Resource.Id.action_settings) 35 | return true; 36 | 37 | return base.OnOptionsItemSelected(item); 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /RippleView/Resources/drawable/shape_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /RippleView/Resources/anim/zoom.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 37 | -------------------------------------------------------------------------------- /RippleView.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RippleView", "RippleView\RippleView.csproj", "{5D8338E2-BD57-469F-AC2C-4E103079C54F}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5D8338E2-BD57-469F-AC2C-4E103079C54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5D8338E2-BD57-469F-AC2C-4E103079C54F}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5D8338E2-BD57-469F-AC2C-4E103079C54F}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {5D8338E2-BD57-469F-AC2C-4E103079C54F}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 23 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF}.Release|Any CPU.Deploy.0 = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /Sample/Resources/drawable/shape_example.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /RippleView/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. -------------------------------------------------------------------------------- /RippleView/Resources/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RippleEffect 2 | ============ 3 | 4 | This is a port from Java to Xamarin.Android C# of [RippleEffect](https://github.com/traex/RippleEffect), 5 | which allows you to give any kind of view the Material design ripple effect when touching a view. 6 | 7 | Simply wrap your view inside of `RippleView` and use the many options to control the animation and 8 | rejoice with a nice ripple effect. 9 | 10 | Usage 11 | ----- 12 | 13 | ``` 14 | 21 | 28 | 29 | ``` 30 | 31 | Customization 32 | ------------- 33 | 34 | There are several attributes you can change in the XML declaration: 35 | 36 | - rvAlpha: int between 0-255, default 90 - Alpha value of the ripple 37 | - rvFramerate: int, default 10 - Frame rate of the ripple animation 38 | - rvRippleDuration: int, default 400 - Duration of the ripple animation in ms 39 | - rvColor: color, default white - Color of the ripple 40 | - rvCentered: bool, default false - Center ripple in the child view 41 | - rvType: enum, (simpleRipple, doubleRipple), default simpleRipple - Simple or double ripple 42 | - rvZoom: bool, default false - Enables a zoom animation when true 43 | - rvZoomDuration: int, default 150 - Duration of the zoom animation 44 | 45 | Caveats 46 | ------- 47 | 48 | When using double ripple a background needs to be set for the RippleView or for its child. 49 | 50 | Thanks 51 | ------ 52 | 53 | Thanks to [Robin Chutaux](https://github.com/traex) for creating this library to begin with :) 54 | 55 | License 56 | ------- 57 | 58 | This project is licensed under the MIT License (MIT), please look at the LICENSE file in the repository. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | 110 | 111 | # nupkg for nuget 112 | *.nupkg 113 | 114 | # Xamarin components 115 | [Cc]omponents 116 | 117 | # Don't add ModernHttpClient binaries 118 | ModernHttpClient/vendor/MonoAndroid/* 119 | ModernHttpClient/vendor/MonoTouch/* 120 | 121 | *.mdb -------------------------------------------------------------------------------- /RippleView/RippleView.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {5D8338E2-BD57-469F-AC2C-4E103079C54F} 9 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10 | Library 11 | Properties 12 | Cheesebaron.RippleEffect 13 | Cheesebaron.RippleEffect 14 | 512 15 | Resources\Resource.Designer.cs 16 | Off 17 | True 18 | v4.0.3 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /Sample/Resources/layout/activity_main.axml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 21 | 28 | 35 | 36 | 43 | 50 | 51 | 52 | 60 | 69 | 70 | 81 | 85 | 86 | -------------------------------------------------------------------------------- /Sample/Resources/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 24 | 25 | 29 | 30 | 35 | 36 | 44 | 45 | 46 | 47 | 54 | 61 | 62 | 63 | 70 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Sample/Sample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {897F8FA7-5333-46F7-B7D1-DA3E059C5FDF} 9 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10 | Library 11 | Properties 12 | Sample 13 | Sample 14 | 512 15 | true 16 | Resources\Resource.Designer.cs 17 | Off 18 | True 19 | True 20 | Properties\AndroidManifest.xml 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | True 31 | None 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | False 41 | SdkOnly 42 | 43 | 44 | 45 | ..\submodules\FloatingActionButton\FloatingActionButton\bin\Debug\DK.Ostebaronen.FloatingActionButton.dll 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Designer 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | {5d8338e2-bd57-469f-ac2c-4e103079c54f} 82 | RippleView 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /RippleView/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.42000 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("Cheesebaron.RippleEffect.Resource", IsApplication=false)] 13 | 14 | namespace Cheesebaron.RippleEffect 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public partial class Animation 28 | { 29 | 30 | // aapt resource value: 0x7f030000 31 | public static int zoom = 2130903040; 32 | 33 | static Animation() 34 | { 35 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 36 | } 37 | 38 | private Animation() 39 | { 40 | } 41 | } 42 | 43 | public partial class Attribute 44 | { 45 | 46 | // aapt resource value: 0x7f010000 47 | public static int rv_alpha = 2130771968; 48 | 49 | // aapt resource value: 0x7f010006 50 | public static int rv_centered = 2130771974; 51 | 52 | // aapt resource value: 0x7f010005 53 | public static int rv_color = 2130771973; 54 | 55 | // aapt resource value: 0x7f010001 56 | public static int rv_framerate = 2130771969; 57 | 58 | // aapt resource value: 0x7f010002 59 | public static int rv_rippleDuration = 2130771970; 60 | 61 | // aapt resource value: 0x7f010008 62 | public static int rv_ripplePadding = 2130771976; 63 | 64 | // aapt resource value: 0x7f010007 65 | public static int rv_type = 2130771975; 66 | 67 | // aapt resource value: 0x7f010009 68 | public static int rv_zoom = 2130771977; 69 | 70 | // aapt resource value: 0x7f010003 71 | public static int rv_zoomDuration = 2130771971; 72 | 73 | // aapt resource value: 0x7f010004 74 | public static int rv_zoomScale = 2130771972; 75 | 76 | static Attribute() 77 | { 78 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 79 | } 80 | 81 | private Attribute() 82 | { 83 | } 84 | } 85 | 86 | public partial class Color 87 | { 88 | 89 | // aapt resource value: 0x7f040000 90 | public static int @__rippleViewDefaultColor = 2130968576; 91 | 92 | static Color() 93 | { 94 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 95 | } 96 | 97 | private Color() 98 | { 99 | } 100 | } 101 | 102 | public partial class Drawable 103 | { 104 | 105 | // aapt resource value: 0x7f020000 106 | public static int shape_rounded = 2130837504; 107 | 108 | static Drawable() 109 | { 110 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 111 | } 112 | 113 | private Drawable() 114 | { 115 | } 116 | } 117 | 118 | public partial class Id 119 | { 120 | 121 | // aapt resource value: 0x7f050000 122 | public static int doubleRipple = 2131034112; 123 | 124 | // aapt resource value: 0x7f050001 125 | public static int rectangle = 2131034113; 126 | 127 | // aapt resource value: 0x7f050002 128 | public static int simpleRipple = 2131034114; 129 | 130 | static Id() 131 | { 132 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 133 | } 134 | 135 | private Id() 136 | { 137 | } 138 | } 139 | 140 | public partial class Styleable 141 | { 142 | 143 | public static int[] RippleView = new int[] { 144 | 2130771968, 145 | 2130771969, 146 | 2130771970, 147 | 2130771971, 148 | 2130771972, 149 | 2130771973, 150 | 2130771974, 151 | 2130771975, 152 | 2130771976, 153 | 2130771977}; 154 | 155 | // aapt resource value: 0 156 | public static int RippleView_rv_alpha = 0; 157 | 158 | // aapt resource value: 6 159 | public static int RippleView_rv_centered = 6; 160 | 161 | // aapt resource value: 5 162 | public static int RippleView_rv_color = 5; 163 | 164 | // aapt resource value: 1 165 | public static int RippleView_rv_framerate = 1; 166 | 167 | // aapt resource value: 2 168 | public static int RippleView_rv_rippleDuration = 2; 169 | 170 | // aapt resource value: 8 171 | public static int RippleView_rv_ripplePadding = 8; 172 | 173 | // aapt resource value: 7 174 | public static int RippleView_rv_type = 7; 175 | 176 | // aapt resource value: 9 177 | public static int RippleView_rv_zoom = 9; 178 | 179 | // aapt resource value: 3 180 | public static int RippleView_rv_zoomDuration = 3; 181 | 182 | // aapt resource value: 4 183 | public static int RippleView_rv_zoomScale = 4; 184 | 185 | static Styleable() 186 | { 187 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 188 | } 189 | 190 | private Styleable() 191 | { 192 | } 193 | } 194 | } 195 | } 196 | #pragma warning restore 1591 197 | -------------------------------------------------------------------------------- /Sample/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.34014 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("Sample.Resource", IsApplication=true)] 13 | 14 | namespace Sample 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public static void UpdateIdValues() 28 | { 29 | global::Cheesebaron.RippleEffect.Resource.Animation.zoom = global::Sample.Resource.Animation.zoom; 30 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_alpha = global::Sample.Resource.Attribute.rv_alpha; 31 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_centered = global::Sample.Resource.Attribute.rv_centered; 32 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_color = global::Sample.Resource.Attribute.rv_color; 33 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_framerate = global::Sample.Resource.Attribute.rv_framerate; 34 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_rippleDuration = global::Sample.Resource.Attribute.rv_rippleDuration; 35 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_ripplePadding = global::Sample.Resource.Attribute.rv_ripplePadding; 36 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_type = global::Sample.Resource.Attribute.rv_type; 37 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_zoom = global::Sample.Resource.Attribute.rv_zoom; 38 | global::Cheesebaron.RippleEffect.Resource.Attribute.rv_zoomDuration = global::Sample.Resource.Attribute.rv_zoomDuration; 39 | global::Cheesebaron.RippleEffect.Resource.Color.@__rippleViewDefaultColor = global::Sample.Resource.Color.@__rippleViewDefaultColor; 40 | global::Cheesebaron.RippleEffect.Resource.Drawable.shape_rounded = global::Sample.Resource.Drawable.shape_rounded; 41 | global::Cheesebaron.RippleEffect.Resource.Id.doubleRipple = global::Sample.Resource.Id.doubleRipple; 42 | global::Cheesebaron.RippleEffect.Resource.Id.rectangle = global::Sample.Resource.Id.rectangle; 43 | global::Cheesebaron.RippleEffect.Resource.Id.simpleRipple = global::Sample.Resource.Id.simpleRipple; 44 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView = global::Sample.Resource.Styleable.RippleView; 45 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_alpha = global::Sample.Resource.Styleable.RippleView_rv_alpha; 46 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_centered = global::Sample.Resource.Styleable.RippleView_rv_centered; 47 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_color = global::Sample.Resource.Styleable.RippleView_rv_color; 48 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_framerate = global::Sample.Resource.Styleable.RippleView_rv_framerate; 49 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_rippleDuration = global::Sample.Resource.Styleable.RippleView_rv_rippleDuration; 50 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_ripplePadding = global::Sample.Resource.Styleable.RippleView_rv_ripplePadding; 51 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_type = global::Sample.Resource.Styleable.RippleView_rv_type; 52 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_zoom = global::Sample.Resource.Styleable.RippleView_rv_zoom; 53 | global::Cheesebaron.RippleEffect.Resource.Styleable.RippleView_rv_zoomDuration = global::Sample.Resource.Styleable.RippleView_rv_zoomDuration; 54 | } 55 | 56 | public partial class Animation 57 | { 58 | 59 | // aapt resource value: 0x7f040000 60 | public const int zoom = 2130968576; 61 | 62 | static Animation() 63 | { 64 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 65 | } 66 | 67 | private Animation() 68 | { 69 | } 70 | } 71 | 72 | public partial class Attribute 73 | { 74 | 75 | // aapt resource value: 0x7f010000 76 | public const int rv_alpha = 2130771968; 77 | 78 | // aapt resource value: 0x7f010005 79 | public const int rv_centered = 2130771973; 80 | 81 | // aapt resource value: 0x7f010004 82 | public const int rv_color = 2130771972; 83 | 84 | // aapt resource value: 0x7f010001 85 | public const int rv_framerate = 2130771969; 86 | 87 | // aapt resource value: 0x7f010002 88 | public const int rv_rippleDuration = 2130771970; 89 | 90 | // aapt resource value: 0x7f010007 91 | public const int rv_ripplePadding = 2130771975; 92 | 93 | // aapt resource value: 0x7f010006 94 | public const int rv_type = 2130771974; 95 | 96 | // aapt resource value: 0x7f010008 97 | public const int rv_zoom = 2130771976; 98 | 99 | // aapt resource value: 0x7f010003 100 | public const int rv_zoomDuration = 2130771971; 101 | 102 | static Attribute() 103 | { 104 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 105 | } 106 | 107 | private Attribute() 108 | { 109 | } 110 | } 111 | 112 | public partial class Color 113 | { 114 | 115 | // aapt resource value: 0x7f060000 116 | public const int @__rippleViewDefaultColor = 2131099648; 117 | 118 | static Color() 119 | { 120 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 121 | } 122 | 123 | private Color() 124 | { 125 | } 126 | } 127 | 128 | public partial class Dimension 129 | { 130 | 131 | // aapt resource value: 0x7f070000 132 | public const int activity_horizontal_margin = 2131165184; 133 | 134 | // aapt resource value: 0x7f070001 135 | public const int activity_vertical_margin = 2131165185; 136 | 137 | static Dimension() 138 | { 139 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 140 | } 141 | 142 | private Dimension() 143 | { 144 | } 145 | } 146 | 147 | public partial class Drawable 148 | { 149 | 150 | // aapt resource value: 0x7f020000 151 | public const int ic_launcher = 2130837504; 152 | 153 | // aapt resource value: 0x7f020001 154 | public const int ic_profil_plus = 2130837505; 155 | 156 | // aapt resource value: 0x7f020002 157 | public const int shape_example = 2130837506; 158 | 159 | // aapt resource value: 0x7f020003 160 | public const int shape_rounded = 2130837507; 161 | 162 | static Drawable() 163 | { 164 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 165 | } 166 | 167 | private Drawable() 168 | { 169 | } 170 | } 171 | 172 | public partial class Id 173 | { 174 | 175 | // aapt resource value: 0x7f050009 176 | public const int action_settings = 2131034121; 177 | 178 | // aapt resource value: 0x7f050003 179 | public const int actionbar = 2131034115; 180 | 181 | // aapt resource value: 0x7f050008 182 | public const int button_floating_action = 2131034120; 183 | 184 | // aapt resource value: 0x7f050001 185 | public const int doubleRipple = 2131034113; 186 | 187 | // aapt resource value: 0x7f050007 188 | public const int floating = 2131034119; 189 | 190 | // aapt resource value: 0x7f050004 191 | public const int more = 2131034116; 192 | 193 | // aapt resource value: 0x7f050005 194 | public const int more2 = 2131034117; 195 | 196 | // aapt resource value: 0x7f050006 197 | public const int rect = 2131034118; 198 | 199 | // aapt resource value: 0x7f050002 200 | public const int rectangle = 2131034114; 201 | 202 | // aapt resource value: 0x7f050000 203 | public const int simpleRipple = 2131034112; 204 | 205 | static Id() 206 | { 207 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 208 | } 209 | 210 | private Id() 211 | { 212 | } 213 | } 214 | 215 | public partial class Layout 216 | { 217 | 218 | // aapt resource value: 0x7f030000 219 | public const int activity_main = 2130903040; 220 | 221 | static Layout() 222 | { 223 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 224 | } 225 | 226 | private Layout() 227 | { 228 | } 229 | } 230 | 231 | public partial class Menu 232 | { 233 | 234 | // aapt resource value: 0x7f0a0000 235 | public const int main = 2131361792; 236 | 237 | static Menu() 238 | { 239 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 240 | } 241 | 242 | private Menu() 243 | { 244 | } 245 | } 246 | 247 | public partial class String 248 | { 249 | 250 | // aapt resource value: 0x7f080002 251 | public const int action_settings = 2131230722; 252 | 253 | // aapt resource value: 0x7f080000 254 | public const int app_name = 2131230720; 255 | 256 | // aapt resource value: 0x7f080001 257 | public const int hello_world = 2131230721; 258 | 259 | static String() 260 | { 261 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 262 | } 263 | 264 | private String() 265 | { 266 | } 267 | } 268 | 269 | public partial class Style 270 | { 271 | 272 | // aapt resource value: 0x7f090000 273 | public const int AppTheme = 2131296256; 274 | 275 | static Style() 276 | { 277 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 278 | } 279 | 280 | private Style() 281 | { 282 | } 283 | } 284 | 285 | public partial class Styleable 286 | { 287 | 288 | public static int[] RippleView = new int[] { 289 | 2130771968, 290 | 2130771969, 291 | 2130771970, 292 | 2130771971, 293 | 2130771972, 294 | 2130771973, 295 | 2130771974, 296 | 2130771975, 297 | 2130771976}; 298 | 299 | // aapt resource value: 0 300 | public const int RippleView_rv_alpha = 0; 301 | 302 | // aapt resource value: 5 303 | public const int RippleView_rv_centered = 5; 304 | 305 | // aapt resource value: 4 306 | public const int RippleView_rv_color = 4; 307 | 308 | // aapt resource value: 1 309 | public const int RippleView_rv_framerate = 1; 310 | 311 | // aapt resource value: 2 312 | public const int RippleView_rv_rippleDuration = 2; 313 | 314 | // aapt resource value: 7 315 | public const int RippleView_rv_ripplePadding = 7; 316 | 317 | // aapt resource value: 6 318 | public const int RippleView_rv_type = 6; 319 | 320 | // aapt resource value: 8 321 | public const int RippleView_rv_zoom = 8; 322 | 323 | // aapt resource value: 3 324 | public const int RippleView_rv_zoomDuration = 3; 325 | 326 | static Styleable() 327 | { 328 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 329 | } 330 | 331 | private Styleable() 332 | { 333 | } 334 | } 335 | } 336 | } 337 | #pragma warning restore 1591 338 | -------------------------------------------------------------------------------- /RippleView/RippleView.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Robin Chutaux 5 | * Copyright (c) 2014 Tomasz Cielecki 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | using System; 27 | using Android.Content; 28 | using Android.Graphics; 29 | using Android.OS; 30 | using Android.Runtime; 31 | using Android.Util; 32 | using Android.Views; 33 | using Android.Views.Animations; 34 | using Android.Widget; 35 | 36 | namespace Cheesebaron.RippleEffect 37 | { 38 | public class RippleView 39 | : RelativeLayout 40 | { 41 | public event EventHandler OnCompletition; 42 | 43 | private int _width; 44 | private int _height; 45 | private int _frameRate = 10; 46 | private int _duration = 400; 47 | private int _paintAlpha = 90; 48 | private Handler _canvasHandler; 49 | private float _radiusMax; 50 | private bool _animationRunning; 51 | private int _timer; 52 | private int _timerEmpty; 53 | private int _durationEmpty = -1; 54 | private float _x = -1; 55 | private float _y = -1; 56 | private int _zoomDuration; 57 | private float _zoomScale; 58 | private Animation _scaleAnimation; 59 | private bool _hasToZoom; 60 | private bool _isCentered; 61 | private int _rippleType; 62 | private Paint _paint; 63 | private Bitmap _originBitmap; 64 | private Color _rippleColor; 65 | //private View _childView; 66 | private int _ripplePadding; 67 | private GestureDetector _gestureDetector; 68 | 69 | protected RippleView(IntPtr javaReference, JniHandleOwnership transfer) 70 | : base(javaReference, transfer) { } 71 | 72 | public RippleView(Context context) 73 | : base(context) { } 74 | 75 | public RippleView(Context context, IAttributeSet attrs) 76 | : this(context, attrs, 0) { } 77 | 78 | public RippleView(Context context, IAttributeSet attrs, int defStyle) 79 | : base(context, attrs, defStyle) 80 | { 81 | Init(context, attrs); 82 | } 83 | 84 | private void Init(Context context, IAttributeSet attrs) 85 | { 86 | if (IsInEditMode) 87 | return; 88 | 89 | var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.RippleView); 90 | _rippleColor = a.GetColor(Resource.Styleable.RippleView_rv_color, 91 | Resources.GetColor(Resource.Color.__rippleViewDefaultColor)); 92 | _rippleType = a.GetInt(Resource.Styleable.RippleView_rv_type, 0); 93 | _hasToZoom = a.GetBoolean(Resource.Styleable.RippleView_rv_zoom, false); 94 | _isCentered = a.GetBoolean(Resource.Styleable.RippleView_rv_centered, false); 95 | _duration = a.GetInt(Resource.Styleable.RippleView_rv_rippleDuration, _duration); 96 | _frameRate = a.GetInt(Resource.Styleable.RippleView_rv_framerate, _frameRate); 97 | _paintAlpha = a.GetInt(Resource.Styleable.RippleView_rv_alpha, _paintAlpha); 98 | _ripplePadding = a.GetDimensionPixelSize(Resource.Styleable.RippleView_rv_ripplePadding, 0); 99 | _canvasHandler = new Handler(); 100 | _zoomScale = a.GetFloat(Resource.Styleable.RippleView_rv_zoomScale, 1.03f); 101 | _zoomDuration = a.GetInt(Resource.Styleable.RippleView_rv_zoomDuration, 200); 102 | _scaleAnimation = AnimationUtils.LoadAnimation(context, Resource.Animation.zoom); 103 | _scaleAnimation.Duration = a.GetInt(Resource.Styleable.RippleView_rv_zoomDuration, 150); 104 | _paint = new Paint(PaintFlags.AntiAlias); 105 | _paint.SetStyle(Paint.Style.Fill); 106 | _paint.Color = _rippleColor; 107 | _paint.Alpha = _paintAlpha; 108 | 109 | a.Recycle(); 110 | 111 | _gestureDetector = new GestureDetector(context, new RippleGestureDetector(this)); 112 | 113 | SetWillNotDraw(false); 114 | DrawingCacheEnabled = true; 115 | } 116 | 117 | /*public override void AddView(View child, int index, ViewGroup.LayoutParams @params) 118 | { 119 | _childView = child; 120 | base.AddView(child, index, @params); 121 | }*/ 122 | 123 | public override void Draw(Canvas canvas) 124 | { 125 | base.Draw(canvas); 126 | if (!_animationRunning) return; 127 | 128 | if (_duration <= _timer * _frameRate) 129 | { 130 | _animationRunning = false; 131 | _timer = 0; 132 | _durationEmpty = -1; 133 | _timerEmpty = 0; 134 | canvas.Restore(); 135 | Invalidate(); 136 | if (OnCompletition != null) 137 | OnCompletition (this, new EventArgs ()); 138 | return; 139 | } 140 | 141 | _canvasHandler.PostDelayed(Invalidate, _frameRate); 142 | 143 | if (_timer == 0) 144 | canvas.Save(); 145 | 146 | canvas.DrawCircle(_x, _y, (_radiusMax * (((float) _timer * _frameRate) / _duration)), _paint); 147 | 148 | _paint.Color = Resources.GetColor(Android.Resource.Color.HoloRedLight); 149 | 150 | if (_rippleType == 1 && _originBitmap != null && (((float) _timer * _frameRate) / _duration) > 0.4f) 151 | { 152 | if (_durationEmpty == -1) 153 | _durationEmpty = _duration - _timer * _frameRate; 154 | 155 | _timerEmpty++; 156 | using (var tmpBitmap = GetCircleBitmap((int) (_paintAlpha - ((_paintAlpha) * 157 | (((float) _timerEmpty * _frameRate) / (_durationEmpty)))))) 158 | { 159 | canvas.DrawBitmap(tmpBitmap, 0, 0, _paint); 160 | tmpBitmap.Recycle(); 161 | } 162 | } 163 | 164 | _paint.Color = _rippleColor; 165 | 166 | if (_rippleType == 1) 167 | { 168 | if ((((float) _timer * _frameRate) / _duration) > 0.6f) 169 | _paint.Alpha = 170 | (int) (_paintAlpha - (_paintAlpha * (((float) _timerEmpty * _frameRate) / _durationEmpty))); 171 | else 172 | _paint.Alpha = _paintAlpha; 173 | } 174 | else 175 | _paint.Alpha = (int)(_paintAlpha - (_paintAlpha * (((float)_timer * _frameRate) / _duration))); 176 | 177 | _timer++; 178 | } 179 | 180 | protected override void OnSizeChanged(int w, int h, int oldw, int oldh) 181 | { 182 | base.OnSizeChanged(w, h, oldw, oldh); 183 | _width = w; 184 | _height = h; 185 | 186 | _scaleAnimation = new ScaleAnimation(1.0f, _zoomScale, 1.0f, _zoomScale, w / 2, h / 2); 187 | _scaleAnimation.Duration = _zoomDuration; 188 | _scaleAnimation.RepeatMode = RepeatMode.Reverse; 189 | _scaleAnimation.RepeatCount = 1; 190 | } 191 | 192 | public void AnimateRipple(MotionEvent ev) { 193 | CreateAnimation(ev.GetX(), ev.GetY()); 194 | } 195 | 196 | public void animateRipple(float x, float y) { 197 | CreateAnimation(x, y); 198 | } 199 | 200 | private void CreateAnimation(float x, float y) 201 | { 202 | if (!Enabled || _animationRunning) return; 203 | 204 | if (_hasToZoom) 205 | StartAnimation(_scaleAnimation); 206 | 207 | _radiusMax = Math.Max(_width, _height); 208 | 209 | if (_rippleType != 2) 210 | _radiusMax /= 2; 211 | 212 | _radiusMax -= _ripplePadding; 213 | 214 | if (_isCentered || _rippleType == 1) { 215 | _x = MeasuredHeight / 2; 216 | _y = MeasuredWidth / 2; 217 | } else { 218 | _x = x; 219 | _y = y; 220 | } 221 | 222 | _animationRunning = true; 223 | 224 | if (_rippleType == 1 && _originBitmap == null) 225 | _originBitmap = GetDrawingCache(true); 226 | 227 | Invalidate(); 228 | } 229 | 230 | public override bool OnTouchEvent(MotionEvent ev) 231 | { 232 | if (_gestureDetector.OnTouchEvent(ev)) 233 | { 234 | AnimateRipple (ev); 235 | SendClickEvent (false); 236 | } 237 | 238 | return true; 239 | } 240 | 241 | public override bool OnInterceptTouchEvent(MotionEvent ev) 242 | { 243 | OnTouchEvent (ev); 244 | return false; 245 | } 246 | 247 | private void SendClickEvent(bool isLongClick) 248 | { 249 | if (Parent is AdapterView) { 250 | AdapterView adapterView = (AdapterView) Parent; 251 | int position = adapterView.GetPositionForView(this); 252 | long id = adapterView.GetItemIdAtPosition(position); 253 | if (isLongClick) { 254 | if (adapterView.OnItemLongClickListener != null) 255 | adapterView.OnItemLongClickListener.OnItemLongClick(adapterView, this, position, id); 256 | } else { 257 | if (adapterView.OnItemClickListener != null) 258 | adapterView.OnItemClickListener.OnItemClick(adapterView, this, position, id); 259 | } 260 | } 261 | } 262 | 263 | private Bitmap GetCircleBitmap(int radius) 264 | { 265 | var output = Bitmap.CreateBitmap(_originBitmap.Width, _originBitmap.Height, Bitmap.Config.Argb8888); 266 | using (var canvas = new Canvas(output)) 267 | using (var paint = new Paint(PaintFlags.AntiAlias)) 268 | using (var rect = new Rect((int)(_x - radius), (int)(_y - radius), (int)(_x + radius), (int)(_y + radius))) 269 | { 270 | canvas.DrawARGB(0, 0, 0, 0); 271 | canvas.DrawCircle(_x, _y, radius, paint); 272 | 273 | paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.SrcIn)); 274 | canvas.DrawBitmap(_originBitmap, rect, rect, paint); 275 | 276 | return output; 277 | } 278 | } 279 | 280 | private class RippleGestureDetector : GestureDetector.SimpleOnGestureListener 281 | { 282 | RippleView rippleView; 283 | public RippleGestureDetector(RippleView rippleView) { 284 | this.rippleView = rippleView; 285 | } 286 | 287 | public override void OnLongPress (MotionEvent e) 288 | { 289 | base.OnLongPress (e); 290 | rippleView.AnimateRipple (e); 291 | rippleView.SendClickEvent (true); 292 | } 293 | 294 | public override bool OnSingleTapConfirmed(MotionEvent e) 295 | { 296 | return true; 297 | } 298 | 299 | public override bool OnSingleTapUp(MotionEvent e) 300 | { 301 | return true; 302 | } 303 | } 304 | } 305 | } --------------------------------------------------------------------------------