├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── livetyping │ │ └── cannyviewanimator │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── livetyping │ │ │ └── cannyviewanimator │ │ │ ├── MainActivity.java │ │ │ ├── RequestResultCodes.java │ │ │ ├── choose │ │ │ ├── ChooseActivity.java │ │ │ └── list │ │ │ │ ├── ChooseItemViewHolder.java │ │ │ │ ├── ChooseListActivity.java │ │ │ │ └── ChooseModel.java │ │ │ ├── custom │ │ │ └── CustomActivity.java │ │ │ ├── transition │ │ │ └── TransitionActivity.java │ │ │ └── xml │ │ │ └── XmlActivity.java │ └── res │ │ ├── drawable-hdpi │ │ └── ic_big_logo.png │ │ ├── drawable-mdpi │ │ └── ic_big_logo.png │ │ ├── drawable-xhdpi │ │ └── ic_big_logo.png │ │ ├── drawable-xxhdpi │ │ └── ic_big_logo.png │ │ ├── drawable-xxxhdpi │ │ └── ic_big_logo.png │ │ ├── drawable │ │ ├── ic_arrow_back.xml │ │ └── ic_check.xml │ │ ├── layout │ │ ├── activity_custom.xml │ │ ├── activity_main.xml │ │ ├── activity_transition.xml │ │ ├── activity_xml.xml │ │ ├── choose_activity.xml │ │ ├── choose_item.xml │ │ └── choose_list_activity.xml │ │ ├── menu │ │ └── choose_list.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── livetyping │ └── cannyviewanimator │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle ├── deploy.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── livetyping │ │ └── library │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── livetyping │ │ │ └── library │ │ │ ├── CannyViewAnimator.java │ │ │ ├── TransitionViewAnimator.java │ │ │ ├── ViewAnimator.java │ │ │ ├── animators │ │ │ ├── property │ │ │ │ ├── PropertyAnimators.java │ │ │ │ ├── PropertyCanny.java │ │ │ │ ├── PropertyIn.java │ │ │ │ └── PropertyOut.java │ │ │ └── reveal │ │ │ │ ├── RevealAnimators.java │ │ │ │ ├── RevealCanny.java │ │ │ │ ├── RevealIn.java │ │ │ │ └── RevealOut.java │ │ │ └── interfaces │ │ │ ├── CannyTransition.java │ │ │ ├── DefaultCannyAnimators.java │ │ │ ├── InAnimator.java │ │ │ └── OutAnimator.java │ └── res │ │ └── values │ │ └── attrs.xml │ └── test │ └── java │ └── com │ └── livetyping │ └── library │ └── ExampleUnitTest.java ├── readme_extra ├── parallax.gif ├── top_1.gif ├── top_2.gif ├── top_3.gif ├── transition.gif ├── u2020.gif └── xml.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | local.properties 3 | .idea 4 | *.iml 5 | build 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-CannyViewAnimator-green.svg?style=flat)](https://android-arsenal.com/details/1/4302) 2 | 3 | # CannyViewAnimator 4 | CannyViewAnimator is an enhanced version of ViewAnimator. It allows to use Animators and 5 | Transitions to extend Visibility. The logic is taken from ViewAnimator of the Android SDK. 6 | The ViewAnimator can show only one view. If you show an other view then previous one will be hidden. 7 | All changes are taking with animations. 8 | 9 | ![Top 1 example](readme_extra/top_1.gif?raw=true "Top 1 example") 10 | ![Top 2 example](readme_extra/top_2.gif?raw=true "Top 2 example") 11 | ![Top 3 example](readme_extra/top_3.gif?raw=true "Top 3 example") 12 | 13 | ## Installation 14 | Add `compile 'com.livetyping:cannyviewanimator:0.8'` in your dependencies. 15 | 16 | ![U2020 example](readme_extra/u2020.gif?raw=true "U2020 example") 17 | 18 | 19 | ## Internal organization 20 | CannyViewAnimator is divided into three layers of abstraction: 21 | * ViewAnimator - switches the visibility of child; 22 | * TransitionViewAnimator (extends ViewAnimator) - performs Transitions that extend Visibility; 23 | * CannyViewAnimator (extends TransitionViewAnimator) - performs Animators; 24 | * CannyTransition - interface for setting Transition for individual children; 25 | * InAnimator - interface for setting animator for appearing; 26 | * OutAnimator - interface for setting animator for disappearing. 27 | 28 | ## ViewAnimator 29 | Includes the following public methods: 30 | * setDisplayedChildIndex (int inChildIndex) - shows a child by its index in the parent; 31 | * setDisplayedChildId (@IdRes int id) - shows a child by its resID; 32 | * setDisplayedChild (View view) - shows a child by its object; 33 | * getDisplayedChildIndex () - obtains the index of the currently displayed child; 34 | * getDisplayedChild () - obtains the object of the currently displayed child; 35 | * getDisplayedChildId () – gets the resID of the currently displayed child; 36 | * bringChildToPosition (View child, int position) – changes the index of a child within the parent. 37 | 38 | ## TransitionViewAnimator 39 | (Use Transitions from AppCompat) 40 | Includes the following public methods: 41 | * startTransition() - launches Transition (starts by default after visibility changes) 42 | * setCannyTransition (CannyTransition cannyTransition) – interface setter for setting Transition for individual children 43 | 44 | ![Transition example](readme_extra/transition.gif?raw=true "Transition example") 45 | 46 | ```java 47 | animator.setCannyTransition(new CannyTransition() { 48 | @Override 49 | public Transition getTransition(View inChild, View outChild) { 50 | TransitionSet transitionSet = new TransitionSet(); 51 | transitionSet.addTransition(new Fade(Fade.IN).addTarget(inChild)); 52 | transitionSet.addTransition(new Fade(Fade.OUT).addTarget(outChild)); 53 | return transitionSet; 54 | } 55 | }); 56 | ``` 57 | 58 | 59 | ## CannyViewAnimator 60 | Includes the following public methods: 61 | * setInAnimator (T ... inAnimators) – interface setter for fading in animation (using the parameters) 62 | * setInAnimator (ListoutAnimators) – interface setter for fading out animation (using the list) 65 | 66 | 67 | ```java 68 | animator.setInAnimator(new InAnimator() { 69 | @Override 70 | public Animator getInAnimator(View inChild, View outChild) { 71 | return ObjectAnimator.ofFloat(inChild, View.ALPHA, 0, 1); 72 | } 73 | }); 74 | animator.setOutAnimator(new OutAnimator() { 75 | @Override 76 | public Animator getOutAnimator(View inChild, View outChild) { 77 | return ObjectAnimator.ofFloat(outChild, View.ALPHA, 1,0); 78 | } 79 | }) 80 | ``` 81 | 82 | 83 | ## Flags 84 | AnimateType - indicates the order in which the animation will run. 85 | - Sequentially 86 | - Together 87 | 88 | `animator.setAnimateType(CannyViewAnimator.TOGETHER);` 89 | 90 | LocationType - indicates the order in which the children will be placed in the parent. 91 | This flag makes sure that children don’t overlap with each other during animation. 92 | - For position 93 | - In always top 94 | - Out always top 95 | 96 | `animator.setLocationType(CannyViewAnimator.IN_ALWAYS_TOP);` 97 | 98 | ## DefaultCannyAnimators 99 | This class group was originally created for testing, but in the end I decided to leave them because 100 | they help to make simple animations effortlessly. It is divided into two types: 101 | * PropertyAnimators - animators of View properties. [List] (library/src/main/java/com/livetyping/library/animators/property/PropertyAnimators.java) 102 | * RevealAnimators - CircularReveal animators. [List] (library/src/main/java/com/livetyping/library/animators/reveal/RevealAnimators.java) 103 | 104 | Example: 105 | ```java 106 | animator.setInAnimator(PropertyAnimators.ROTATION_180); 107 | animator.setInAnimator(PropertyAnimators.ROTATION_M180); 108 | ``` 109 | 110 | ## Helper classes 111 | This group of classes is needed for easier creation of InAnimators and OutAnimators. 112 | * PropertyIn 113 | * PropertyOut 114 | * RevealIn 115 | * RevealOut 116 | 117 | Example of parallax effect: 118 | ```java 119 | animator.setInAnimator(new PropertyIn(View.TRANSLATION_X, width, 0).setDuration(1000)); 120 | animator.setOutAnimator(new PropertyOut(View.TRANSLATION_X, 0, -width / 2).setDuration(1000)); 121 | animator.setLocationType(CannyViewAnimator.IN_ALWAYS_TOP); 122 | animator.setAnimateType(CannyViewAnimator.TOGETHER); 123 | ``` 124 | 125 | ![Parallax example](readme_extra/parallax.gif?raw=true "Parallax example") 126 | 127 | 128 | ## XML 129 | Attribute list: 130 | * `animate_type` inmplementation `setAnimateType` 131 | * `location_type` inmplementation `setLocationType` 132 | * `in` set default in animator 133 | * `out` set default out animator 134 | * `prelolipop_in` set default in animator (without reveal animators) 135 | * `prelolipop_out` set default out animator (without reveal animators) 136 | 137 | If the current Android version is lower than Lollipop, then animators will be taken from 138 | `prelolipop_in`, if `prelolipop_in` is empty, then animators will taken from `in`. 139 | 140 | Example: 141 | 142 | ![XML example](readme_extra/xml.gif?raw=true "XML example") 143 | 144 | ```xml 145 | 154 | ``` 155 | ## License 156 | Copyright 2015 Danil Perevalov. 157 | 158 | Licensed under the Apache License, Version 2.0 (the "License"); 159 | you may not use this file except in compliance with the License. 160 | You may obtain a copy of the License at 161 | 162 | http://www.apache.org/licenses/LICENSE-2.0 163 | 164 | Unless required by applicable law or agreed to in writing, software 165 | distributed under the License is distributed on an "AS IS" BASIS, 166 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 167 | See the License for the specific language governing permissions and 168 | limitations under the License. 169 | 170 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.livetyping.cannyviewanimator" 9 | minSdkVersion 14 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | } 23 | 24 | dependencies { 25 | compile fileTree(dir: 'libs', include: ['*.jar']) 26 | testCompile 'junit:junit:4.12' 27 | compile project(":library") 28 | compile 'com.android.support:appcompat-v7:24+' 29 | compile 'com.android.support:recyclerview-v7:24+' 30 | compile 'com.android.support:cardview-v7:24+' 31 | compile 'com.android.support:design:24+' 32 | compile 'com.github.princeparadoxes:recyclerbindableadapter:1.2.1' 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Danil\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/livetyping/cannyviewanimator/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | 8 | import com.livetyping.cannyviewanimator.choose.ChooseActivity; 9 | import com.livetyping.cannyviewanimator.custom.CustomActivity; 10 | import com.livetyping.cannyviewanimator.transition.TransitionActivity; 11 | import com.livetyping.cannyviewanimator.xml.XmlActivity; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | private View startCustom; 15 | private View startXml; 16 | private View startTransition; 17 | private View startChoose; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | findViews(); 24 | initViews(); 25 | } 26 | 27 | private void findViews() { 28 | startCustom = findViewById(R.id.main_activity_start_custom); 29 | startXml = findViewById(R.id.main_activity_start_xml); 30 | startTransition = findViewById(R.id.main_activity_start_transition); 31 | startChoose = findViewById(R.id.main_activity_start_choose); 32 | } 33 | 34 | private void initViews() { 35 | startCustom.setOnClickListener(getStartActivityCL(CustomActivity.class)); 36 | startXml.setOnClickListener(getStartActivityCL(XmlActivity.class)); 37 | startTransition.setOnClickListener(getStartActivityCL(TransitionActivity.class)); 38 | startChoose.setOnClickListener(getStartActivityCL(ChooseActivity.class)); 39 | } 40 | 41 | private View.OnClickListener getStartActivityCL(final Class cls) { 42 | return new View.OnClickListener() { 43 | @Override 44 | public void onClick(View v) { 45 | startActivity(new Intent(MainActivity.this, cls)); 46 | } 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/RequestResultCodes.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator; 2 | 3 | /** 4 | * Created by Danil on 23.06.2016. 5 | */ 6 | public class RequestResultCodes { 7 | // ChooseActivity -> ChooseListActivity 8 | public static final int REQUEST = 11010; 9 | public static final int REQUEST_IN = 11011; 10 | public static final int REQUEST_OUT = 11012; 11 | 12 | //ChooseListActivity -> ChooseActivity 13 | public static final int RESULT_IN = 11260; 14 | public static final int RESULT_OUT = 11261; 15 | public static final String KEY_ANIMATORS = "ChooseListActivity.checked.animators"; 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/choose/ChooseActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.choose; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.SwitchCompat; 7 | import android.view.View; 8 | import android.widget.FrameLayout; 9 | import android.widget.RadioGroup; 10 | import android.widget.TextView; 11 | 12 | import com.livetyping.cannyviewanimator.R; 13 | import com.livetyping.cannyviewanimator.RequestResultCodes; 14 | import com.livetyping.cannyviewanimator.choose.list.ChooseListActivity; 15 | import com.livetyping.library.CannyViewAnimator; 16 | import com.livetyping.library.animators.property.PropertyAnimators; 17 | import com.livetyping.library.animators.reveal.RevealAnimators; 18 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | public class ChooseActivity extends AppCompatActivity { 24 | 25 | private CannyViewAnimator animator; 26 | private TextView inButton, outButton, startButton; 27 | private SwitchCompat typeCheck; 28 | private FrameLayout checkContainer; 29 | private RadioGroup locationTypeChooser; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.choose_activity); 35 | findViews(); 36 | initViews(); 37 | } 38 | 39 | private void findViews() { 40 | animator = (CannyViewAnimator) findViewById(R.id.choose_animator); 41 | inButton = (TextView) findViewById(R.id.choose_in_button); 42 | outButton = (TextView) findViewById(R.id.choose_out_button); 43 | checkContainer = (FrameLayout) findViewById(R.id.choose_container); 44 | typeCheck = (SwitchCompat) findViewById(R.id.choose_check); 45 | startButton = (TextView) findViewById(R.id.choose_start_button); 46 | locationTypeChooser = (RadioGroup) findViewById(R.id.choose_location_container); 47 | } 48 | 49 | private void initViews() { 50 | startButton.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | animator.setDisplayedChildIndex(animator.getDisplayedChildIndex() + 1); 54 | } 55 | }); 56 | checkContainer.setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | animator.setAnimateType(typeCheck.isChecked() 60 | ? CannyViewAnimator.SEQUENTIALLY 61 | : CannyViewAnimator.TOGETHER); 62 | typeCheck.setChecked(!typeCheck.isChecked()); 63 | 64 | } 65 | }); 66 | inButton.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | startActivityForResult(RequestResultCodes.REQUEST_IN); 70 | } 71 | }); 72 | outButton.setOnClickListener(new View.OnClickListener() { 73 | @Override 74 | public void onClick(View v) { 75 | startActivityForResult(RequestResultCodes.REQUEST_OUT); 76 | } 77 | }); 78 | locationTypeChooser.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 79 | @Override 80 | public void onCheckedChanged(RadioGroup group, int checkedId) { 81 | switch (checkedId) { 82 | case R.id.choose_location_for_position: 83 | animator.setLocationType(CannyViewAnimator.FOR_POSITION); 84 | break; 85 | case R.id.choose_location_in_always_top: 86 | animator.setLocationType(CannyViewAnimator.IN_ALWAYS_TOP); 87 | break; 88 | case R.id.choose_location_out_always_top: 89 | animator.setLocationType(CannyViewAnimator.OUT_ALWAYS_TOP); 90 | break; 91 | } 92 | } 93 | }); 94 | locationTypeChooser.check(R.id.choose_location_for_position); 95 | } 96 | 97 | private void startActivityForResult(int code) { 98 | Intent intent = new Intent(this, ChooseListActivity.class); 99 | intent.putExtra(String.valueOf(RequestResultCodes.REQUEST), code); 100 | startActivityForResult(intent, RequestResultCodes.REQUEST); 101 | } 102 | 103 | @Override 104 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 105 | super.onActivityResult(requestCode, resultCode, data); 106 | if (resultCode != RequestResultCodes.RESULT_IN 107 | && resultCode != RequestResultCodes.RESULT_OUT) return; 108 | List positionsAnimators = data 109 | .getIntegerArrayListExtra(RequestResultCodes.KEY_ANIMATORS); 110 | List animators = new ArrayList<>(positionsAnimators.size()); 111 | String text = ""; 112 | for (Integer position : positionsAnimators) { 113 | DefaultCannyAnimators newAnimator = position < RevealAnimators.values().length 114 | ? RevealAnimators.values()[position] 115 | : PropertyAnimators.values()[position - RevealAnimators.values().length]; 116 | animators.add(newAnimator); 117 | text += getNormalName(newAnimator.getName()) + " "; 118 | } 119 | if (resultCode == RequestResultCodes.RESULT_IN) { 120 | animator.setInAnimator(animators); 121 | inButton.setText(text); 122 | } else { 123 | animator.setOutAnimator(animators); 124 | outButton.setText(text); 125 | } 126 | } 127 | 128 | private String getNormalName(String name) { 129 | name = name.replaceAll("_", " "); 130 | return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); 131 | } 132 | } -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/choose/list/ChooseItemViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.choose.list; 2 | 3 | import android.support.v7.widget.CardView; 4 | import android.view.View; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.danil.recyclerbindableadapter.library.view.BindableViewHolder; 9 | 10 | import com.livetyping.cannyviewanimator.R; 11 | 12 | public class ChooseItemViewHolder extends BindableViewHolder { 14 | private final CardView container; 15 | private final TextView mainText; 16 | private final ImageView check; 17 | 18 | public ChooseItemViewHolder(View itemView) { 19 | super(itemView); 20 | container = (CardView) itemView.findViewById(R.id.choose_item_container); 21 | mainText = ((TextView) itemView.findViewById(R.id.choose_item_text)); 22 | check = (ImageView) itemView.findViewById(R.id.choose_item_check); 23 | } 24 | 25 | @Override 26 | public void bindView(int position, ChooseModel item, OnItemClick actionListener) { 27 | super.bindView(position, item, actionListener); 28 | mainText.setText(getNormalName(item.getAnimators().getName())); 29 | check.setVisibility(item.isChecked() ? View.VISIBLE : View.GONE); 30 | } 31 | 32 | private String getNormalName(String name) { 33 | name = name.replaceAll("_", " "); 34 | return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); 35 | } 36 | 37 | interface OnItemClick extends BindableViewHolder.ActionListener { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/choose/list/ChooseListActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.choose.list; 2 | 3 | import android.content.Intent; 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.support.v7.widget.Toolbar; 10 | import android.view.MenuItem; 11 | import android.view.View; 12 | 13 | import com.danil.recyclerbindableadapter.library.RecyclerBindableAdapter; 14 | import com.danil.recyclerbindableadapter.library.SimpleBindableAdapter; 15 | import com.livetyping.cannyviewanimator.R; 16 | import com.livetyping.cannyviewanimator.RequestResultCodes; 17 | import com.livetyping.library.animators.property.PropertyAnimators; 18 | import com.livetyping.library.animators.reveal.RevealAnimators; 19 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | public class ChooseListActivity extends AppCompatActivity implements ChooseItemViewHolder.OnItemClick, Toolbar.OnMenuItemClickListener { 26 | 27 | private Toolbar toolbar; 28 | private RecyclerView recyclerView; 29 | private SimpleBindableAdapter adapter; 30 | private ArrayList checked = new ArrayList<>(); 31 | private boolean isIn; 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.choose_list_activity); 37 | int code = getIntent().getIntExtra(String.valueOf(RequestResultCodes.REQUEST), 0); 38 | isIn = code == RequestResultCodes.REQUEST_IN; 39 | findViews(); 40 | initViews(); 41 | } 42 | 43 | private void findViews() { 44 | recyclerView = (RecyclerView) findViewById(R.id.choose_list_recycler); 45 | toolbar = (Toolbar) findViewById(R.id.choose_list_toolbar); 46 | } 47 | 48 | private void initViews() { 49 | recyclerView.setAdapter(getAdapter()); 50 | recyclerView.setLayoutManager(new LinearLayoutManager(this)); 51 | toolbar.setNavigationIcon(R.drawable.ic_arrow_back); 52 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 53 | @Override 54 | public void onClick(View v) { 55 | onBackPressed(); 56 | } 57 | }); 58 | toolbar.inflateMenu(R.menu.choose_list); 59 | toolbar.setOnMenuItemClickListener(this); 60 | } 61 | 62 | private SimpleBindableAdapter getAdapter() { 63 | adapter = new SimpleBindableAdapter<>(R.layout.choose_item, ChooseItemViewHolder.class); 64 | adapter.setActionListener(this); 65 | List items = new ArrayList<>(); 66 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 67 | items.addAll(Arrays.asList(RevealAnimators.values())); 68 | } 69 | items.addAll(Arrays.asList(PropertyAnimators.values())); 70 | adapter.addAll(ChooseModel.getAnimators(items)); 71 | return adapter; 72 | } 73 | 74 | @Override 75 | public void OnItemClickListener(int position, ChooseModel item) { 76 | if (item.isChecked()) { 77 | checked.remove(checked.indexOf(adapter.indexOf(item))); 78 | } else { 79 | checked.add(adapter.indexOf(item)); 80 | } 81 | item.setChecked(!item.isChecked()); 82 | adapter.notifyItemChanged(position); 83 | } 84 | 85 | @Override 86 | public boolean onMenuItemClick(MenuItem item) { 87 | switch (item.getItemId()) { 88 | case R.id.choose_list_apply: 89 | Intent intent = new Intent(); 90 | if (checked.size() == 0) checked.add(0); 91 | intent.putExtra(RequestResultCodes.KEY_ANIMATORS, checked); 92 | int code = isIn ? RequestResultCodes.RESULT_IN : RequestResultCodes.RESULT_OUT; 93 | setResult(code, intent); 94 | onBackPressed(); 95 | break; 96 | } 97 | return false; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/choose/list/ChooseModel.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.choose.list; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 11 | 12 | /** 13 | * Created by Danil on 15.05.2016. 14 | */ 15 | public class ChooseModel { 16 | private DefaultCannyAnimators animators; 17 | private boolean checked; 18 | 19 | public ChooseModel(DefaultCannyAnimators animators) { 20 | this.animators = animators; 21 | } 22 | 23 | public boolean isChecked() { 24 | return checked; 25 | } 26 | 27 | public void setChecked(boolean checked) { 28 | this.checked = checked; 29 | } 30 | 31 | public DefaultCannyAnimators getAnimators() { 32 | return animators; 33 | } 34 | 35 | public static List getAnimators(List animatorsList) { 36 | ArrayList chooseModels = new ArrayList<>(animatorsList.size()); 37 | for (DefaultCannyAnimators animators : animatorsList) { 38 | chooseModels.add(new ChooseModel(animators)); 39 | } 40 | return chooseModels; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/custom/CustomActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.custom; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ObjectAnimator; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | 10 | import com.livetyping.cannyviewanimator.R; 11 | import com.livetyping.library.CannyViewAnimator; 12 | import com.livetyping.library.animators.property.PropertyIn; 13 | import com.livetyping.library.animators.property.PropertyOut; 14 | import com.livetyping.library.interfaces.InAnimator; 15 | import com.livetyping.library.interfaces.OutAnimator; 16 | 17 | public class CustomActivity extends AppCompatActivity { 18 | private CannyViewAnimator animator; 19 | private TextView startButton; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_custom); 25 | findViews(); 26 | initViews(); 27 | } 28 | 29 | @Override 30 | protected void onResume() { 31 | super.onResume(); 32 | } 33 | 34 | private void findViews() { 35 | animator = (CannyViewAnimator) findViewById(R.id.custom_animator); 36 | startButton = (TextView) findViewById(R.id.custom_start_button); 37 | } 38 | 39 | private void initViews() { 40 | animator.setInAnimator(new InAnimator() { 41 | @Override 42 | public Animator getInAnimator(View inChild, View outChild) { 43 | return ObjectAnimator.ofFloat(inChild, View.TRANSLATION_X, animator.getWidth(), 0) 44 | .setDuration(1000); 45 | } 46 | }); 47 | animator.setOutAnimator(new OutAnimator() { 48 | @Override 49 | public Animator getOutAnimator(View inChild, View outChild) { 50 | return ObjectAnimator.ofFloat(outChild, View.TRANSLATION_X, 0, 51 | -animator.getWidth() / 2).setDuration(1000); 52 | } 53 | }); 54 | animator.setLocationType(CannyViewAnimator.IN_ALWAYS_TOP); 55 | animator.setAnimateType(CannyViewAnimator.TOGETHER); 56 | startButton.setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | animator.setDisplayedChildIndex(animator.getDisplayedChildIndex() + 1); 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/transition/TransitionActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.transition; 2 | 3 | import android.os.Bundle; 4 | import android.support.transition.Fade; 5 | import android.support.transition.Transition; 6 | import android.support.transition.TransitionSet; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import com.livetyping.cannyviewanimator.R; 12 | import com.livetyping.library.CannyViewAnimator; 13 | import com.livetyping.library.animators.property.PropertyAnimators; 14 | import com.livetyping.library.interfaces.CannyTransition; 15 | 16 | public class TransitionActivity extends AppCompatActivity { 17 | private CannyViewAnimator animator; 18 | private TextView startButton; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_transition); 24 | findViews(); 25 | initViews(); 26 | } 27 | 28 | private void findViews(){ 29 | animator = (CannyViewAnimator) findViewById(R.id.transition_animator); 30 | startButton = (TextView) findViewById(R.id.transition_start_button); 31 | } 32 | 33 | private void initViews(){ 34 | animator.setCannyTransition(new CannyTransition() { 35 | @Override 36 | public Transition getTransition(View inChild, View outChild) { 37 | TransitionSet transitionSet = new TransitionSet(); 38 | transitionSet.addTransition(new Fade(Fade.IN).addTarget(inChild)); 39 | transitionSet.addTransition(new Fade(Fade.OUT).addTarget(outChild)); 40 | return transitionSet; 41 | } 42 | }); 43 | animator.setInAnimator(PropertyAnimators.SCALE_X_HALF, PropertyAnimators.SCALE_Y_HALF); 44 | animator.setOutAnimator(PropertyAnimators.SCALE_X_HALF, PropertyAnimators.SCALE_Y_HALF); 45 | startButton.setOnClickListener(new View.OnClickListener() { 46 | @Override 47 | public void onClick(View v) { 48 | animator.setDisplayedChildIndex(animator.getDisplayedChildIndex() + 1); 49 | } 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/livetyping/cannyviewanimator/xml/XmlActivity.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator.xml; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import com.livetyping.cannyviewanimator.R; 9 | import com.livetyping.library.CannyViewAnimator; 10 | 11 | public class XmlActivity extends AppCompatActivity { 12 | private CannyViewAnimator animator; 13 | private TextView startButton; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_xml); 19 | findViews(); 20 | initViews(); 21 | } 22 | 23 | private void findViews(){ 24 | animator = (CannyViewAnimator) findViewById(R.id.xml_animator); 25 | startButton = (TextView) findViewById(R.id.xml_start_button); 26 | } 27 | 28 | private void initViews(){ 29 | startButton.setOnClickListener(new View.OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | animator.setDisplayedChildIndex(animator.getDisplayedChildIndex() + 1); 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/drawable-hdpi/ic_big_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/drawable-mdpi/ic_big_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/drawable-xhdpi/ic_big_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/drawable-xxhdpi/ic_big_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/drawable-xxxhdpi/ic_big_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_custom.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 26 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 18 | 19 | 23 | 24 | 28 | 29 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_transition.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 23 | 24 | 29 | 30 | 35 | 36 | 37 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_xml.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | 20 | 22 | 23 | 25 | 26 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/choose_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 26 | 32 | 33 | 38 | 39 | 44 | 45 | 50 | 51 | 52 | 58 | 59 | 64 | 65 | 71 | 72 | 77 | 78 | 79 | 85 | 86 | 92 | 93 | 96 | 97 | -------------------------------------------------------------------------------- /app/src/main/res/layout/choose_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 18 | 19 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/choose_list_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/menu/choose_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FF5722 4 | #E64A19 5 | #FFCCBC 6 | #FFC107 7 | #212121 8 | #727272 9 | #FFFFFF 10 | #B6B6B6 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CannyViewAnimator 3 | Custom example 4 | Xml example 5 | Transition example 6 | Choose your animation! 7 | First view 8 | Second view 9 | Third view 10 | START! 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 17 | 18 | 22 | 23 | 29 | 30 | 34 | 35 | 39 | 40 | 44 | 45 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/test/java/com/livetyping/cannyviewanimator/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.cannyviewanimator; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | ext { 16 | versionName = VERSION_NAME as String 17 | versionCode = VERSION_CODE as int 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | VERSION_NAME=0.8 21 | VERSION_CODE=080 22 | GROUP=com.livetyping 23 | 24 | POM_DESCRIPTION=Android library for easy create animation. 25 | POM_URL=https://github.com/LiveTyping/CannyViewAnimator 26 | POM_SCM_URL=https://github.com/LiveTyping/CannyViewAnimator.git 27 | POM_SCM_CONNECTION=scm:git@github.com:LiveTyping/CannyViewAnimator.git 28 | POM_SCM_DEV_CONNECTION=scm:git@github.com:LiveTyping/CannyViewAnimator.git 29 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 30 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 31 | POM_LICENCE_DIST=repo 32 | POM_DEVELOPER_ID=princeparadoxes 33 | POM_DEVELOPER_NAME=Danil Perevalov 34 | POM_DEVELOPER_EMAIL=princeparadoxes@yandex.ru -------------------------------------------------------------------------------- /gradle/deploy.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | 4 | def isReleaseBuild() { 5 | return VERSION_NAME.contains("SNAPSHOT") == false 6 | } 7 | 8 | def getReleaseRepositoryUrl() { 9 | return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL 10 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 11 | } 12 | 13 | def getSnapshotRepositoryUrl() { 14 | return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL 15 | : "https://oss.sonatype.org/content/repositories/snapshots/" 16 | } 17 | 18 | def getRepositoryUsername() { 19 | return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" 20 | } 21 | 22 | def getRepositoryPassword() { 23 | return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" 24 | } 25 | 26 | afterEvaluate { project -> 27 | uploadArchives { 28 | repositories { 29 | mavenDeployer { 30 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 31 | 32 | pom.groupId = GROUP 33 | pom.artifactId = POM_ARTIFACT_ID 34 | pom.version = VERSION_NAME 35 | 36 | repository(url: getReleaseRepositoryUrl()) { 37 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 38 | } 39 | snapshotRepository(url: getSnapshotRepositoryUrl()) { 40 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 41 | } 42 | 43 | pom.project { 44 | name POM_NAME 45 | packaging POM_PACKAGING 46 | description POM_DESCRIPTION 47 | url POM_URL 48 | 49 | scm { 50 | url POM_SCM_URL 51 | connection POM_SCM_CONNECTION 52 | developerConnection POM_SCM_DEV_CONNECTION 53 | } 54 | 55 | licenses { 56 | license { 57 | name POM_LICENCE_NAME 58 | url POM_LICENCE_URL 59 | distribution POM_LICENCE_DIST 60 | } 61 | } 62 | 63 | developers { 64 | developer { 65 | id POM_DEVELOPER_ID 66 | name POM_DEVELOPER_NAME 67 | email POM_DEVELOPER_EMAIL 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | signing { 76 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 77 | sign configurations.archives 78 | } 79 | 80 | task androidJavadocs(type: Javadoc) { 81 | source = android.sourceSets.main.java.srcDirs 82 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 83 | } 84 | 85 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { 86 | classifier = 'javadoc' 87 | from androidJavadocs.destinationDir 88 | } 89 | 90 | task androidSourcesJar(type: Jar) { 91 | classifier = 'sources' 92 | from android.sourceSets.main.java.sourceFiles 93 | } 94 | 95 | artifacts { 96 | archives androidSourcesJar 97 | archives androidJavadocsJar 98 | } 99 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Oct 08 18:59:19 ALMT 2016 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-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 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 Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | String versionNameRoot = rootProject.versionName 4 | int versionCodeRoot = rootProject.versionCode 5 | 6 | android { 7 | compileSdkVersion 24 8 | buildToolsVersion "24.0.1" 9 | 10 | defaultConfig { 11 | minSdkVersion 14 12 | versionCode versionCodeRoot 13 | versionName versionNameRoot 14 | } 15 | 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | compile 'com.android.support:support-annotations:24.2.0' 26 | compile 'com.android.support:transition:24.2.0' 27 | } 28 | 29 | apply from: '../gradle/deploy.gradle' 30 | 31 | -------------------------------------------------------------------------------- /library/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=CannyViewAnimator 2 | POM_ARTIFACT_ID=cannyviewanimator 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Danil\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /library/src/androidTest/java/com/livetyping/library/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/CannyViewAnimator.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.animation.AnimatorSet; 6 | import android.animation.ValueAnimator; 7 | import android.content.Context; 8 | import android.content.res.TypedArray; 9 | import android.os.Build; 10 | import android.support.annotation.IntDef; 11 | import android.util.AttributeSet; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | 15 | import com.livetyping.library.animators.property.PropertyAnimators; 16 | import com.livetyping.library.animators.reveal.RevealAnimators; 17 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 18 | import com.livetyping.library.interfaces.InAnimator; 19 | import com.livetyping.library.interfaces.OutAnimator; 20 | 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.util.ArrayList; 24 | import java.util.Arrays; 25 | import java.util.HashMap; 26 | import java.util.List; 27 | import java.util.Map; 28 | 29 | public class CannyViewAnimator extends TransitionViewAnimator { 30 | 31 | public static final int SEQUENTIALLY = 1; 32 | public static final int TOGETHER = 2; 33 | private int animateType = SEQUENTIALLY; 34 | 35 | @Retention(RetentionPolicy.SOURCE) 36 | @IntDef({SEQUENTIALLY, TOGETHER}) 37 | @interface AnimateType { 38 | } 39 | 40 | 41 | public static final int FOR_POSITION = 1; 42 | public static final int IN_ALWAYS_TOP = 2; 43 | public static final int OUT_ALWAYS_TOP = 3; 44 | private int locationType = FOR_POSITION; 45 | 46 | @Retention(RetentionPolicy.SOURCE) 47 | @IntDef({FOR_POSITION, IN_ALWAYS_TOP, OUT_ALWAYS_TOP}) 48 | @interface LocationType { 49 | } 50 | 51 | private List inAnimator; 52 | private List outAnimator; 53 | private final Map attachedList = new HashMap<>(getChildCount()); 54 | 55 | 56 | public CannyViewAnimator(Context context) { 57 | super(context); 58 | } 59 | 60 | public CannyViewAnimator(Context context, AttributeSet attrs) { 61 | super(context, attrs); 62 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CannyViewAnimator, 0, 0); 63 | int animateType = a.getInt(R.styleable.CannyViewAnimator_animate_type, 1); 64 | int locationType = a.getInt(R.styleable.CannyViewAnimator_location_type, 1); 65 | int preLollipopIn = a.getInt(R.styleable.CannyViewAnimator_pre_lollipop_in, -1); 66 | int preLollipopOut = a.getInt(R.styleable.CannyViewAnimator_pre_lollipop_out, -1); 67 | int in = a.getInt(R.styleable.CannyViewAnimator_in, 0); 68 | int out = a.getInt(R.styleable.CannyViewAnimator_out, 0); 69 | a.recycle(); 70 | this.animateType = animateType; 71 | this.locationType = locationType; 72 | boolean preLollipop = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP; 73 | setInAnimator(getAnimators((preLollipop && preLollipopIn != -1) ? preLollipopIn : in)); 74 | setOutAnimator(getAnimators((preLollipop && preLollipopOut != -1) ? preLollipopOut : out)); 75 | } 76 | 77 | private ArrayList getAnimators(int flags) { 78 | boolean preLollipop = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP; 79 | ArrayList animators = new ArrayList<>(); 80 | int size = PropertyAnimators.values().length; 81 | size = preLollipop ? size : size + RevealAnimators.values().length; 82 | List defaultAnimators = new ArrayList<>(size); 83 | defaultAnimators.addAll(Arrays.asList(PropertyAnimators.values())); 84 | if (!preLollipop) 85 | defaultAnimators.addAll(Arrays.asList(RevealAnimators.values())); 86 | for (int i = 0; i < size; i++) { 87 | if ((flags & (int) Math.pow(2, i)) == Math.pow(2, i)) { 88 | animators.add(defaultAnimators.get(i)); 89 | } 90 | } 91 | return animators; 92 | } 93 | 94 | @SafeVarargs 95 | public final void setInAnimator(T... inAnimators) { 96 | setInAnimator(Arrays.asList(inAnimators)); 97 | } 98 | 99 | public void setInAnimator(List inAnimators) { 100 | this.inAnimator = inAnimators; 101 | } 102 | 103 | @SafeVarargs 104 | public final void setOutAnimator(T... outAnimators) { 105 | setOutAnimator(Arrays.asList(outAnimators)); 106 | } 107 | 108 | public void setOutAnimator(List outAnimators) { 109 | this.outAnimator = outAnimators; 110 | } 111 | 112 | @Override 113 | protected void changeVisibility(View inChild, View outChild) { 114 | if (attachedList.get(outChild) && attachedList.get(inChild)) { 115 | AnimatorSet animatorSet = new AnimatorSet(); 116 | Animator inAnimator = mergeInAnimators(inChild, outChild); 117 | Animator outAnimator = mergeOutAnimators(inChild, outChild); 118 | prepareTransition(inChild, outChild); 119 | 120 | switch (animateType) { 121 | case SEQUENTIALLY: 122 | animatorSet.playSequentially(outAnimator, inAnimator); 123 | break; 124 | case TOGETHER: 125 | animatorSet.playTogether(outAnimator, inAnimator); 126 | break; 127 | } 128 | 129 | switch (locationType) { 130 | case FOR_POSITION: 131 | addOnStartVisibleListener(inAnimator, inChild); 132 | addOnEndInvisibleListener(outAnimator, outChild); 133 | break; 134 | case IN_ALWAYS_TOP: 135 | addOnStartVisibleListener(inAnimator, inChild); 136 | addOnEndInvisibleListener(inAnimator, outChild); 137 | addOnStartToTopOnEndToInitPositionListener(inAnimator, inChild); 138 | break; 139 | case OUT_ALWAYS_TOP: 140 | addOnStartVisibleListener(outAnimator, inChild); 141 | addOnEndInvisibleListener(outAnimator, outChild); 142 | addOnStartToTopOnEndToInitPositionListener(outAnimator, outChild); 143 | break; 144 | } 145 | animatorSet.start(); 146 | } else { 147 | super.changeVisibility(inChild, outChild); 148 | } 149 | } 150 | 151 | private AnimatorSet mergeInAnimators(final View inChild, final View outChild) { 152 | AnimatorSet animatorSet = new AnimatorSet(); 153 | List animators = new ArrayList<>(inAnimator.size()); 154 | for (InAnimator inAnimator : this.inAnimator) { 155 | if (inAnimator != null) { 156 | Animator animator = inAnimator.getInAnimator(inChild, outChild); 157 | if (animator != null) { 158 | animators.add(animator); 159 | } 160 | } 161 | } 162 | animatorSet.playTogether(animators); 163 | return animatorSet; 164 | } 165 | 166 | private AnimatorSet mergeOutAnimators(final View inChild, final View outChild) { 167 | AnimatorSet animatorSet = new AnimatorSet(); 168 | List animators = new ArrayList<>(outAnimator.size()); 169 | for (OutAnimator outAnimator : this.outAnimator) { 170 | if (outAnimator != null) { 171 | Animator animator = outAnimator.getOutAnimator(inChild, outChild); 172 | if (animator != null) 173 | animators.add(animator); 174 | } 175 | } 176 | animatorSet.playTogether(animators); 177 | addRestoreInitValuesListener(animatorSet); 178 | return animatorSet; 179 | } 180 | 181 | private void addRestoreInitValuesListener(AnimatorSet animatorSet) { 182 | for (Animator animator : animatorSet.getChildAnimations()) { 183 | if (animator instanceof ValueAnimator) { 184 | animator.addListener(new AnimatorListenerAdapter() { 185 | @Override 186 | public void onAnimationEnd(Animator animation) { 187 | animation.removeListener(this); 188 | animation.setDuration(0); 189 | ((ValueAnimator) animation).reverse(); 190 | } 191 | }); 192 | } 193 | } 194 | } 195 | 196 | private void addOnStartVisibleListener(Animator animator, final View view) { 197 | animator.addListener(new AnimatorListenerAdapter() { 198 | @Override 199 | public void onAnimationStart(Animator animation) { 200 | startTransition(); 201 | view.setVisibility(VISIBLE); 202 | } 203 | }); 204 | } 205 | 206 | private void addOnEndInvisibleListener(Animator animator, final View view) { 207 | animator.addListener(new AnimatorListenerAdapter() { 208 | @Override 209 | public void onAnimationEnd(Animator animation) { 210 | startTransition(); 211 | view.setVisibility(INVISIBLE); 212 | } 213 | }); 214 | } 215 | 216 | private void addOnStartToTopOnEndToInitPositionListener(Animator animator, final View view) { 217 | final int initLocation = indexOfChild(view); 218 | animator.addListener(new AnimatorListenerAdapter() { 219 | @Override 220 | public void onAnimationStart(Animator animation) { 221 | bringChildToPosition(view, getChildCount() - 1); 222 | } 223 | 224 | @Override 225 | public void onAnimationEnd(Animator animation) { 226 | bringChildToPosition(view, initLocation); 227 | } 228 | }); 229 | } 230 | 231 | public int getAnimateType() { 232 | return animateType; 233 | } 234 | 235 | public void setAnimateType(@AnimateType int animateType) { 236 | this.animateType = animateType; 237 | } 238 | 239 | public int getLocationType() { 240 | return locationType; 241 | } 242 | 243 | public void setLocationType(@LocationType int locationType) { 244 | this.locationType = locationType; 245 | } 246 | 247 | @Override 248 | public void addView(View child, int index, ViewGroup.LayoutParams params) { 249 | attachedList.put(child, false); 250 | child.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { 251 | @Override 252 | public void onViewAttachedToWindow(View v) { 253 | attachedList.put(v, true); 254 | } 255 | 256 | @Override 257 | public void onViewDetachedFromWindow(View v) { 258 | attachedList.put(v, false); 259 | } 260 | }); 261 | super.addView(child, index, params); 262 | } 263 | 264 | @Override 265 | public void removeAllViews() { 266 | attachedList.clear(); 267 | super.removeAllViews(); 268 | } 269 | 270 | @Override 271 | public void removeView(View view) { 272 | attachedList.remove(view); 273 | super.removeView(view); 274 | } 275 | 276 | @Override 277 | public void removeViewAt(int index) { 278 | attachedList.remove(getChildAt(index)); 279 | super.removeViewAt(index); 280 | } 281 | 282 | @Override 283 | public void removeViews(int start, int count) { 284 | for (int i = start; i < start + count; i++) { 285 | attachedList.remove(getChildAt(i)); 286 | } 287 | super.removeViews(start, count); 288 | } 289 | 290 | } 291 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/TransitionViewAnimator.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.support.transition.Transition; 6 | import android.support.transition.TransitionManager; 7 | import android.util.AttributeSet; 8 | import android.view.View; 9 | 10 | import com.livetyping.library.interfaces.CannyTransition; 11 | 12 | /** 13 | * Created by Danil on 16.07.2016. 14 | */ 15 | public class TransitionViewAnimator extends ViewAnimator { 16 | private CannyTransition cannyTransition; 17 | private Transition transition; 18 | 19 | public TransitionViewAnimator(Context context) { 20 | super(context); 21 | } 22 | 23 | public TransitionViewAnimator(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | @Override 28 | protected void changeVisibility(View inChild, View outChild) { 29 | prepareTransition(inChild, outChild); 30 | startTransition(); 31 | super.changeVisibility(inChild, outChild); 32 | } 33 | 34 | protected void prepareTransition(View inChild, View outChild) { 35 | if (cannyTransition != null) { 36 | transition = cannyTransition.getTransition(inChild, outChild); 37 | } 38 | } 39 | 40 | public void startTransition() { 41 | if (transition != null) { 42 | TransitionManager.beginDelayedTransition(this, transition); 43 | } 44 | } 45 | 46 | public void setCannyTransition(CannyTransition cannyTransition) { 47 | this.cannyTransition = cannyTransition; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/ViewAnimator.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library; 2 | 3 | import android.content.Context; 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | import android.support.annotation.IdRes; 7 | import android.util.AttributeSet; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | 12 | import java.lang.reflect.Field; 13 | import java.lang.reflect.InvocationTargetException; 14 | import java.lang.reflect.Method; 15 | 16 | public class ViewAnimator extends FrameLayout { 17 | 18 | private int lastWhichIndex = 0; 19 | 20 | public ViewAnimator(Context context) { 21 | super(context); 22 | } 23 | 24 | public ViewAnimator(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public void setDisplayedChildIndex(int inChildIndex) { 29 | if (inChildIndex >= getChildCount()) { 30 | inChildIndex = 0; 31 | } else if (inChildIndex < 0) { 32 | inChildIndex = getChildCount() - 1; 33 | } 34 | boolean hasFocus = getFocusedChild() != null; 35 | int outChildIndex = lastWhichIndex; 36 | lastWhichIndex = inChildIndex; 37 | changeVisibility(getChildAt(inChildIndex), getChildAt(outChildIndex)); 38 | if (hasFocus) { 39 | requestFocus(FOCUS_FORWARD); 40 | } 41 | } 42 | 43 | public void setDisplayedChildId(@IdRes int id) { 44 | if (getDisplayedChildId() == id) { 45 | return; 46 | } 47 | for (int i = 0, count = getChildCount(); i < count; i++) { 48 | if (getChildAt(i).getId() == id) { 49 | setDisplayedChildIndex(i); 50 | return; 51 | } 52 | } 53 | throw new IllegalArgumentException("No view with ID " + id); 54 | } 55 | 56 | public void setDisplayedChild(View view) { 57 | setDisplayedChildId(view.getId()); 58 | } 59 | 60 | public int getDisplayedChildIndex() { 61 | return lastWhichIndex; 62 | } 63 | 64 | public View getDisplayedChild() { 65 | return getChildAt(lastWhichIndex); 66 | } 67 | 68 | public int getDisplayedChildId() { 69 | return getDisplayedChild().getId(); 70 | } 71 | 72 | protected void changeVisibility(View inChild, View outChild) { 73 | outChild.setVisibility(INVISIBLE); 74 | inChild.setVisibility(VISIBLE); 75 | } 76 | 77 | @Override 78 | public void addView(View child, int index, ViewGroup.LayoutParams params) { 79 | super.addView(child, index, params); 80 | if (getChildCount() == 1) { 81 | child.setVisibility(View.VISIBLE); 82 | } else { 83 | child.setVisibility(View.INVISIBLE); 84 | } 85 | if (index >= 0 && lastWhichIndex >= index) { 86 | setDisplayedChildIndex(lastWhichIndex + 1); 87 | } 88 | } 89 | 90 | @Override 91 | public void removeAllViews() { 92 | super.removeAllViews(); 93 | lastWhichIndex = 0; 94 | } 95 | 96 | @Override 97 | public void removeView(View view) { 98 | final int index = indexOfChild(view); 99 | if (index >= 0) { 100 | removeViewAt(index); 101 | } 102 | } 103 | 104 | @Override 105 | public void removeViewAt(int index) { 106 | super.removeViewAt(index); 107 | final int childCount = getChildCount(); 108 | if (childCount == 0) { 109 | lastWhichIndex = 0; 110 | } else if (lastWhichIndex >= childCount) { 111 | setDisplayedChildIndex(childCount - 1); 112 | } else if (lastWhichIndex == index) { 113 | setDisplayedChildIndex(lastWhichIndex); 114 | } 115 | } 116 | 117 | @Override 118 | public void removeViewInLayout(View view) { 119 | removeView(view); 120 | } 121 | 122 | @Override 123 | public void removeViews(int start, int count) { 124 | super.removeViews(start, count); 125 | if (getChildCount() == 0) { 126 | lastWhichIndex = 0; 127 | } else if (lastWhichIndex >= start && lastWhichIndex < start + count) { 128 | setDisplayedChildIndex(lastWhichIndex); 129 | } 130 | } 131 | 132 | @Override 133 | public void removeViewsInLayout(int start, int count) { 134 | removeViews(start, count); 135 | } 136 | 137 | public void bringChildToPosition(View child, int position) { 138 | final int index = indexOfChild(child); 139 | if (index < 0 && position >= getChildCount()) return; 140 | try { 141 | Method removeFromArray = ViewGroup.class.getDeclaredMethod("removeFromArray", int.class); 142 | removeFromArray.setAccessible(true); 143 | removeFromArray.invoke(this, index); 144 | Method addInArray = ViewGroup.class.getDeclaredMethod("addInArray", View.class, int.class); 145 | addInArray.setAccessible(true); 146 | addInArray.invoke(this, child, position); 147 | Field mParent = View.class.getDeclaredField("mParent"); 148 | mParent.setAccessible(true); 149 | mParent.set(child, this); 150 | } catch (NoSuchMethodException e) { 151 | e.printStackTrace(); 152 | } catch (InvocationTargetException e) { 153 | e.printStackTrace(); 154 | } catch (IllegalAccessException e) { 155 | e.printStackTrace(); 156 | } catch (NoSuchFieldException e) { 157 | e.printStackTrace(); 158 | } 159 | } 160 | 161 | @Override 162 | protected void onRestoreInstanceState(Parcelable state) { 163 | if (!(state instanceof SavedState)) { 164 | super.onRestoreInstanceState(state); 165 | return; 166 | } 167 | SavedState ss = (SavedState) state; 168 | super.onRestoreInstanceState(ss.getSuperState()); 169 | lastWhichIndex = ss.lastWhichIndex; 170 | setDisplayedChildIndex(lastWhichIndex); 171 | } 172 | 173 | @Override 174 | protected Parcelable onSaveInstanceState() { 175 | SavedState savedState = new SavedState(super.onSaveInstanceState()); 176 | savedState.lastWhichIndex = lastWhichIndex; 177 | return savedState; 178 | } 179 | 180 | public static class SavedState extends View.BaseSavedState { 181 | int lastWhichIndex; 182 | 183 | SavedState(Parcelable superState) { 184 | super(superState); 185 | } 186 | 187 | @Override 188 | public void writeToParcel(Parcel dest, int flags) { 189 | super.writeToParcel(dest, flags); 190 | dest.writeInt(this.lastWhichIndex); 191 | } 192 | 193 | @Override 194 | public String toString() { 195 | return "ViewAnimator.SavedState{" + 196 | "lastWhichIndex=" + lastWhichIndex + 197 | '}'; 198 | } 199 | 200 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 201 | @Override 202 | public SavedState createFromParcel(Parcel source) { 203 | return new SavedState(source); 204 | } 205 | 206 | @Override 207 | public SavedState[] newArray(int size) { 208 | return new SavedState[size]; 209 | } 210 | }; 211 | 212 | protected SavedState(Parcel in) { 213 | super(in); 214 | this.lastWhichIndex = in.readInt(); 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/property/PropertyAnimators.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.property; 2 | 3 | import android.animation.Animator; 4 | import android.annotation.SuppressLint; 5 | import android.view.View; 6 | 7 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 8 | import com.livetyping.library.interfaces.InAnimator; 9 | import com.livetyping.library.interfaces.OutAnimator; 10 | 11 | @SuppressLint("RtlHardcoded") 12 | public enum PropertyAnimators implements DefaultCannyAnimators { 13 | EMPTY(new PropertyIn(), new PropertyOut()), 14 | //alpha 15 | ALPHA(new PropertyIn(View.ALPHA, 0, 1), new PropertyOut(View.ALPHA, 1, 0)), 16 | ALPHA_HALF(new PropertyIn(View.ALPHA, 0.5f, 1), new PropertyOut(View.ALPHA, 1, 0.5f)), 17 | //scale 18 | SCALE_X(new PropertyIn(View.SCALE_X, 0, 1), new PropertyOut(View.SCALE_X, 1, 0)), 19 | SCALE_X_HALF(new PropertyIn(View.SCALE_X, 0.5f, 1), new PropertyOut(View.SCALE_X, 1, 0.5f)), 20 | SCALE_Y(new PropertyIn(View.SCALE_Y, 0, 1), new PropertyOut(View.SCALE_Y, 1, 0)), 21 | SCALE_Y_HALF(new PropertyIn(View.SCALE_Y, 0.5f, 1), new PropertyOut(View.SCALE_Y, 1, 0.5f)), 22 | //rotation 23 | ROTATION_90(new PropertyIn(View.ROTATION, 90, 0), new PropertyOut(View.ROTATION, 0, 90)), 24 | ROTATION_180(new PropertyIn(View.ROTATION, 180, 0), new PropertyOut(View.ROTATION, 0, 180)), 25 | ROTATION_360(new PropertyIn(View.ROTATION, 360, 0), new PropertyOut(View.ROTATION, 0, 360)), 26 | ROTATION_M90(new PropertyIn(View.ROTATION, -90, 0), new PropertyOut(View.ROTATION, 0, -90)), 27 | ROTATION_M180(new PropertyIn(View.ROTATION, -180, 0), new PropertyOut(View.ROTATION, 0, -180)), 28 | ROTATION_M360(new PropertyIn(View.ROTATION, -360, 0), new PropertyOut(View.ROTATION, 0, -360)), 29 | //rotation x 30 | ROTATION_X_90(new PropertyIn(View.ROTATION_X, 90, 0), new PropertyOut(View.ROTATION_X, 0, 90)), 31 | ROTATION_X_360(new PropertyIn(View.ROTATION_X, 360, 0), new PropertyOut(View.ROTATION_X, 0, 360)), 32 | ROTATION_X_M90(new PropertyIn(View.ROTATION_X, -90, 0), new PropertyOut(View.ROTATION_X, 0, -90)), 33 | ROTATION_X_M360(new PropertyIn(View.ROTATION_X, -360, 0), new PropertyOut(View.ROTATION_X, 0, -360)), 34 | //rotation y 35 | ROTATION_Y_90(new PropertyIn(View.ROTATION_Y, 90, 0), new PropertyOut(View.ROTATION_Y, 0, 90)), 36 | ROTATION_Y_360(new PropertyIn(View.ROTATION_Y, 360, 0), new PropertyOut(View.ROTATION_Y, 0, 360)), 37 | ROTATION_Y_M90(new PropertyIn(View.ROTATION_Y, -90, 0), new PropertyOut(View.ROTATION_Y, 0, -90)), 38 | ROTATION_Y_M360(new PropertyIn(View.ROTATION_Y, -360, 0), new PropertyOut(View.ROTATION_Y, 0, -360)); 39 | private InAnimator inAnimator; 40 | private OutAnimator outAnimator; 41 | 42 | PropertyAnimators(InAnimator inAnimator, 43 | OutAnimator outAnimator) { 44 | this.inAnimator = inAnimator; 45 | this.outAnimator = outAnimator; 46 | } 47 | 48 | public String getName() { 49 | return name(); 50 | } 51 | 52 | 53 | @Override 54 | public Animator getInAnimator(View inChild, View outChild) { 55 | return inAnimator.getInAnimator(inChild, outChild); 56 | } 57 | 58 | @Override 59 | public Animator getOutAnimator(View inChild, View outChild) { 60 | return outAnimator.getOutAnimator(inChild, outChild); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/property/PropertyCanny.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.property; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.PropertyValuesHolder; 6 | import android.util.Property; 7 | import android.view.View; 8 | 9 | class PropertyCanny { 10 | Animator propertyAnimator; 11 | 12 | public PropertyCanny(PropertyValuesHolder... holders) { 13 | this.propertyAnimator = ObjectAnimator.ofPropertyValuesHolder(holders); 14 | } 15 | 16 | public PropertyCanny(Property property, float start, float end) { 17 | this.propertyAnimator = ObjectAnimator.ofFloat(null, property, start, end); 18 | } 19 | 20 | public PropertyCanny(String propertyName, float start, float end) { 21 | this.propertyAnimator = ObjectAnimator.ofFloat(null, propertyName, start, end); 22 | } 23 | 24 | public Animator getPropertyAnimator(View child) { 25 | propertyAnimator.setTarget(child); 26 | return propertyAnimator.clone(); 27 | } 28 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/property/PropertyIn.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.property; 2 | 3 | import android.animation.Animator; 4 | import android.animation.PropertyValuesHolder; 5 | import android.util.Property; 6 | import android.view.View; 7 | 8 | import com.livetyping.library.interfaces.InAnimator; 9 | 10 | public class PropertyIn extends PropertyCanny implements InAnimator { 11 | 12 | public PropertyIn(PropertyValuesHolder... holders) { 13 | super(holders); 14 | } 15 | 16 | public PropertyIn(Property property, float start, float end) { 17 | super(property, start, end); 18 | } 19 | 20 | public PropertyIn(String propertyName, float start, float end) { 21 | super(propertyName, start, end); 22 | } 23 | 24 | public PropertyIn setDuration(long millis) { 25 | propertyAnimator.setDuration(millis); 26 | return this; 27 | } 28 | 29 | @Override 30 | public Animator getInAnimator(View inChild, View outChild) { 31 | return getPropertyAnimator(inChild); 32 | } 33 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/property/PropertyOut.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.property; 2 | 3 | import android.animation.Animator; 4 | import android.animation.PropertyValuesHolder; 5 | import android.util.Property; 6 | import android.view.View; 7 | 8 | import com.livetyping.library.interfaces.OutAnimator; 9 | 10 | public class PropertyOut extends PropertyCanny implements OutAnimator { 11 | 12 | public PropertyOut(PropertyValuesHolder... holders) { 13 | super(holders); 14 | } 15 | 16 | public PropertyOut(Property property, float start, float end) { 17 | super(property, start, end); 18 | } 19 | 20 | public PropertyOut(String propertyName, float start, float end) { 21 | super(propertyName, start, end); 22 | } 23 | 24 | public PropertyOut setDuration(long millis) { 25 | propertyAnimator.setDuration(millis); 26 | return this; 27 | } 28 | 29 | @Override 30 | public Animator getOutAnimator(View inChild, View outChild) { 31 | return getPropertyAnimator(outChild); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/reveal/RevealAnimators.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.reveal; 2 | 3 | import android.animation.Animator; 4 | import android.annotation.SuppressLint; 5 | import android.annotation.TargetApi; 6 | import android.os.Build; 7 | import android.view.Gravity; 8 | import android.view.View; 9 | 10 | import com.livetyping.library.interfaces.DefaultCannyAnimators; 11 | import com.livetyping.library.interfaces.InAnimator; 12 | import com.livetyping.library.interfaces.OutAnimator; 13 | 14 | /** 15 | * Created by Danil on 09.05.2016. 16 | */ 17 | @SuppressLint("RtlHardcoded") 18 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 19 | public enum RevealAnimators implements DefaultCannyAnimators { 20 | CIRCULAR_REVEAL_TOP_CENTER(new RevealIn(Gravity.TOP | Gravity.CENTER_HORIZONTAL), 21 | new RevealOut(Gravity.TOP | Gravity.CENTER_HORIZONTAL)), 22 | CIRCULAR_REVEAL_TOP_LEFT(new RevealIn(Gravity.TOP | Gravity.LEFT), 23 | new RevealOut(Gravity.TOP | Gravity.LEFT)), 24 | CIRCULAR_REVEAL_TOP_RIGHT(new RevealIn(Gravity.TOP | Gravity.RIGHT), 25 | new RevealOut(Gravity.TOP | Gravity.RIGHT)), 26 | CIRCULAR_REVEAL_BOTTOM_CENTER(new RevealIn(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL), 27 | new RevealOut(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL)), 28 | CIRCULAR_REVEAL_BOTTOM_LEFT(new RevealIn(Gravity.BOTTOM | Gravity.LEFT), 29 | new RevealOut(Gravity.BOTTOM | Gravity.LEFT)), 30 | CIRCULAR_REVEAL_BOTTOM_RIGHT(new RevealIn(Gravity.BOTTOM | Gravity.RIGHT), 31 | new RevealOut(Gravity.BOTTOM | Gravity.RIGHT)), 32 | CIRCULAR_REVEAL_CENTER_LEFT(new RevealIn(Gravity.LEFT | Gravity.CENTER_VERTICAL), 33 | new RevealOut(Gravity.LEFT | Gravity.CENTER_VERTICAL)), 34 | CIRCULAR_REVEAL_CENTER_RIGHT(new RevealIn(Gravity.RIGHT | Gravity.CENTER_VERTICAL), 35 | new RevealOut(Gravity.RIGHT | Gravity.CENTER_VERTICAL)), 36 | CIRCULAR_REVEAL_CENTER(new RevealIn(Gravity.CENTER), 37 | new RevealOut(Gravity.CENTER)); 38 | 39 | 40 | private InAnimator inAnimator; 41 | private OutAnimator outAnimator; 42 | 43 | RevealAnimators(InAnimator inAnimator, 44 | OutAnimator outAnimator) { 45 | this.inAnimator = inAnimator; 46 | this.outAnimator = outAnimator; 47 | } 48 | 49 | @Override 50 | public String getName() { 51 | return name(); 52 | } 53 | 54 | 55 | @Override 56 | public Animator getInAnimator(View inChild, View outChild) { 57 | return inAnimator.getInAnimator(inChild, outChild); 58 | } 59 | 60 | @Override 61 | public Animator getOutAnimator(View inChild, View outChild) { 62 | return outAnimator.getOutAnimator(inChild, outChild); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/reveal/RevealCanny.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.reveal; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.view.Gravity; 5 | import android.view.View; 6 | 7 | class RevealCanny { 8 | private final int gravity; 9 | 10 | public RevealCanny(int gravity) { 11 | this.gravity = gravity; 12 | } 13 | 14 | @SuppressLint("RtlHardcoded") 15 | protected int getCenterX(View view) { 16 | final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; 17 | if (horizontalGravity == Gravity.LEFT) { 18 | return 0; 19 | } else if (horizontalGravity == Gravity.RIGHT) { 20 | return view.getWidth(); 21 | } else { // (Gravity.CENTER_HORIZONTAL) 22 | return view.getWidth() / 2; 23 | } 24 | } 25 | 26 | protected int getCenterY(View view) { 27 | final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; 28 | if (verticalGravity == Gravity.TOP) { 29 | return 0; 30 | } else if (verticalGravity == Gravity.BOTTOM) { 31 | return view.getHeight(); 32 | } else { // (Gravity.CENTER_VERTICAL) 33 | return view.getHeight() / 2; 34 | } 35 | } 36 | 37 | public int getGravity() { 38 | return gravity; 39 | } 40 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/reveal/RevealIn.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.reveal; 2 | 3 | import android.animation.Animator; 4 | import android.annotation.TargetApi; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.ViewAnimationUtils; 8 | 9 | import com.livetyping.library.interfaces.InAnimator; 10 | 11 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 12 | public class RevealIn extends RevealCanny implements InAnimator { 13 | 14 | public RevealIn(int gravity) { 15 | super(gravity); 16 | } 17 | 18 | @Override 19 | public Animator getInAnimator(View inChild, View outChild) { 20 | float inRadius = (float) Math.hypot(inChild.getWidth(), inChild.getHeight()); 21 | return ViewAnimationUtils.createCircularReveal(inChild, getCenterX(inChild), 22 | getCenterY(inChild), 0, inRadius); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/animators/reveal/RevealOut.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.animators.reveal; 2 | 3 | import android.animation.Animator; 4 | import android.annotation.TargetApi; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.ViewAnimationUtils; 8 | 9 | import com.livetyping.library.interfaces.OutAnimator; 10 | 11 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 12 | public class RevealOut extends RevealCanny implements OutAnimator { 13 | 14 | public RevealOut(int gravity) { 15 | super(gravity); 16 | } 17 | 18 | @Override 19 | public Animator getOutAnimator(View inChild, View outChild) { 20 | float outRadius = (float) Math.hypot(outChild.getWidth(), outChild.getHeight()); 21 | return ViewAnimationUtils.createCircularReveal(outChild, getCenterX(outChild), 22 | getCenterY(outChild), outRadius, 0); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/interfaces/CannyTransition.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.interfaces; 2 | 3 | import android.support.transition.Transition; 4 | import android.view.View; 5 | 6 | public interface CannyTransition { 7 | Transition getTransition(View inChild, View outChild); 8 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/interfaces/DefaultCannyAnimators.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.interfaces; 2 | 3 | /** 4 | * Created by Danil on 09.05.2016. 5 | */ 6 | public interface DefaultCannyAnimators extends InAnimator, OutAnimator { 7 | String getName(); 8 | } 9 | -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/interfaces/InAnimator.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.interfaces; 2 | 3 | import android.animation.Animator; 4 | import android.view.View; 5 | 6 | public interface InAnimator { 7 | Animator getInAnimator(View inChild, View outChild); 8 | } -------------------------------------------------------------------------------- /library/src/main/java/com/livetyping/library/interfaces/OutAnimator.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library.interfaces; 2 | 3 | import android.animation.Animator; 4 | import android.view.View; 5 | 6 | public interface OutAnimator { 7 | Animator getOutAnimator(View inChild, View outChild); 8 | } -------------------------------------------------------------------------------- /library/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /library/src/test/java/com/livetyping/library/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.livetyping.library; 2 | 3 | /** 4 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 5 | */ 6 | public class ExampleUnitTest { 7 | } -------------------------------------------------------------------------------- /readme_extra/parallax.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/parallax.gif -------------------------------------------------------------------------------- /readme_extra/top_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/top_1.gif -------------------------------------------------------------------------------- /readme_extra/top_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/top_2.gif -------------------------------------------------------------------------------- /readme_extra/top_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/top_3.gif -------------------------------------------------------------------------------- /readme_extra/transition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/transition.gif -------------------------------------------------------------------------------- /readme_extra/u2020.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/u2020.gif -------------------------------------------------------------------------------- /readme_extra/xml.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiveTyping/CannyViewAnimator/6e3789dec637bb6710eff47141e2a20200c2c084/readme_extra/xml.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':library' 2 | --------------------------------------------------------------------------------