├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── ritik │ │ └── emojireactionview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── ritik │ │ │ └── emojireactionview │ │ │ ├── Feed.java │ │ │ ├── FeedAdapter.java │ │ │ ├── MainActivity.java │ │ │ ├── MyRecyclerView.java │ │ │ └── SimpleExample.java │ └── res │ │ ├── drawable-hdpi │ │ ├── baseline_image_white_18.png │ │ ├── baseline_image_white_24.png │ │ ├── baseline_image_white_36.png │ │ ├── baseline_image_white_48.png │ │ ├── outline_view_day_white_18.png │ │ ├── outline_view_day_white_24.png │ │ ├── outline_view_day_white_36.png │ │ └── outline_view_day_white_48.png │ │ ├── drawable-mdpi │ │ ├── baseline_image_white_18.png │ │ ├── baseline_image_white_24.png │ │ ├── baseline_image_white_36.png │ │ ├── baseline_image_white_48.png │ │ ├── outline_view_day_white_18.png │ │ ├── outline_view_day_white_24.png │ │ ├── outline_view_day_white_36.png │ │ └── outline_view_day_white_48.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xhdpi │ │ ├── baseline_image_white_18.png │ │ ├── baseline_image_white_24.png │ │ ├── baseline_image_white_36.png │ │ ├── baseline_image_white_48.png │ │ ├── outline_view_day_white_18.png │ │ ├── outline_view_day_white_24.png │ │ ├── outline_view_day_white_36.png │ │ └── outline_view_day_white_48.png │ │ ├── drawable-xxhdpi │ │ ├── baseline_image_white_18.png │ │ ├── baseline_image_white_24.png │ │ ├── baseline_image_white_36.png │ │ ├── baseline_image_white_48.png │ │ ├── outline_view_day_white_18.png │ │ ├── outline_view_day_white_24.png │ │ ├── outline_view_day_white_36.png │ │ └── outline_view_day_white_48.png │ │ ├── drawable-xxxhdpi │ │ ├── baseline_image_white_18.png │ │ ├── baseline_image_white_24.png │ │ ├── baseline_image_white_36.png │ │ ├── baseline_image_white_48.png │ │ ├── outline_view_day_white_18.png │ │ ├── outline_view_day_white_24.png │ │ ├── outline_view_day_white_36.png │ │ └── outline_view_day_white_48.png │ │ ├── drawable │ │ ├── baseline_image_24.xml │ │ ├── emoji1.png │ │ ├── emoji2.png │ │ ├── emoji3.png │ │ ├── emoji4.png │ │ ├── emoji5.png │ │ ├── emoji6.png │ │ ├── feed1.jpg │ │ ├── feed10.jpg │ │ ├── feed11.jpg │ │ ├── feed3.png │ │ ├── feed4.jpg │ │ ├── feed5.jpg │ │ ├── feed6.jpg │ │ ├── feed7.jpeg │ │ ├── feed8.jpg │ │ ├── feed9.jpg │ │ ├── ic_launcher_background.xml │ │ └── outline_view_day_24.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── feed.xml │ │ ├── my_recycler.xml │ │ └── simple.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── ritik │ └── emojireactionview │ └── ExampleUnitTest.java ├── build.gradle ├── emojireactionlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── ritik │ │ └── emojireactionlibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── ritik │ │ │ └── emojireactionlibrary │ │ │ ├── ClickInterface.java │ │ │ ├── EmojiReactionView.java │ │ │ └── RisingEmoji.java │ └── res │ │ ├── drawable │ │ └── home.png │ │ └── values │ │ ├── attrs.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── ritik │ └── emojireactionlibrary │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── sample ├── coverImage.png ├── recycler.gif └── simple.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ### Android ### 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | 28 | # Log Files 29 | *.log 30 | 31 | # Android Studio Navigation editor temp files 32 | .navigation/ 33 | 34 | # Android Studio captures folder 35 | captures/ 36 | 37 | # Intellij 38 | *.iml 39 | .idea/ 40 | 41 | # Keystore files 42 | *.jks 43 | 44 | # External native build folder generated in Android Studio 2.2 and later 45 | .externalNativeBuild 46 | 47 | # Google Services (e.g. APIs or Firebase) 48 | google-services.json 49 | 50 | ### Android Patch ### 51 | gen-external-apklibs -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | sudo: required 4 | 5 | android: 6 | components: 7 | - tools 8 | - platform-tools 9 | - tools 10 | - build-tools-27.0.3 11 | - android-27 12 | - extra-google-m2repository 13 | - extra-android-m2repository 14 | 15 | script: 16 | - ./gradlew build 17 | - ./gradlew test 18 | 19 | before_install: 20 | - chmod +x gradlew 21 | 22 | after_success: 23 | - python <(curl -s https://raw.githubusercontent.com/TouK/sputnik-ci/master/sputnik-ci.py) 24 | 25 | env: 26 | global: 27 | - secure: PIbHGVr+Bv0HbK6qOE6C0FrVqcsm/Q6kzFCOa4y9ixT8+2i82DDP4kyyy2ymKevmps+7+SCeJiW8KQkZa7gztSG0h1BoHJo0C6f0xiMYG4kY/7Gq4ZX3mehOVFUymxqhVED/NMK4a7JJxqcSH7JIkBLkuEaueqxc3CmHjI7LCqTr9yMdu/8ulhOeEL/Drg0zsNK9424K6BtxnTh6nNmbNfRnvxCgFc3mLuZ4J6/YN7lBagNiBhpr3XsXdvUC/W89UCcQCIkl/xBKPTxoUGxD6YG+IhapEJrQvqsFkvwFcsUUa9iL7+23QDlK7VGXeKZxwcMYWjRSVai3np94cHZwqivL1okoMFnIjqcAAzX5NOgd0VvM1dUqIwkXQDhp9IPGqDe/H1BiuRb8rmbJyRsxx5YjwksuPugDcG/B24qhyz4NM+gupMx0UE1DXS20xtE1kItEMzCyOJGXDwD9VR13ED0kYkcZoovPFdGFUOpAyAE9UYe1wDpDbmxF8o24tM5ICTcaATpiowWvBmS3i2qsEg8akpxmOqwWK//aOg2aNRiiX5we1H8QK8QNT0MoRf7B9bh59BHL6aOJ/jCeiYXb1jjWGQCGO9Vh3lzJWw2V9f2CvnUaZfeJOCzLgVPqtrI9E1LoPLiVT0Izx9DZ+aINrBxhNfndz5UZ4VQPHF8DDe4= -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to EmojiReactionView 2 | ========================== 3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: 4 | If you'd like to report a bug or join in the development 5 | of EmojiReactionView, then here are some notes on how to do that. 6 | 7 | ## Contents 8 | * [Reporting bugs and opening issues](#reporting-bugs-and-opening-issues) 9 | * [Coding Guidelines](#coding-guidelines) 10 | * [Pull Requests](#pull-requests) 11 | * [MVP architecture](#mvp-architecture) 12 | * [Style Check](#style-check) 13 | * [Git Commit Messages](#git-commit-messages) 14 | * [MDG Chat Room](#mdg-chat-room) 15 | * [Security](#security) 16 | 17 | ## Reporting bugs and opening issues 18 | 19 | If you'd like a report a bug or open an issue then please: 20 | 21 | **Check if there is an existing issue.** If there is then please add 22 | any more information that you have, or give it a 👍. 23 | 24 | When submitting an issue please describe the issue as clearly as possible, including how to 25 | reproduce the bug, which situations it appears in, what you expected to happen, and what actually happens. 26 | If you can include a screenshot for front end issues that is very helpful. 27 | 28 | ## Coding Guidelines 29 | 30 | ### Pull Requests 31 | We love pull requests, so be bold with them! Don't be afraid of going ahead 32 | and changing something, or adding a new feature. We're very happy to work with you 33 | to get your changes merged into EmojiReactionView. 34 | 35 | If you've got an idea for a change then please discuss it in the open first, 36 | either by opening an issue, or by joining us in our 37 | [MDG public chat room](https://mdg.sdslabs.co/chat). 38 | 39 | If you're looking for something to work on, have a look at the open issues in the repository [here](https://github.com/dev-ritik/EmojiReactionView/issues). 40 | 41 | > We don't have a set format for Pull requests, but we expect you to list changes, bugs generated and other relevant things in PR message. 42 | 43 | ### MVP architecture 44 | EmojiReactionView is built keeping [MVP (model-view-presenter)](https://en.wikipedia.org/wiki/Model–view–presenter) architecture in mind, so any changes that are proposed to EmojiReactionView should follow MVP architecture. If you are confused regarding where a method should be, join us at [MDG public chat room](https://mdg.sdslabs.co/chat), we'll be happy to help. 45 | 46 | ### Style Check 47 | EmojiReactionView uses Sputnik for performing style checks on the codebase, which helps us in maintaining the quality of the code. Sputnik checks for violation upon submission of Pull Requests. If Sputnik reports a violation and you believe that it is not applicable, just comment `N/A` on the sputnik review with the reason of why it is not applicable. **Pull Requests will only be merged once all the violations are resolved**. 48 | 49 | ### Git Commit Messages 50 | * Use the present tense ("Add feature" not "Added feature") 51 | * Use the imperative mood ("Move cursor to..." not "Moves cursor to...") 52 | * Limit the first line to 72 characters or less 53 | * Reference issues and pull requests liberally 54 | * When only changing documentation, include `[ci skip]` in the commit description 55 | * Consider starting the commit message with an applicable emoji: 56 | * :art: `:art:` when improving the format/structure of the code 57 | * :racehorse: `:racehorse:` when improving performance 58 | * :non-potable_water: `:non-potable_water:` when plugging memory leaks 59 | * :memo: `:memo:` when writing docs 60 | * :bug: `:bug:` when fixing a bug 61 | * :fire: `:fire:` when removing code or files 62 | * :green_heart: `:green_heart:` when fixing the CI build 63 | * :white_check_mark: `:white_check_mark:` when adding tests 64 | * :lock: `:lock:` when dealing with security 65 | * :arrow_up: `:arrow_up:` when upgrading dependencies 66 | * :arrow_down: `:arrow_down:` when downgrading dependencies 67 | * :shirt: `:shirt:` when removing linter warnings 68 | 69 | ## MDG Chat Room 70 | 71 | If you want to ask any questions in real-time, or get a feel for what's going on 72 | then please drop into our [MDG public chat room](https://mdg.sdslabs.co/chat). 73 | If no one is online then you can still leave a message that will hopefully get a reply 74 | when we return. 75 | 76 | ## Security 77 | 78 | Please do not publish security vulnerabilities publicly until we've had a chance 79 | to address them. All security related issues/patches should be sent directly to 80 | [sdsmobilelabs@gmail.com](mailto:sdsmobilelabs@gmail.com) where we will attempt to address them quickly. If you're 81 | unsure whether something is a security issue or not, then please be cautious and contact us at [sdsmobilelabs@gmail.com](mailto:sdsmobilelabs@gmail.com) first. 82 | 83 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ritik kumar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #
EmojiReactionView
2 | 3 |
4 | 5 | Platform 7 | 8 | 9 | API 11 | 12 | 13 | License: MIT 15 | 16 | 17 | Download 19 | 20 | 21 | Sputnik 23 | 24 | 25 | Build Status 27 | 28 |

29 | 30 | 31 | 32 |
An Android library to make Emoji Reactions on imageviews in a manner Instagram does this!.

33 | 34 | ___ 35 | # Table of contents 36 | 37 | * [Features](#features) 38 | * [Example](#example) 39 | * [Usage](#usage) 40 | * [Further customization](#further-customization) 41 | * [Public methods](#public-methods) 42 | * [Contributions](#contributions) 43 | * [License](#license) 44 | 45 | # Features 46 | - Design : The library tries to be reasonably close to the original Instagram's design. 47 | - Customization : Users can customize the look to a great extent easily and reliably. 48 | - Support for RecyclerView : It can easily be used with Recycler views. 49 | - Optimum performance : Efforts have been made to keep memory usage as small as possible. 50 | - Unharmed image : The library doesn't change/modify the image, so every modification of image as imageview is possible 51 | 52 | # Example 53 | Below is the two sample for usage of the library: 54 | 55 | 56 | 57 | 58 |
59 | 60 | # Usage 61 | Just add the following dependency in your app's `build.gradle` 62 | ```groovy 63 | repositories { 64 | maven { 65 | url 'https://dl.bintray.com/dev-ritik/EmojiReactionView/' 66 | } 67 | } 68 | 69 | dependencies { 70 | implementation 'com.ritik:emojireactionlibrary:1.0.2' 71 | } 72 | 73 | ``` 74 | 75 | Add the following code in your xml file 76 | ```xml 77 | 82 | ``` 83 | where `emoji` is an array resource which is the address to all emojis to be in the panel like: 84 | ```xml 85 | 86 | 87 | @drawable/em1 88 | @drawable/em2 89 | @drawable/em2 90 | 91 | ``` 92 | 93 | and for the home emoji, rename that to **home**, so that its resource id becomes `R.drawable.home` 94 | to override default home emoji originally set. 95 | 96 | To get notified of when the emojis are clicked, you can use: 97 | ```java 98 | myImage.setOnEmojiClickListener(new ClickInterface() { 99 | @Override 100 | public void onEmojiClicked(int emojiIndex, int x, int y) { 101 | // emojiIndex is the index of the emoji being clicked (0 based) 102 | // x,y are the coordinates of the clicked position relative to the image 103 | // (if x && y == -1 => changed by program(SetClickedEmojiNumber) 104 | } 105 | 106 | @Override 107 | public void onEmojiUnclicked(int emojiIndex, int x, int y) { 108 | // emojiIndex is the index of the emoji being clicked (0 based) 109 | // x,y are the coordinates of the clicked position relative to the image 110 | // (if x && y == -1 => changed by program(SetClickedEmojiNumber) 111 | } 112 | }); 113 | ``` 114 | 115 | **If you are struck somewhere, you can always check its usage in the sample app for [Simple](https://github.com/dev-ritik/EmojiReactionView/blob/master/app/src/main/java/com/ritik/emojireactionview/SimpleExample.java) 116 | and [RecyclerView](https://github.com/dev-ritik/EmojiReactionView/blob/master/app/src/main/java/com/ritik/emojireactionview/FeedAdapter.java) usage.** 117 | 118 | _With this all done and working, you have made to the default design!_ 119 | 120 | # Further customization 121 | The library provides these attributes to modify default design to a custom one: 122 | 123 | |Attribute |Description | Type(Range) |Default Value | 124 | |---------------------|------------------------------------------------------------|---------------------------------------------------|-------------------------------------| 125 | |emojis | Set the emojis to be displayed in the panel animation | reference | | 126 | |set_emoji | Set the current selected emoji | integer(>-1)(< noe*) (0 based) | -1 | 127 | |home_Center_X | Set the x coordinate of homeEmoji's center | dimensions | 30 * density | 128 | |home_Center_Y | Set the y coordinate of homeEmoji's center | dimensions | Height - 30 * density | 129 | |home_side | Set the side length of homeEmoji | dimensions | 50 * density | 130 | |panel_center_X | Set the x coordinate of the center of panel animation | `dimension` or `fraction` [0%,100%] (w.r.t width)#| width / 2 | 131 | |panel_center_Y | Set the y coordinate of the center of panel animation | `dimension` or `fraction` [0%,100%] (w.r.t height)| Height - emojiSide / 2 | 132 | |panel_radius | Set the radius of panel animation | dimension | min(Height,Width) / 2 - 20 * density| 133 | |panel_emoji_side | Set the side of emojis on the panel | dimension | 50 * density | 134 | |emojis_rising_height | Set the height of the rising emojis(to start disappearing) | `fraction` [0%,100%] (w.r.t height)# | Height / 2 | 135 | |emojis_rising_speed | Set the speed per frame of the rising emojis | dimension | 10 * density | 136 | |emojis_rising_number | Set the number of emojis rising in rising emojis animation | integer | 24 | 137 | 138 | *noe = number of emojis.
139 | *#* measurement from bottom 140 | # Public methods 141 | 142 | |Method |Description |Data Type | 143 | |-------------------------|----------------------------------------------|----------------------------| 144 | |getCentre | Get the center of panel animation | int(Pixels) | 145 | |getRadius | Get the radius of panel animation | int(Pixels) | 146 | |get/SetClickedEmojiNumber| Get/Set the current selected emoji | int (-1 for none)(0 based) | 147 | |getNumberOfEmojis | Get the number Of emojis in the panel | int | 148 | |getEmojisRisingSpeed | Get the speed per frame of the rising emojis | int(Pixels) | 149 | |getHomeRect | Get the Rect of the home emoji | Rect | 150 | |getPanelEmojiSide | Get the side of emojis on the panel | int(Pixels) | 151 | |get/SetHomeBitmap | Get/Set the bitmap of the home emoji | Bitmap | 152 | |isHomeEmojiVisible | Is home emoji visible | boolean | 153 | |isPanelAnimWorking | Is panel visible | boolean | 154 | |isClickingAnimWorking | Is the clicking animation working | boolean | 155 | |isEmojiRising | Is emoji rising animation visible | boolean | 156 | |setHomeEmojiVisible | Switch to home bitmap visible mode | boolean | 157 | |setPanelAnimWorking | Start the panel animation | boolean | 158 | 159 | # Contributions 160 | 161 | All contributions are welcome and appreciated. Please make a Pull Request or open an issue, if necessary. 162 | This may also include any form of feature enhancement. Every constructive criticism is welcome. 163 | See [Contributing.md](https://github.com/dev-ritik/EmojiReactionView/blob/master/CONTRIBUTING.md) 164 | 165 | # License 166 | This library is licensed under `MIT license`. View [license](LICENSE). 167 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.ritik.emojireactionview" 7 | minSdkVersion 19 8 | targetSdkVersion 27 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | vectorDrawables.useSupportLibrary = true 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation 'com.android.support:appcompat-v7:27.1.1' 25 | implementation 'com.android.support:design:27.1.1' 26 | implementation 'com.android.support.constraint:constraint-layout:1.1.2' 27 | testImplementation 'junit:junit:4.12' 28 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 29 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 30 | 31 | implementation 'com.android.support:recyclerview-v7:27.1.1' 32 | implementation 'com.android.support:cardview-v7:27.1.1' 33 | 34 | implementation project(path: ':emojireactionlibrary') 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/ritik/emojireactionview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.ritik.emojireactionview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/ritik/emojireactionview/Feed.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | /** 4 | * This class is the object for displaying sample feeds 5 | */ 6 | 7 | class Feed { 8 | private String name; 9 | private int picAddress; 10 | private String time; 11 | private String message; 12 | private int clickedEmoji; 13 | 14 | Feed(String name, int picAddress, String time, String message, int clickedEmoji) { 15 | this.name = name; 16 | this.picAddress = picAddress; 17 | this.time = time; 18 | this.message = message; 19 | this.clickedEmoji = clickedEmoji; 20 | } 21 | 22 | public int getClickedEmoji() { 23 | return clickedEmoji; 24 | } 25 | 26 | public void setClickedEmoji(int clickedEmoji) { 27 | this.clickedEmoji = clickedEmoji; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public int getPicAddress() { 39 | return picAddress; 40 | } 41 | 42 | public void setPicAddress(int picAddress) { 43 | this.picAddress = picAddress; 44 | } 45 | 46 | public String getTime() { 47 | return time; 48 | } 49 | 50 | public void setTime(String time) { 51 | this.time = time; 52 | } 53 | 54 | public String getMessage() { 55 | return message; 56 | } 57 | 58 | public void setMessage(String message) { 59 | this.message = message; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/ritik/emojireactionview/FeedAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.TextView; 11 | import android.widget.Toast; 12 | 13 | import com.ritik.emojireactionlibrary.ClickInterface; 14 | import com.ritik.emojireactionlibrary.EmojiReactionView; 15 | 16 | import java.util.ArrayList; 17 | 18 | /** 19 | * This class is the adapter for displaying sample feeds 20 | */ 21 | 22 | public class FeedAdapter extends RecyclerView.Adapter { 23 | private ArrayList mDataSet; 24 | private Context context; 25 | 26 | class ViewHolder extends RecyclerView.ViewHolder { 27 | TextView messageTextView, timeTextView, name; 28 | // ImageView photo; 29 | EmojiReactionView photo; 30 | 31 | private ViewHolder(View view) { 32 | super(view); 33 | photo = view.findViewById(R.id.photoImageView); 34 | messageTextView = view.findViewById(R.id.messageTextView); 35 | 36 | timeTextView = view.findViewById(R.id.time); 37 | name = view.findViewById(R.id.name); 38 | } 39 | } 40 | 41 | // Provide a suitable constructor (depends on the kind of dataset) 42 | FeedAdapter(ArrayList myDataSet) { 43 | mDataSet = myDataSet; 44 | } 45 | 46 | // Create new views (invoked by the layout manager) 47 | @NonNull 48 | @Override 49 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, 50 | int viewType) { 51 | // create a new view 52 | // Log.i("point fa50","create"); 53 | View v = LayoutInflater.from(parent.getContext()) 54 | .inflate(R.layout.feed, parent, false); 55 | this.context = parent.getContext(); 56 | return new ViewHolder(v); 57 | } 58 | //TODO open and close circle anim on view creation 59 | 60 | @Override 61 | public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) { 62 | // - get element from your dataSet at this position 63 | // - replace the contents of the view with that element 64 | // Log.i("point fa50","bind"); 65 | final Feed feed = mDataSet.get(position); 66 | 67 | holder.photo.setImageResource(feed.getPicAddress()); 68 | holder.photo.setHomeEmojiVisible(); 69 | holder.photo.setOnEmojiClickListener(new ClickInterface() { 70 | @Override 71 | public void onEmojiClicked(int emojiIndex, int x, int y) { 72 | String message; 73 | if (x != -1) { 74 | switch (emojiIndex) { 75 | case 0: 76 | message = " Great!! "; 77 | break; 78 | case 1: 79 | message = " Hehe "; 80 | break; 81 | case 2: 82 | message = " Loved... "; 83 | break; 84 | case 3: 85 | message = " Shocked!! "; 86 | break; 87 | case 4: 88 | message = " Sad... "; 89 | break; 90 | case 5: 91 | message = " Lit!! "; 92 | break; 93 | default: 94 | message = " ** "; 95 | } 96 | Toast.makeText(context,message, Toast.LENGTH_SHORT).show(); 97 | } 98 | feed.setClickedEmoji(emojiIndex); 99 | } 100 | 101 | @Override 102 | public void onEmojiUnclicked(int emojiIndex, int x, int y) { 103 | // if (x != -1) 104 | // Toast.makeText(context, "Emoji " + emojiIndex +" removed", Toast.LENGTH_SHORT).show(); 105 | } 106 | }); 107 | 108 | // always after listener for changes 109 | holder.photo.setClickedEmojiNumber(feed.getClickedEmoji()); 110 | 111 | // holder.photo.setOnClickListener(new View.OnClickListener() { 112 | // @Override 113 | // public void onClick(View view) { 114 | // Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show(); 115 | // } 116 | // }); 117 | 118 | holder.messageTextView.setText(feed.getMessage()); 119 | holder.timeTextView.setText(feed.getTime()); 120 | holder.name.setText(feed.getName()); 121 | 122 | } 123 | 124 | // Return the size of your dataSet (invoked by the layout manager) 125 | @Override 126 | public int getItemCount() { 127 | return mDataSet.size(); 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /app/src/main/java/com/ritik/emojireactionview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.TabLayout; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentManager; 7 | import android.support.v4.app.FragmentPagerAdapter; 8 | import android.support.v4.view.ViewPager; 9 | import android.support.v7.app.AppCompatActivity; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | 16 | private TabLayout tabLayout; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_main); 22 | 23 | setupViewPager((ViewPager) findViewById(R.id.viewpager)); 24 | 25 | tabLayout = (TabLayout) findViewById(R.id.tabs); 26 | tabLayout.setupWithViewPager((ViewPager) findViewById(R.id.viewpager)); 27 | 28 | setupTabIcons(); 29 | } 30 | 31 | private void setupTabIcons() { 32 | tabLayout.getTabAt(0).setIcon(R.drawable.baseline_image_24); 33 | tabLayout.getTabAt(1).setIcon(R.drawable.outline_view_day_24); 34 | } 35 | 36 | private void setupViewPager(ViewPager viewPager) { 37 | ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); 38 | adapter.addFragment(new SimpleExample(), "Simple"); 39 | adapter.addFragment(new MyRecyclerView(), "Recycler view"); 40 | viewPager.setAdapter(adapter); 41 | } 42 | 43 | class ViewPagerAdapter extends FragmentPagerAdapter { 44 | private final List mFragmentList = new ArrayList<>(); 45 | private final List mFragmentTitleList = new ArrayList<>(); 46 | 47 | ViewPagerAdapter(FragmentManager manager) { 48 | super(manager); 49 | } 50 | 51 | @Override 52 | public Fragment getItem(int position) { 53 | return mFragmentList.get(position); 54 | } 55 | 56 | @Override 57 | public int getCount() { 58 | return mFragmentList.size(); 59 | } 60 | 61 | void addFragment(Fragment fragment, String title) { 62 | mFragmentList.add(fragment); 63 | mFragmentTitleList.add(title); 64 | } 65 | 66 | @Override 67 | public CharSequence getPageTitle(int position) { 68 | return mFragmentTitleList.get(position); 69 | } 70 | } 71 | // 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/ritik/emojireactionview/MyRecyclerView.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import java.util.ArrayList; 13 | 14 | public class MyRecyclerView extends Fragment { 15 | 16 | public static RecyclerView.Adapter mAdapter; 17 | ArrayList feeds; 18 | 19 | public MyRecyclerView() { 20 | // Required empty public constructor 21 | } 22 | 23 | @Override 24 | public void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | } 27 | 28 | @Override 29 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 30 | Bundle savedInstanceState) { 31 | // Inflate the layout for this fragment 32 | View view = inflater.inflate(R.layout.my_recycler, container, false); 33 | 34 | RecyclerView mRecyclerView = view.findViewById(R.id.my_recycler_view); 35 | // mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL)); 36 | feeds = new ArrayList<>(); 37 | 38 | mAdapter = new FeedAdapter(feeds); 39 | 40 | feeds.add(new Feed("Adam", R.drawable.feed8, "Nov 6,11:52 AM", "The journey not the arrival matters.", -1)); 41 | feeds.add(new Feed("Alina", R.drawable.feed9, "Nov 6,11:52 AM", "Just living is not enough...", -1)); 42 | feeds.add(new Feed("James", R.drawable.feed4, "Nov 6,11:52 AM", "The dog is the perfect portrait subject. He doesn't pose. He isn't aware of the camera.", -1)); 43 | feeds.add(new Feed("Emily", R.drawable.feed10, "Nov 6,11:52 AM", "Dream as if you’ll live forever, live as if you’ll die today.", -1)); 44 | feeds.add(new Feed("Moore", R.drawable.feed3, "Nov 6,11:52 AM", "Quotes .... truth!! life", -1)); 45 | feeds.add(new Feed("Thomson", R.drawable.feed5, "Nov 6,11:52 AM", "I spent 90 percent of my money on women and drink. The rest I wasted!", -1)); 46 | feeds.add(new Feed("William", R.drawable.feed6, "Nov 6,11:52 AM", "Music is my medicine!!", -1)); 47 | feeds.add(new Feed("Olivia", R.drawable.feed7, "Nov 6,11:52 AM", "It's refreshing to have some time off from wondering whether I look fat.", -1)); 48 | feeds.add(new Feed("Sophia", R.drawable.feed1, "Nov 6,11:52 AM", "Adventure may hurt you but monotony will kill you.", -1)); 49 | mRecyclerView.setAdapter(mAdapter); 50 | 51 | mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 52 | 53 | return view; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/ritik/emojireactionview/SimpleExample.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Toast; 10 | 11 | import com.ritik.emojireactionlibrary.ClickInterface; 12 | import com.ritik.emojireactionlibrary.EmojiReactionView; 13 | 14 | public class SimpleExample extends Fragment { 15 | 16 | EmojiReactionView myImage; 17 | int clickedEmoji = 0; 18 | 19 | public SimpleExample() { 20 | // Required empty public constructor 21 | } 22 | 23 | @Override 24 | public void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | } 27 | 28 | @Override 29 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 30 | Bundle savedInstanceState) { 31 | // Inflate the layout for this fragment 32 | View view = inflater.inflate(R.layout.simple, container, false); 33 | myImage = view.findViewById(R.id.image); 34 | if (savedInstanceState != null) { 35 | clickedEmoji = savedInstanceState.getInt("emojiNumber"); 36 | myImage.setClickedEmojiNumber(clickedEmoji); 37 | } 38 | // 39 | // myImage.setOnClickListener(new View.OnClickListener() { 40 | // @Override 41 | // public void onClick(View v) { 42 | // Toast.makeText(getActivity(), "clicked!!", Toast.LENGTH_SHORT).show(); 43 | // } 44 | // }); 45 | 46 | myImage.setOnEmojiClickListener(new ClickInterface() { 47 | @Override 48 | public void onEmojiClicked(int emojiIndex, int x, int y) { 49 | String message; 50 | if (x != -1) { 51 | switch (emojiIndex) { 52 | case 0: 53 | message = " Great!! "; 54 | break; 55 | case 1: 56 | message = " Hehe "; 57 | break; 58 | case 2: 59 | message = " Loved... "; 60 | break; 61 | case 3: 62 | message = " Shocked!! "; 63 | break; 64 | case 4: 65 | message = " Sad... "; 66 | break; 67 | case 5: 68 | message = " Lit!! "; 69 | break; 70 | default: 71 | message = " ** "; 72 | } 73 | Toast.makeText(getActivity(),message, Toast.LENGTH_SHORT).show(); 74 | } 75 | clickedEmoji = emojiIndex; 76 | } 77 | 78 | @Override 79 | public void onEmojiUnclicked(int emojiIndex, int x, int y) { 80 | // if (x != -1) 81 | // Toast.makeText(getActivity(), "Emoji " + emojiIndex +" removed", Toast.LENGTH_SHORT).show(); 82 | } 83 | }); 84 | return view; 85 | 86 | } 87 | 88 | @Override 89 | public void onSaveInstanceState(@NonNull Bundle outState) { 90 | outState.putInt("emojiNumber", clickedEmoji); 91 | super.onSaveInstanceState(outState); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/baseline_image_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/baseline_image_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/baseline_image_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/baseline_image_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/baseline_image_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/baseline_image_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/baseline_image_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/baseline_image_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/outline_view_day_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/outline_view_day_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/outline_view_day_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/outline_view_day_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/outline_view_day_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/outline_view_day_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/outline_view_day_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-hdpi/outline_view_day_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/baseline_image_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/baseline_image_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/baseline_image_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/baseline_image_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/baseline_image_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/baseline_image_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/baseline_image_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/baseline_image_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/outline_view_day_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/outline_view_day_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/outline_view_day_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/outline_view_day_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/outline_view_day_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/outline_view_day_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/outline_view_day_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-mdpi/outline_view_day_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/baseline_image_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/baseline_image_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/baseline_image_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/baseline_image_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/baseline_image_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/baseline_image_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/baseline_image_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/baseline_image_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/outline_view_day_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/outline_view_day_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/outline_view_day_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/outline_view_day_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/outline_view_day_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/outline_view_day_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/outline_view_day_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xhdpi/outline_view_day_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/baseline_image_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/baseline_image_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/baseline_image_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/baseline_image_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/baseline_image_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/baseline_image_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/baseline_image_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/baseline_image_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/outline_view_day_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/outline_view_day_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/outline_view_day_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/outline_view_day_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/outline_view_day_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/outline_view_day_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/outline_view_day_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxhdpi/outline_view_day_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/baseline_image_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/baseline_image_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/baseline_image_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/baseline_image_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/baseline_image_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/baseline_image_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/baseline_image_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/baseline_image_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/outline_view_day_white_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/outline_view_day_white_18.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/outline_view_day_white_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/outline_view_day_white_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/outline_view_day_white_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/outline_view_day_white_36.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/outline_view_day_white_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable-xxxhdpi/outline_view_day_white_48.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_image_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/emoji6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/emoji6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed10.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed11.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed4.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed6.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed7.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed8.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/feed9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/drawable/feed9.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/outline_view_day_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 18 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 24 | 25 | 30 | 31 | 41 | 42 | 51 | 52 | 53 | 54 | 60 | 61 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /app/src/main/res/layout/my_recycler.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/simple.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #125688 4 | #125688 5 | #FFFFFF 6 | #FFFFFF 7 | #000000 8 | #c8e8ff 9 | #6200EA 10 | #4E342E 11 | #757575 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 264dp 6 | 16dp 7 | 14sp 8 | 72dp 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | EmojiReactionView 3 | 4 | 5 | @drawable/emoji1 6 | @drawable/emoji2 7 | @drawable/emoji3 8 | @drawable/emoji4 9 | @drawable/emoji5 10 | @drawable/emoji6 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 14 | 15 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/test/java/com/ritik/emojireactionview/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionview; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.1.4' 11 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 13 | 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | google() 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /emojireactionlibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /emojireactionlibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | ext { 4 | bintrayRepo = 'EmojiReactionView' 5 | bintrayName = 'EmojiReactionView' 6 | 7 | publishedGroupId = 'com.ritik' 8 | libraryName = 'EmojiReactionView' 9 | artifact = 'emojireactionlibrary' 10 | 11 | libraryDescription = 'An Android library to make Emoji Reactions on imageviews in a manner Instagram does this!' 12 | 13 | siteUrl = 'https://github.com/dev-ritik/EmojiReactionView' 14 | gitUrl = 'https://github.com/dev-ritik/EmojiReactionView.git' 15 | 16 | libraryVersion = '1.0.2' 17 | 18 | developerId = 'dev-ritik' 19 | developerName = 'Ritik Kumar' 20 | developerEmail = 'ritikkne@gmail.com' 21 | 22 | licenseName = 'The MIT License' 23 | licenseUrl = 'https://opensource.org/licenses/MIT' 24 | allLicenses = ["MIT"] 25 | } 26 | 27 | android { 28 | compileSdkVersion 27 29 | 30 | defaultConfig { 31 | minSdkVersion 19 32 | targetSdkVersion 27 33 | versionCode 1 34 | versionName "1.0" 35 | 36 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 37 | 38 | } 39 | 40 | buildTypes { 41 | release { 42 | minifyEnabled false 43 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 44 | } 45 | } 46 | 47 | } 48 | 49 | dependencies { 50 | implementation fileTree(dir: 'libs', include: ['*.jar']) 51 | 52 | implementation 'com.android.support:appcompat-v7:27.1.1' 53 | testImplementation 'junit:junit:4.12' 54 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 55 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 56 | } 57 | 58 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle' 59 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle' -------------------------------------------------------------------------------- /emojireactionlibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/androidTest/java/com/ritik/emojireactionlibrary/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionlibrary; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.ritik.emojireactionlibrary.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/java/com/ritik/emojireactionlibrary/ClickInterface.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionlibrary; 2 | 3 | /** 4 | * Click interface for the EmojiReactionView. 5 | */ 6 | public interface ClickInterface { 7 | 8 | void onEmojiClicked(int emojiIndex,int x, int y); 9 | 10 | void onEmojiUnclicked(int emojiIndex,int x, int y); 11 | 12 | } -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/java/com/ritik/emojireactionlibrary/EmojiReactionView.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionlibrary; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.animation.ValueAnimator; 6 | import android.annotation.SuppressLint; 7 | import android.app.Activity; 8 | import android.content.Context; 9 | import android.content.res.TypedArray; 10 | import android.graphics.Bitmap; 11 | import android.graphics.Canvas; 12 | import android.graphics.Color; 13 | import android.graphics.Matrix; 14 | import android.graphics.Paint; 15 | import android.graphics.Path; 16 | import android.graphics.PathMeasure; 17 | import android.graphics.Rect; 18 | import android.graphics.drawable.ColorDrawable; 19 | import android.graphics.drawable.Drawable; 20 | import android.util.AttributeSet; 21 | import android.util.Log; 22 | import android.view.MotionEvent; 23 | import android.view.animation.AccelerateInterpolator; 24 | import android.widget.ImageView; 25 | 26 | import java.util.ArrayList; 27 | import java.util.Random; 28 | import java.util.Timer; 29 | import java.util.TimerTask; 30 | 31 | import static android.util.TypedValue.TYPE_DIMENSION; 32 | 33 | /** 34 | * This class does all the background work related to displaying emoji on the canvas 35 | */ 36 | 37 | public class EmojiReactionView extends android.support.v7.widget.AppCompatImageView { 38 | 39 | /// General variables 40 | 41 | // Click interface for emoji click 42 | private ClickInterface mClickInterface; 43 | // Array of emoji bitmaps 44 | private Bitmap[] emojiBitmap; 45 | // Index of the selected bitmap 46 | private int clickedEmojiNumber = -1; 47 | // Total number of emoji bitmaps 48 | private int numberOfEmojis = 0; 49 | // ArrayList containing all emoji ids to be displayed 50 | private ArrayList emojiId = new ArrayList<>(); 51 | // Activity context 52 | private Context context; 53 | // Density factor 54 | private final float densityFactor = getResources().getDisplayMetrics().density; 55 | // Variable for getting the dimension height or width, whichever is smaller 56 | private int smallerDimension; 57 | // boolean to declare if a touch gesture was a swipe 58 | private boolean wasSwiping = false; 59 | // boolean to declare if a touch gesture was a swipe and started from an emoji on panel 60 | private boolean emojiClicked = false; 61 | 62 | /// Home emoji variables 63 | 64 | // Home emoji rect variable 65 | private Rect homeRect = new Rect(); 66 | // Length of side of home rect 67 | private int homeSide = (int) (50 * densityFactor); 68 | // Home emoji center 69 | private int[] homeCenter = new int[]{(int) (30 * densityFactor), 0}; 70 | // Raw home emoji center Y coordinate given by the user 71 | private float homeCenterYGiven = -1; 72 | // Home emoji bitmap 73 | private Bitmap homeBitmap; 74 | // Boolean to make home emoji visible 75 | private boolean homeEmojiVisible; 76 | 77 | //TODO: can be improved in landscape mode!! 78 | /// Circular Animation Variables 79 | 80 | // Panel center 81 | private int[] panelCentre = new int[2]; 82 | // Raw panel center given by user 83 | private float[] panelCentreGiven = new float[]{-2, -2}; 84 | // Panel radius variable 85 | private int panelRadius; 86 | // Raw panel radius variable given by user 87 | private int panelRadiusGiven = -1; 88 | // Emoji icon side length 89 | private int panelEmojiSide = (int) (50 * densityFactor); 90 | // Coordinates for emoji translation 91 | private int[][] emojiMovingPoint; 92 | // Variable used to measure the length of a path, and/or to find the position and tangent along it 93 | private PathMeasure[] pms; 94 | // Boolean checks whether animation is working or not 95 | private boolean panelAnimWorking; 96 | // Matrix is used emojis that are present in circular reveal as there is a rotating animation for them 97 | private Matrix[] emojiMatrix; 98 | int iCurStep = 20;// current step 99 | int iCurStepTaken = 0;// current steps total 100 | 101 | /// Variables for clicking and un-clicking gesture detection 102 | 103 | // Radius for defining clicked region radius 104 | private int clickedRadius; 105 | // Paint object for creating a white background around the emoji when clicked 106 | private Paint clickedPaint = new Paint(); 107 | // Boolean to check that click animation is working or not 108 | private boolean clickingAnimWorking; 109 | 110 | /// RisingEmoji 111 | 112 | // speed per frame of the rising emojis 113 | private int emojisRisingSpeed = (int) (10 * densityFactor); 114 | // height of the rising emojis(to start disappearing) 115 | private int emojisRisingHeight; 116 | // raw height of the rising emojis(to start disappearing) given by user 117 | private float emojisRisingHeightGiven = -2; 118 | // Arraylist storing properties of rising emojis 119 | private ArrayList risingEmojis = new ArrayList<>(); 120 | // Total number of emojis rising 121 | private int numberOfRisers = 24; 122 | // Boolean to check if emojis are rising 123 | private boolean emojiRising; 124 | // Timer to rise emojis continuously 125 | private Timer emojiRisingTimer; 126 | // Variable to count number of emojis started disappearing 127 | private int fading = 0; 128 | // is the emojis started disappearing 129 | private boolean startFading = false; 130 | 131 | public EmojiReactionView(Context context) { 132 | super(context); 133 | init(); 134 | } 135 | 136 | public EmojiReactionView(Context context, AttributeSet attrs) { 137 | this(context, attrs, 0); 138 | } 139 | 140 | public EmojiReactionView(Context context, AttributeSet attrs, int defStyle) { 141 | super(context, attrs, defStyle); 142 | this.context = context; 143 | // extract data from attributes 144 | this.initBaseXMLAttrs(context, attrs); 145 | 146 | init(); 147 | } 148 | 149 | final void initBaseXMLAttrs(Context context, AttributeSet attrs) { 150 | final TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.EmojiReactionView); 151 | 152 | // Log.i("point 152", "attrs" ); 153 | final int N = arr.getIndexCount(); 154 | for (int i = 0; i < N; ++i) { 155 | int attr = arr.getIndex(i); 156 | 157 | if (attr == R.styleable.EmojiReactionView_emojis) { 158 | final TypedArray resourceArray = context.getResources().obtainTypedArray(arr.getResourceId(R.styleable.EmojiReactionView_emojis, 0)); 159 | // Get emojis id from attribute and store it in arraylist 160 | for (int j = 0; j < resourceArray.length(); j++) { 161 | emojiId.add(resourceArray.getResourceId(j, 0)); 162 | } 163 | numberOfEmojis = emojiId.size(); 164 | resourceArray.recycle(); 165 | 166 | } else if (attr == R.styleable.EmojiReactionView_set_emoji) { 167 | clickedEmojiNumber = arr.getInt(attr, clickedEmojiNumber); 168 | } else if (attr == R.styleable.EmojiReactionView_home_Center_X) { 169 | homeCenter[0] = arr.getDimensionPixelSize(attr, homeCenter[0]); 170 | 171 | } else if (attr == R.styleable.EmojiReactionView_home_Center_Y) { 172 | homeCenterYGiven = arr.getDimensionPixelSize(attr, -1); 173 | 174 | } else if (attr == R.styleable.EmojiReactionView_home_side) { 175 | homeSide = arr.getDimensionPixelSize(attr, homeSide); 176 | 177 | } else if (attr == R.styleable.EmojiReactionView_panel_center_X) { 178 | if (arr.peekValue(attr).type == TYPE_DIMENSION) 179 | panelCentreGiven[0] = arr.getDimensionPixelSize(attr, -2); 180 | else { 181 | panelCentreGiven[0] = checkFraction(arr.getFraction(attr, -1, -1, -2)); 182 | } 183 | } else if (attr == R.styleable.EmojiReactionView_panel_center_Y) { 184 | if (arr.peekValue(attr).type == TYPE_DIMENSION) 185 | panelCentreGiven[1] = arr.getDimensionPixelSize(attr, -2); 186 | else 187 | panelCentreGiven[1] = checkFraction(arr.getFraction(attr, -1, -1, -2)); 188 | } else if (attr == R.styleable.EmojiReactionView_panel_radius) { 189 | panelRadiusGiven = arr.getDimensionPixelSize(attr, -1); 190 | 191 | } else if (attr == R.styleable.EmojiReactionView_panel_emoji_side) { 192 | panelEmojiSide = arr.getDimensionPixelSize(attr, panelEmojiSide); 193 | 194 | } else if (attr == R.styleable.EmojiReactionView_emojis_rising_height) { 195 | emojisRisingHeightGiven = checkFraction(arr.getFraction(attr, -1, -1, -2)); 196 | } else if (attr == R.styleable.EmojiReactionView_emojis_rising_speed) { 197 | emojisRisingSpeed = arr.getDimensionPixelSize(attr, -1); 198 | 199 | } else if (attr == R.styleable.EmojiReactionView_emojis_rising_number) { 200 | numberOfRisers = arr.getInt(attr, numberOfRisers); 201 | } 202 | } 203 | if (clickedEmojiNumber >= numberOfEmojis || clickedEmojiNumber < -1) { 204 | throw new IllegalArgumentException("set_emoji can't be more than number of emojis!"); 205 | } 206 | 207 | arr.recycle(); 208 | numberOfEmojis = emojiId.size(); 209 | emojiBitmap = new Bitmap[numberOfEmojis]; 210 | 211 | } 212 | 213 | private float checkFraction(float input) { 214 | // Check that percents entered is within [0% 100%] 215 | if (input == -2 || (input >= -1 && input <= 0)) { 216 | return input; 217 | } else throw new IllegalArgumentException(); 218 | } 219 | 220 | public int[] getCentre() { 221 | return panelCentre; 222 | } 223 | 224 | public float getRadius() { 225 | return panelRadius; 226 | } 227 | 228 | public int getClickedEmojiNumber() { 229 | return clickedEmojiNumber; 230 | } 231 | 232 | public void setClickedEmojiNumber(int clickedEmojiNumber) { 233 | // Set the currently selected emoji with immediate effect 234 | if (mClickInterface != null) 235 | 236 | if (clickedEmojiNumber == -1) { 237 | mClickInterface.onEmojiUnclicked(clickedEmojiNumber, -1, -1); 238 | } else if (this.clickedEmojiNumber == clickedEmojiNumber) { 239 | mClickInterface.onEmojiUnclicked(this.clickedEmojiNumber, -1, -1); 240 | 241 | } else if (clickedEmojiNumber >= 0 && clickedEmojiNumber < numberOfEmojis) { 242 | mClickInterface.onEmojiUnclicked(this.clickedEmojiNumber, -1, -1); 243 | mClickInterface.onEmojiClicked(clickedEmojiNumber, -1, -1); 244 | } else throw new IllegalArgumentException("clickedEmojiNumber out of range"); 245 | 246 | this.clickedEmojiNumber = clickedEmojiNumber; 247 | // Get the Emoji to be displayed in Bitmap 248 | if (emojiBitmap == null) emojiBitmap = new Bitmap[numberOfEmojis]; 249 | if (clickedEmojiNumber != -1 && emojiBitmap[clickedEmojiNumber] == null) 250 | emojiBitmap[clickedEmojiNumber] = getBitmapFromId(emojiId.get(clickedEmojiNumber), panelEmojiSide); 251 | invalidate(); 252 | } 253 | 254 | public int getNumberOfEmojis() { 255 | return numberOfEmojis; 256 | } 257 | 258 | public int getEmojisRisingSpeed() { 259 | return emojisRisingSpeed; 260 | } 261 | 262 | public Rect getHomeRect() { 263 | return homeRect; 264 | } 265 | 266 | public int getPanelEmojiSide() { 267 | return panelEmojiSide; 268 | } 269 | 270 | public Bitmap getHomeBitmap() { 271 | return homeBitmap; 272 | } 273 | 274 | public void setHomeBitmap(Bitmap homeBitmap) { 275 | this.homeBitmap = homeBitmap; 276 | } 277 | 278 | public boolean isHomeEmojiVisible() { 279 | return homeEmojiVisible; 280 | } 281 | 282 | public boolean isPanelAnimWorking() { 283 | return panelAnimWorking; 284 | } 285 | 286 | public boolean isClickingAnimWorking() { 287 | return clickingAnimWorking; 288 | } 289 | 290 | public boolean isEmojiRising() { 291 | return emojiRising; 292 | } 293 | 294 | public void setHomeEmojiVisible() { 295 | // Make the home emoji visible 296 | if (emojiRising) { 297 | emojiRising = false; 298 | if (emojiRisingTimer != null) { 299 | emojiRisingTimer.cancel(); 300 | emojiRisingTimer.purge(); 301 | emojiRisingTimer = null; 302 | } 303 | fading = 0; 304 | startFading = false; 305 | if (risingEmojis.size() != 0) risingEmojis.clear(); 306 | } 307 | homeEmojiVisible = true; 308 | panelAnimWorking = false; 309 | clickingAnimWorking = false; 310 | setColorFilter(Color.rgb(255, 255, 255), android.graphics.PorterDuff.Mode.MULTIPLY); 311 | } 312 | 313 | public void setPanelAnimWorking() { 314 | // Start Circular animation 315 | 316 | if (emojiMatrix == null) return; 317 | 318 | if (emojiRising) { 319 | emojiRising = false; 320 | if (emojiRisingTimer != null) { 321 | emojiRisingTimer.cancel(); 322 | emojiRisingTimer.purge(); 323 | emojiRisingTimer = null; 324 | } 325 | fading = 0; 326 | startFading = false; 327 | if (risingEmojis.size() != 0) risingEmojis.clear(); 328 | } 329 | 330 | panelAnimWorking = true; 331 | homeEmojiVisible = false; 332 | clickingAnimWorking = false; 333 | invalidate(); 334 | } 335 | 336 | public void setOnEmojiClickListener(ClickInterface l) { 337 | // Set the listener to the clickedEmojiNumber 338 | this.mClickInterface = l; 339 | } 340 | 341 | private void init() { 342 | // Log.i("point 343", "init " + getWidth()); 343 | 344 | // The paint which dims the background on circular animation 345 | clickedPaint.setColor(Color.argb(150, 185, 185, 185)); 346 | 347 | // Get the Emoji to be displayed in Bitmap 348 | if (clickedEmojiNumber != -1) { 349 | emojiBitmap[clickedEmojiNumber] = getBitmapFromId(emojiId.get(clickedEmojiNumber), panelEmojiSide); 350 | } 351 | 352 | setup(); 353 | } 354 | 355 | private void setup() { 356 | // Log.i("point 357", "setup" + getWidth() + " "); 357 | if (emojiId == null) { 358 | return; 359 | } 360 | if (numberOfEmojis == 0) { 361 | homeEmojiVisible = false; 362 | panelAnimWorking = false; 363 | clickingAnimWorking = false; 364 | emojiRising = false; 365 | return; 366 | } 367 | 368 | if (getWidth() == 0 && getHeight() == 0) { 369 | return; 370 | } else { 371 | smallerDimension = getHeight() > getWidth() ? getWidth() : getHeight(); 372 | } 373 | 374 | // set emojisRisingHeight based on user data 375 | if (emojisRisingHeightGiven == -2) { 376 | emojisRisingHeight = getHeight() / 2; 377 | } else if (emojisRisingHeightGiven <= 0 && emojisRisingHeightGiven >= -1) { 378 | emojisRisingHeight = getHeight() - (int) (emojisRisingHeightGiven * getHeight()); 379 | } 380 | setHomeRect(); 381 | setPathPanel(); 382 | 383 | homeEmojiVisible = true; 384 | } 385 | 386 | private void setHomeRect() { 387 | // Set the homeRect y coordinate based on user data 388 | if (homeCenterYGiven == -1) { 389 | homeCenter[1] = getHeight() - (int) (30 * densityFactor); 390 | } else { 391 | homeCenter[1] = (int) (getHeight() - homeCenterYGiven); 392 | } 393 | 394 | // Set the homeBitmap with the default Bitmap 395 | // use R.drawable.home to access or modify it 396 | if (homeBitmap == null) 397 | homeBitmap = getBitmapFromId(R.drawable.home, homeSide); 398 | // Set the home Rect 399 | homeRect = new Rect((homeCenter[0] - homeSide / 2), (homeCenter[1] - homeSide / 2), (homeCenter[0] + homeSide / 2), (homeCenter[1] + homeSide / 2)); 400 | } 401 | 402 | private void setPathPanel() { 403 | // Set the coordinates for circular animation 404 | if (panelCentreGiven[0] == -2) 405 | panelCentre[0] = getWidth() / 2; 406 | else if (panelCentreGiven[0] >= -1 && panelCentreGiven[0] <= 0) { 407 | panelCentre[0] = 0 - (int) (panelCentreGiven[0] * getWidth()); 408 | } else if (panelCentreGiven[0] >= 0) { 409 | panelCentre[0] = (int) (panelCentreGiven[0]); 410 | } 411 | if (panelCentreGiven[1] == -2) 412 | panelCentre[1] = getHeight() - panelEmojiSide / 2; 413 | else if (panelCentreGiven[1] >= -1 && panelCentreGiven[1] <= 0) { 414 | panelCentre[1] = getHeight() + (int) (panelCentreGiven[1] * getHeight()); 415 | } else if (panelCentreGiven[1] >= 0) { 416 | panelCentre[1] = getHeight() - (int) (panelCentreGiven[1]); 417 | } 418 | //TODO: need to look somewhat flatter 419 | 420 | // Set the radius of circular animation 421 | if (panelRadiusGiven == -1) { 422 | panelRadius = (int) (smallerDimension / 2 - 20 * densityFactor); 423 | } else { 424 | panelRadius = smallerDimension / 2 > panelRadiusGiven ? panelRadiusGiven : smallerDimension / 2; 425 | } 426 | 427 | clickedRadius = (int) (panelEmojiSide * 0.65); 428 | // angle between successive emojis 429 | double angle = Math.PI / (numberOfEmojis + 1); 430 | 431 | // set up PathMeasure object between initial and final coordinates 432 | Path emojiPath1; 433 | pms = new PathMeasure[numberOfEmojis]; 434 | for (int i = 1; i <= numberOfEmojis; i++) { 435 | emojiPath1 = new Path(); 436 | emojiPath1.moveTo(panelCentre[0], panelCentre[1]); 437 | emojiPath1.lineTo((float) (panelCentre[0] + panelRadius * Math.cos(i * angle + Math.PI)), (float) (panelCentre[1] + panelRadius * Math.sin(i * angle + Math.PI))); 438 | pms[i - 1] = new PathMeasure(emojiPath1, false); 439 | } 440 | 441 | } 442 | 443 | @Override 444 | protected void onDraw(Canvas canvas) { 445 | // Log.i("point 446", "draw"); 446 | super.onDraw(canvas); 447 | 448 | if (homeEmojiVisible) 449 | // To make home emoji visible 450 | if (clickedEmojiNumber == -1) 451 | canvas.drawBitmap(homeBitmap, null, homeRect, null); 452 | else canvas.drawBitmap(emojiBitmap[clickedEmojiNumber], null, homeRect, null); 453 | 454 | if (panelAnimWorking) { 455 | // to start circular animation 456 | // to display clicked circle on clicked emoji 457 | if (clickedEmojiNumber != -1) { 458 | canvas.drawCircle(emojiMovingPoint[clickedEmojiNumber][0], emojiMovingPoint[clickedEmojiNumber][1], clickedRadius, clickedPaint); 459 | } 460 | for (int i = 0; i < numberOfEmojis; i++) { 461 | canvas.drawBitmap(emojiBitmap[i], emojiMatrix[i], null); 462 | } 463 | startPanelAnim(); 464 | } 465 | 466 | if (clickingAnimWorking) { 467 | // to start clicking animation 468 | // Display clicked circle 469 | if (clickedEmojiNumber != -1) { 470 | canvas.drawCircle(emojiMovingPoint[clickedEmojiNumber][0], emojiMovingPoint[clickedEmojiNumber][1], clickedRadius, clickedPaint); 471 | } 472 | for (int i = 0; i < numberOfEmojis; i++) { 473 | canvas.drawBitmap(emojiBitmap[i], emojiMatrix[i], null); 474 | } 475 | } 476 | 477 | if (emojiRising) { 478 | // display rising emojis at their new position 479 | for (RisingEmoji re : risingEmojis) { 480 | canvas.drawBitmap(emojiBitmap[clickedEmojiNumber], null, re.getRect(), re.getPaint()); 481 | } 482 | } 483 | } 484 | 485 | private void startPanelAnim() { 486 | // start circular animation 487 | 488 | // float array to store new coordinates 489 | float[] emojiMovingPointFloat = new float[2]; 490 | 491 | // initialise matrix array 492 | if (emojiMatrix == null) { 493 | emojiMatrix = new Matrix[numberOfEmojis]; 494 | } 495 | 496 | // get emojiBitmap from their ids 497 | for (int i = 0; i < numberOfEmojis; i++) { 498 | if (emojiBitmap[i] == null) { 499 | emojiBitmap[i] = getBitmapFromId(emojiId.get(i), panelEmojiSide); 500 | } 501 | } 502 | 503 | // initialise array to hold emoji coordinates 504 | if (emojiMovingPoint == null) { 505 | emojiMovingPoint = new int[numberOfEmojis][2]; 506 | for (int i = 0; i < numberOfEmojis; i++) { 507 | emojiMovingPoint[i] = new int[2]; 508 | } 509 | } 510 | 511 | float fSegmentLen = pms[0].getLength() / 210;//210 animation steps 512 | 513 | if (iCurStep >= 0) { 514 | for (int i = 0; i < numberOfEmojis; i++) { 515 | pms[i].getPosTan(fSegmentLen * iCurStepTaken, emojiMovingPointFloat, null); 516 | emojiMovingPoint[i] = convertFloatArrayToIntArray(emojiMovingPointFloat, emojiMovingPoint[i]); 517 | emojiMatrix[i] = new Matrix(); 518 | // int scale = panelEmojiSide / emojiBitmap[0].getHeight(); 519 | // emojiMatrix.get(i).setScale(scale, scale); 520 | // move bitmap to the coordinate 521 | emojiMatrix[i].postTranslate(emojiMovingPoint[i][0] - panelEmojiSide / 2, emojiMovingPoint[i][1] - panelEmojiSide / 2); 522 | // rotate it with required effect 523 | emojiMatrix[i].postRotate((iCurStep) * (75 - 150 * (i + 1) / (numberOfEmojis + 1)) / 20, emojiMovingPoint[i][0], emojiMovingPoint[i][1]); 524 | } 525 | // to get deceleration effect 526 | iCurStepTaken += iCurStep; 527 | iCurStep--; 528 | // gradually dim background 529 | setColorFilter(Color.rgb(255 - 6 * (20 - iCurStep), 255 - 6 * (20 - iCurStep), 255 - 6 * (20 - iCurStep)), android.graphics.PorterDuff.Mode.MULTIPLY); 530 | } else { 531 | iCurStep = 20; 532 | iCurStepTaken = 0; 533 | } 534 | } 535 | 536 | private int[] convertFloatArrayToIntArray(float[] emojiMovingPointFloat, int[] ints) { 537 | ints[0] = (int) emojiMovingPointFloat[0]; 538 | ints[1] = (int) emojiMovingPointFloat[1]; 539 | return ints; 540 | } 541 | 542 | private void startClickingAnim(final int clickedIndex) { 543 | // start clicking animation 544 | 545 | panelAnimWorking = false; 546 | clickingAnimWorking = true; 547 | ValueAnimator animator = ValueAnimator.ofFloat(1, 0.4f); 548 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 549 | @Override 550 | public void onAnimationUpdate(ValueAnimator valueAnimator) { 551 | // reduce clicked emoji by reducing its scale and translating it to the required position 552 | emojiMatrix[clickedIndex].setScale((float) valueAnimator.getAnimatedValue(), (float) valueAnimator.getAnimatedValue()); 553 | emojiMatrix[clickedIndex].postTranslate(emojiMovingPoint[clickedIndex][0] - (float) valueAnimator.getAnimatedValue() * panelEmojiSide / 2, emojiMovingPoint[clickedIndex][1] - (float) valueAnimator.getAnimatedValue() * panelEmojiSide / 2); 554 | invalidate(); 555 | } 556 | }); 557 | animator.addListener(new AnimatorListenerAdapter() { 558 | @Override 559 | public void onAnimationEnd(Animator animation) { 560 | // restore background dimness 561 | setColorFilter(Color.rgb(255, 255, 255), android.graphics.PorterDuff.Mode.MULTIPLY); 562 | clickingAnimWorking = false; 563 | clickedEmojiNumber = clickedIndex; 564 | 565 | // start emoji rising animation 566 | emojiRisinginit(); 567 | } 568 | }); 569 | animator.setDuration(500); 570 | animator.setInterpolator(new AccelerateInterpolator()); 571 | animator.start(); 572 | } 573 | 574 | private void startUnclickingAnim(final int clickedIndex) { 575 | // start unclicking animation 576 | 577 | panelAnimWorking = false; 578 | clickingAnimWorking = true; 579 | ValueAnimator animator = ValueAnimator.ofFloat(1, 0.4f); 580 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 581 | @Override 582 | public void onAnimationUpdate(ValueAnimator valueAnimator) { 583 | // reduce clicked emoji by reducing its scale and translating it to the required position 584 | emojiMatrix[clickedIndex].setScale((float) valueAnimator.getAnimatedValue(), (float) valueAnimator.getAnimatedValue()); 585 | emojiMatrix[clickedIndex].postTranslate(emojiMovingPoint[clickedIndex][0] - (float) valueAnimator.getAnimatedValue() * panelEmojiSide / 2, emojiMovingPoint[clickedIndex][1] - (float) valueAnimator.getAnimatedValue() * panelEmojiSide / 2); 586 | 587 | // reduce the size of background panel radius 588 | clickedRadius = (int) (panelEmojiSide * (float) valueAnimator.getAnimatedValue() * 0.65); 589 | invalidate(); 590 | } 591 | }); 592 | animator.addListener(new AnimatorListenerAdapter() { 593 | @Override 594 | public void onAnimationEnd(Animator animation) { 595 | clickingAnimWorking = false; 596 | clickedEmojiNumber = -1; 597 | homeEmojiVisible = true; 598 | // restore background dimness 599 | setColorFilter(Color.rgb(255, 255, 255), android.graphics.PorterDuff.Mode.MULTIPLY); 600 | clickedRadius = (int) (panelEmojiSide * 0.65); 601 | } 602 | }); 603 | animator.setDuration(500); 604 | animator.setInterpolator(new AccelerateInterpolator()); 605 | animator.start(); 606 | } 607 | 608 | private void emojiRisinginit() { 609 | // set up rising emojis 610 | 611 | // directly invalidate if numberOfRisers<=0 612 | if (numberOfRisers <= 0) { 613 | homeEmojiVisible = true; 614 | invalidate(); 615 | return; 616 | } 617 | 618 | emojiRising = true; 619 | 620 | //set up emojis with random behaviour at random position 621 | for (int i = 0; i < numberOfRisers; i++) { 622 | Rect risingRect = calculateNewRect(new Rect(), new Random().nextInt(getWidth() + 1), getHeight() + new Random().nextInt(2 * getHeight() / 5), new Random().nextInt(panelEmojiSide / 4) + panelEmojiSide / 3); 623 | risingEmojis.add(new RisingEmoji(risingRect, new Random().nextInt(6) + emojisRisingSpeed)); 624 | } 625 | // start animation 626 | emojiRisingAnim(); 627 | } 628 | 629 | private void emojiRisingAnim() { 630 | // timer to continuously rise emojis 631 | 632 | if (emojiRisingTimer == null) { 633 | emojiRisingTimer = new Timer(); 634 | emojiRisingTimer.scheduleAtFixedRate(new TimerTask() { 635 | @Override 636 | public void run() { 637 | // calculate new coordinates in non ui thread 638 | riseEmoji(); 639 | ((Activity) context).runOnUiThread(new Runnable() { 640 | @Override 641 | public void run() { 642 | // display the emojis at their new position 643 | invalidate(); 644 | } 645 | }); 646 | } 647 | }, 5, 40); 648 | } 649 | 650 | } 651 | 652 | private void riseEmoji() { 653 | // calculate new coordinates 654 | 655 | if (startFading) 656 | fading += new Random().nextInt(numberOfRisers / 5); 657 | // currently index to which emojis will be faded 658 | for (int i = 0; i < risingEmojis.size(); i++) { 659 | RisingEmoji re = risingEmojis.get(i); 660 | // update rects to their new positions 661 | re.setRect(calculateNewRect(re.getRect(), re.getRect().centerX(), re.getRect().centerY() - re.getSpeed(), re.getRect().width() / 2)); 662 | 663 | //if any of the emoji crossed the threshold height, start fading emojis 664 | if (startFading || re.getRect().top <= emojisRisingHeight) { 665 | startFading = true; 666 | if (fading > risingEmojis.size()) fading = risingEmojis.size(); 667 | if (re.getPaint() == null) re.setPaint(new Paint()); 668 | 669 | // if emojis index is smaller than currently fading index 670 | if (i <= fading) { 671 | // fade 672 | re.getPaint().setAlpha(re.getPaint().getAlpha() / 2); 673 | // increase size 674 | re.setRect(calculateNewRect(re.getRect(), re.getRect().centerX(), re.getRect().centerY(), (int) (re.getRect().width() * 0.55))); 675 | } 676 | 677 | // remove if size almost completely faded 678 | if (re.getPaint().getAlpha() < 10) { 679 | risingEmojis.remove(risingEmojis.get(i)); 680 | i--; 681 | } 682 | 683 | } 684 | 685 | // stop animation if every emoji has faded 686 | if (risingEmojis.size() == 0) { 687 | emojiRising = false; 688 | if (emojiRisingTimer != null) { 689 | emojiRisingTimer.cancel(); 690 | emojiRisingTimer.purge(); 691 | emojiRisingTimer = null; 692 | } 693 | homeEmojiVisible = true; 694 | fading = 0; 695 | startFading = false; 696 | break; 697 | } 698 | } 699 | } 700 | //TODO set emoji before anim starts 701 | //TODO hover over emojis effect 702 | 703 | @SuppressLint("ClickableViewAccessibility") 704 | @Override 705 | public boolean onTouchEvent(MotionEvent event) { 706 | // respond to touch events 707 | 708 | // Log.i("point 709", "onTouchEvent " + event.getAction() + wasSwiping + emojiClicked ); 709 | if (event.getAction() == MotionEvent.ACTION_DOWN) { 710 | // prepare for new gesture 711 | wasSwiping = false; 712 | emojiClicked = false; 713 | if (homeEmojiVisible && homeRect.contains((int) event.getX(), (int) event.getY())) { 714 | emojiClicked = true; 715 | } else if (panelAnimWorking) { 716 | for (int i = numberOfEmojis - 1; i >= 0; i--) { 717 | if (clickedOnEmojiReact(i, event.getX(), event.getY())) { 718 | emojiClicked = true; 719 | break; 720 | } 721 | } 722 | if (clickedEmojiNumber != -1 && clickedOnRing(event.getX(), event.getY(), clickedEmojiNumber)) { 723 | emojiClicked = true; 724 | } 725 | } 726 | super.onTouchEvent(event); 727 | return true; 728 | } else if (!wasSwiping && event.getAction() == MotionEvent.ACTION_MOVE) { 729 | // swiping gesture detected 730 | wasSwiping = true; 731 | 732 | } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { 733 | if (wasSwiping && !emojiClicked) { 734 | // gesture ends with homeEmoji visible 735 | panelAnimWorking = false; 736 | homeEmojiVisible = true; 737 | setColorFilter(Color.rgb(255, 255, 255), android.graphics.PorterDuff.Mode.MULTIPLY); 738 | } else { 739 | // time to respond to clicks on emojiRect 740 | if (panelAnimWorking) { 741 | // detect if clicked on EmojiReact 742 | for (int i = numberOfEmojis - 1; i >= 0; i--) { 743 | if (clickedOnEmojiReact(i, event.getX(), event.getY())) { 744 | 745 | if (clickedEmojiNumber == i) { 746 | if (mClickInterface != null) 747 | mClickInterface.onEmojiUnclicked(i, (int) event.getX(), (int) event.getY()); 748 | startUnclickingAnim(clickedEmojiNumber); 749 | return false; 750 | } else if (clickedEmojiNumber != -1) { 751 | if (mClickInterface != null) 752 | mClickInterface.onEmojiUnclicked(clickedEmojiNumber, (int) event.getX(), (int) event.getY()); 753 | } 754 | 755 | if (mClickInterface != null) 756 | mClickInterface.onEmojiClicked(i, (int) event.getX(), (int) event.getY()); 757 | startClickingAnim(i); 758 | return false; 759 | } 760 | } 761 | // detect if clicked on circle surrounding clicked Emoji 762 | if (clickedEmojiNumber != -1 && clickedOnRing(event.getX(), event.getY(), clickedEmojiNumber)) { 763 | if (mClickInterface != null) 764 | mClickInterface.onEmojiUnclicked(clickedEmojiNumber, (int) event.getX(), (int) event.getY()); 765 | startUnclickingAnim(clickedEmojiNumber); 766 | return false; 767 | } 768 | if (!wasSwiping) { 769 | // clicked on background 770 | 771 | // restore background dimness 772 | panelAnimWorking = false; 773 | homeEmojiVisible = true; 774 | setColorFilter(Color.rgb(255, 255, 255), android.graphics.PorterDuff.Mode.MULTIPLY); 775 | } 776 | } else if (homeEmojiVisible && homeRect.contains((int) event.getX(), (int) event.getY())) { 777 | // detect if clicked on homeEmoji 778 | homeEmojiVisible = false; 779 | panelAnimWorking = true; 780 | startPanelAnim(); 781 | return false; 782 | } 783 | return super.onTouchEvent(event); 784 | 785 | } 786 | } 787 | return super.onTouchEvent(event); 788 | } 789 | 790 | private boolean clickedOnEmojiReact(int i, double x, double y) { 791 | return (Math.abs(x - emojiMovingPoint[i][0]) < panelEmojiSide / 2 && Math.abs(y - emojiMovingPoint[i][1]) < panelEmojiSide / 2); 792 | } 793 | 794 | private boolean clickedOnRing(float x, float y, int clickedEmojiNumber) { 795 | return (Math.pow(x - emojiMovingPoint[clickedEmojiNumber][0], 2) + Math.pow(y - emojiMovingPoint[clickedEmojiNumber][1], 2) <= Math.pow(clickedRadius, 2)); 796 | } 797 | 798 | @Override 799 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 800 | super.onSizeChanged(w, h, oldw, oldh); 801 | setup(); 802 | } 803 | 804 | @Override 805 | public void setPadding(int left, int top, int right, int bottom) { 806 | super.setPadding(left, top, right, bottom); 807 | setup(); 808 | } 809 | 810 | @Override 811 | public void setPaddingRelative(int start, int top, int end, int bottom) { 812 | super.setPaddingRelative(start, top, end, bottom); 813 | setup(); 814 | } 815 | 816 | private Bitmap getBitmapFromId(int id, int side) { 817 | // generate bitmap from id of defined size 818 | if (side <= 0) 819 | throw new IllegalArgumentException("Emoji can't have 0 or negative side"); 820 | 821 | Drawable drawable = getResources().getDrawable(id); 822 | if (drawable == null) { 823 | return null; 824 | } 825 | try { 826 | Bitmap bitmap; 827 | if (drawable instanceof ColorDrawable) { 828 | bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); 829 | } else { 830 | bitmap = Bitmap.createBitmap(side, side, Bitmap.Config.ARGB_8888); 831 | } 832 | 833 | drawable.setBounds(0, 0, side, side); 834 | drawable.draw(new Canvas(bitmap)); 835 | return bitmap; 836 | } catch (Exception e) { 837 | e.printStackTrace(); 838 | return null; 839 | } 840 | } 841 | 842 | private Rect calculateNewRect(Rect initialRect, int x, int y, int halfSide) { 843 | // return rect with center x,y and side of length 2*halfside 844 | 845 | initialRect.left = x - halfSide; 846 | initialRect.right = x + halfSide; 847 | initialRect.top = y - halfSide; 848 | initialRect.bottom = y + halfSide; 849 | return initialRect; 850 | } 851 | } 852 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/java/com/ritik/emojireactionlibrary/RisingEmoji.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionlibrary; 2 | 3 | import android.graphics.Paint; 4 | import android.graphics.Rect; 5 | 6 | /** 7 | * This class deals with properties of risingEmoji Rect 8 | */ 9 | 10 | class RisingEmoji { 11 | private Rect rect; 12 | private int speed; 13 | private Paint paint; 14 | 15 | RisingEmoji(Rect rect, int speed) { 16 | this.rect = rect; 17 | this.speed = speed; 18 | } 19 | 20 | public Rect getRect() { 21 | return rect; 22 | } 23 | 24 | public void setRect(Rect rect) { 25 | this.rect = rect; 26 | } 27 | 28 | public int getSpeed() { 29 | return speed; 30 | } 31 | 32 | public void setSpeed(int speed) { 33 | this.speed = speed; 34 | } 35 | 36 | public Paint getPaint() { 37 | return paint; 38 | } 39 | 40 | public void setPaint(Paint paint) { 41 | this.paint = paint; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/res/drawable/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/emojireactionlibrary/src/main/res/drawable/home.png -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | /// General Attributes 7 | 8 | 9 | 10 | 11 | /// Home emoji Attributes 12 | 13 | 14 | 15 | 16 | 17 | /// Panel Animation Attributes 18 | 19 | 20 | 21 | 22 | 23 | 24 | /// Rising Emojis Attributes 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | EmojiReactionLibrary 3 | 4 | -------------------------------------------------------------------------------- /emojireactionlibrary/src/test/java/com/ritik/emojireactionlibrary/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.ritik.emojireactionlibrary; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jul 20 18:45:20 IST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /sample/coverImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/sample/coverImage.png -------------------------------------------------------------------------------- /sample/recycler.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/sample/recycler.gif -------------------------------------------------------------------------------- /sample/simple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdgspace/EmojiReactionView/303abec49dfcb96f9c123d7474974e4c50e35698/sample/simple.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':emojireactionlibrary' 2 | --------------------------------------------------------------------------------