Skip to content

Commit 2cf1804

Browse files
author
chetan-fueled
committed
feat(*): transition for shared elements
1 parent 38f3cac commit 2cf1804

File tree

9 files changed

+267
-4
lines changed

9 files changed

+267
-4
lines changed

flowr/src/main/java/com/fueled/flowr/Flowr.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import android.content.Intent;
44
import android.content.pm.ActivityInfo;
55
import android.net.Uri;
6+
import android.os.Build;
67
import android.os.Bundle;
78
import android.support.annotation.AnimRes;
89
import android.support.annotation.IdRes;
910
import android.support.annotation.NonNull;
1011
import android.support.annotation.Nullable;
12+
import android.support.annotation.RequiresApi;
1113
import android.support.v4.app.Fragment;
1214
import android.support.v4.app.FragmentManager;
1315
import android.support.v4.app.FragmentTransaction;
@@ -18,6 +20,7 @@
1820
import com.fueled.flowr.internal.FlowrDeepLinkHandler;
1921
import com.fueled.flowr.internal.FlowrDeepLinkInfo;
2022
import com.fueled.flowr.internal.TransactionData;
23+
import com.fueled.flowr.internal.TransitionConfig;
2124

2225
import java.util.ArrayList;
2326
import java.util.Collections;
@@ -267,6 +270,10 @@ protected <T extends Fragment & FlowrFragment> void displayFragment(TransactionD
267270
Fragment fragment = data.getFragmentClass().newInstance();
268271
fragment.setArguments(data.getArgs());
269272

273+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && data.getTransitionConfig() != null) {
274+
setTransitions(fragment, data.getTransitionConfig());
275+
}
276+
270277
FragmentTransaction transaction = screen.getScreenFragmentManager().beginTransaction();
271278

272279
if (!data.isSkipBackStack()) {
@@ -282,6 +289,11 @@ protected <T extends Fragment & FlowrFragment> void displayFragment(TransactionD
282289
transaction.add(mainContainerId, fragment);
283290
}
284291

292+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && data.getTransitionConfig() != null &&
293+
data.getSharedElements() != null && data.getSharedElements().length > 0) {
294+
addSharedElements(transaction, data.getSharedElements());
295+
}
296+
285297
transaction.commit();
286298

287299
if (data.isSkipBackStack()) {
@@ -323,6 +335,33 @@ private <T extends Fragment & FlowrFragment> void injectDeepLinkInfo(Transaction
323335
}
324336
}
325337

338+
/**
339+
* Set transitions to the destination fragment from @{@link TransitionConfig}.
340+
*
341+
* @param fragment The destination Fragment.
342+
* @param transitionConfig The transition configuration @{@link TransitionConfig}.
343+
*/
344+
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
345+
private void setTransitions(Fragment fragment, TransitionConfig transitionConfig) {
346+
fragment.setEnterTransition(transitionConfig.enter);
347+
fragment.setSharedElementEnterTransition(transitionConfig.sharedElementEnter);
348+
fragment.setExitTransition(transitionConfig.exit);
349+
fragment.setSharedElementReturnTransition(transitionConfig.sharedElementExit);
350+
}
351+
352+
/**
353+
* Add shared elements to a Fragment Transaction.
354+
*
355+
* @param transaction The transaction that will.
356+
* @param views The shared elements.
357+
*/
358+
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
359+
private void addSharedElements(FragmentTransaction transaction, View[] views) {
360+
for (View view : views) {
361+
transaction.addSharedElement(view, view.getTransitionName());
362+
}
363+
}
364+
326365
/**
327366
* Set a Custom Animation to a Fragment transaction
328367
*
@@ -730,6 +769,18 @@ public Builder setCustomTransactionAnimation(@AnimRes int enterAnim, @AnimRes in
730769

731770
}
732771

772+
/**
773+
* Set transition between fragments.
774+
*
775+
* @param transitionConfig builder class for configuring fragment transitions
776+
* @param sharedElements array of shared elements
777+
*/
778+
public Builder setTransition(TransitionConfig transitionConfig, View... sharedElements) {
779+
data.setTransitionConfig(transitionConfig);
780+
data.setSharedElements(sharedElements);
781+
return this;
782+
}
783+
733784
/**
734785
* Don't use any animations for this transaction
735786
*/

flowr/src/main/java/com/fueled/flowr/internal/TransactionData.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import android.os.Bundle;
55
import android.support.v4.app.Fragment;
66
import android.support.v4.app.FragmentTransaction;
7+
import android.view.View;
78

89
import com.fueled.flowr.FlowrFragment;
910

@@ -23,6 +24,8 @@ public final class TransactionData<T extends Fragment & FlowrFragment> {
2324
private int popEnterAnim;
2425
private int popExitAnim;
2526
private Intent deepLinkIntent;
27+
private View[] sharedElements;
28+
private TransitionConfig transitionConfig;
2629

2730
public TransactionData(Class<? extends T> fragmentClass) {
2831
this(fragmentClass, FragmentTransaction.TRANSIT_NONE, FragmentTransaction.TRANSIT_NONE);
@@ -121,4 +124,20 @@ public int getExitAnim() {
121124
public void setExitAnim(int exitAnim) {
122125
this.exitAnim = exitAnim;
123126
}
127+
128+
public View[] getSharedElements() {
129+
return sharedElements;
130+
}
131+
132+
public void setSharedElements(View[] sharedElements) {
133+
this.sharedElements = sharedElements;
134+
}
135+
136+
public TransitionConfig getTransitionConfig() {
137+
return transitionConfig;
138+
}
139+
140+
public void setTransitionConfig(TransitionConfig transitionConfig) {
141+
this.transitionConfig = transitionConfig;
142+
}
124143
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.fueled.flowr.internal;
2+
3+
import android.os.Build;
4+
import android.support.annotation.RequiresApi;
5+
import android.transition.ChangeBounds;
6+
import android.transition.Explode;
7+
import android.transition.Fade;
8+
import android.transition.Slide;
9+
import android.transition.Transition;
10+
import android.view.Gravity;
11+
12+
/**
13+
* Copyright (c) 2017 Fueled. All rights reserved.
14+
*
15+
* @author chetansachdeva on 21/11/17
16+
*/
17+
18+
public class TransitionConfig {
19+
20+
public Transition sharedElementEnter;
21+
public Transition sharedElementExit;
22+
public Transition enter;
23+
public Transition exit;
24+
25+
private TransitionConfig(Builder builder) {
26+
sharedElementEnter = builder.sharedElementEnter;
27+
sharedElementExit = builder.sharedElementExit;
28+
enter = builder.enter;
29+
exit = builder.exit;
30+
}
31+
32+
public static final class Builder {
33+
private Transition sharedElementEnter;
34+
private Transition sharedElementExit;
35+
private Transition enter;
36+
private Transition exit;
37+
38+
public Builder() {
39+
}
40+
41+
public Builder sharedElementEnter(Transition val) {
42+
sharedElementEnter = val;
43+
return this;
44+
}
45+
46+
public Builder sharedElementExit(Transition val) {
47+
sharedElementExit = val;
48+
return this;
49+
}
50+
51+
public Builder enter(Transition val) {
52+
enter = val;
53+
return this;
54+
}
55+
56+
public Builder exit(Transition val) {
57+
exit = val;
58+
return this;
59+
}
60+
61+
public TransitionConfig build() {
62+
return new TransitionConfig(this);
63+
}
64+
}
65+
66+
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
67+
public static class Provider {
68+
public static Transition fade = new Fade();
69+
public static Transition explode = new Explode();
70+
public static Transition slideRight = new Slide(Gravity.RIGHT);
71+
public static Transition slideLeft = new Slide(Gravity.LEFT);
72+
public static Transition changeBounds = new ChangeBounds();
73+
}
74+
}

sample/src/main/java/com/fueled/flowr/sample/CategoriesFragment.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import android.view.View;
44

55
import com.fueled.flowr.NavigationIconType;
6+
import com.fueled.flowr.annotations.DeepLink;
67
import com.fueled.flowr.sample.core.AbstractFragment;
78

89
/**
910
* Created by [email protected] on 18/05/2017.
1011
* Copyright (c) 2017 Fueled. All rights reserved.
1112
*/
13+
14+
@DeepLink(value = {"/categories"})
1215
public class CategoriesFragment extends AbstractFragment {
1316

1417
@Override

sample/src/main/java/com/fueled/flowr/sample/HomeFragment.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.fueled.flowr.sample;
22

33
import android.databinding.DataBindingUtil;
4+
import android.os.Build;
5+
import android.support.annotation.NonNull;
46
import android.view.View;
57

68
import com.fueled.flowr.NavigationIconType;
9+
import com.fueled.flowr.internal.TransitionConfig;
710
import com.fueled.flowr.sample.core.AbstractFragment;
811
import com.fueled.flowr.sample.databinding.FragmentHomeBinding;
912

@@ -25,6 +28,7 @@ protected void setupView(View view) {
2528
binding = DataBindingUtil.bind(view);
2629
binding.homeOpenViewButton.setOnClickListener(this);
2730
binding.homeOpenLinkButton.setOnClickListener(this);
31+
binding.homeOpenTransitionButton.setOnClickListener(this);
2832
}
2933

3034
@Override
@@ -39,10 +43,18 @@ public NavigationIconType getNavigationIconType() {
3943

4044
@Override
4145
public void onClick(View view) {
42-
if (view.getId() == R.id.home_open_view_button) {
43-
displayViewFragment();
44-
} else {
45-
displayLinkFragment();
46+
switch (view.getId()) {
47+
case R.id.home_open_view_button:
48+
displayViewFragment();
49+
break;
50+
case R.id.home_open_link_button:
51+
displayLinkFragment();
52+
break;
53+
case R.id.home_open_transition_button:
54+
displayTransitionFragment();
55+
break;
56+
default:
57+
break;
4658
}
4759
}
4860

@@ -57,4 +69,24 @@ private void displayLinkFragment() {
5769
getFlowr().open("/hello")
5870
.displayFragment();
5971
}
72+
73+
private void displayTransitionFragment() {
74+
getFlowr().open("/transition")
75+
.replaceCurrentFragment(true)
76+
.setTransition(getTransitionConfig(), binding.flowrTextView)
77+
.displayFragment();
78+
}
79+
80+
@NonNull
81+
private TransitionConfig getTransitionConfig() {
82+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
83+
return new TransitionConfig.Builder()
84+
.sharedElementEnter(TransitionConfig.Provider.changeBounds)
85+
.sharedElementExit(TransitionConfig.Provider.changeBounds)
86+
.enter(TransitionConfig.Provider.fade)
87+
.exit(TransitionConfig.Provider.fade)
88+
.build();
89+
}
90+
return null;
91+
}
6092
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.fueled.flowr.sample;
2+
3+
import android.view.View;
4+
5+
import com.fueled.flowr.NavigationIconType;
6+
import com.fueled.flowr.annotations.DeepLink;
7+
import com.fueled.flowr.sample.core.AbstractFragment;
8+
9+
/**
10+
* Created by [email protected] on 18/05/2017.
11+
* Copyright (c) 2017 Fueled. All rights reserved.
12+
*/
13+
14+
@DeepLink(value = {"/transition"})
15+
public class TransitionFragment extends AbstractFragment {
16+
17+
@Override
18+
public int getLayoutId() {
19+
return R.layout.fragment_transition;
20+
}
21+
22+
@Override
23+
protected void setupView(View view) {
24+
25+
}
26+
27+
@Override
28+
public String getTitle() {
29+
return "Transition Fragment";
30+
}
31+
32+
@Override
33+
public NavigationIconType getNavigationIconType() {
34+
return NavigationIconType.HAMBURGER;
35+
}
36+
}

sample/src/main/res/layout/fragment_home.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,22 @@
99
android:gravity="center"
1010
android:orientation="vertical">
1111

12+
<TextView
13+
android:id="@+id/flowr_text_view"
14+
android:layout_width="wrap_content"
15+
android:layout_height="wrap_content"
16+
android:background="@color/colorPrimary"
17+
android:padding="4dp"
18+
android:text="@string/app_name"
19+
android:textColor="@color/white"
20+
android:textSize="16sp"
21+
android:transitionName="transitionText"/>
22+
1223
<Button
1324
android:id="@+id/home_open_view_button"
1425
android:layout_width="wrap_content"
1526
android:layout_height="wrap_content"
27+
android:layout_marginTop="10dp"
1628
android:text="@string/open_view_fragment"/>
1729

1830
<Button
@@ -22,6 +34,13 @@
2234
android:layout_marginTop="10dp"
2335
android:text="@string/open_link_fragment"/>
2436

37+
<Button
38+
android:id="@+id/home_open_transition_button"
39+
android:layout_width="wrap_content"
40+
android:layout_height="wrap_content"
41+
android:layout_marginTop="10dp"
42+
android:text="@string/open_transition_fragment"/>
43+
2544
</LinearLayout>
2645

2746
</layout>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
android:background="#FFFFFF"
6+
android:orientation="vertical">
7+
8+
<TextView
9+
android:layout_width="wrap_content"
10+
android:layout_height="wrap_content"
11+
android:layout_gravity="center"
12+
android:text="@string/transition_message"/>
13+
14+
<TextView
15+
android:id="@+id/flowr_text_view"
16+
android:layout_width="wrap_content"
17+
android:layout_height="wrap_content"
18+
android:layout_gravity="center_horizontal"
19+
android:layout_marginTop="10dp"
20+
android:background="@color/colorPrimary"
21+
android:padding="8dp"
22+
android:text="@string/app_name"
23+
android:textColor="@color/white"
24+
android:textSize="20sp"
25+
android:transitionName="transitionText"/>
26+
27+
</FrameLayout>

0 commit comments

Comments
 (0)