Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(*): transition for shared elements #35

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ When displaying a new fragment there are multiple parameters that can be specifi
* **`skipBackStack`**: specify whether this fragment will be added to the `FragmentManager` back stack or not. The default value for this is `false`.
* **`clearBackStack`**: specify whether the `FragmentManager` backstack should be cleared before displaying this fragment. The default value used for this is `false`.
* **`replaceCurrentFragment`**: specify whether this fragment should replace the fragment currently displayed inside the container or just be added over it. The default value used for this is `false`.
* **`enterAnim`** and **`exitAnim`**: animation resource ID for the enter and exit fragment animation. The default values used here are `R.anim.fragment_enter_anim` and `R.anim.fragment_exit_anim`.
* **`setCustomTransactionAnimation`**: specify `enterAnim` and `exitAnim` animation resource ID for the enter and exit fragment animation. The default values used here are `R.anim.fragment_enter_anim` and `R.anim.fragment_exit_anim`.
* **`setTransition`**: specify `transitionConfig` and `sharedElements` for adding custom transitions. For API >= 21, shared elements can also be passed between fragments. Make sure to add `android:transitionName` attribute to the shared views.

finally after we have specified all the parameters we need we can simply call `displayFragment()` to display the fragment.

Expand Down
Binary file not shown.
51 changes: 51 additions & 0 deletions flowr/src/main/java/com/fueled/flowr/Flowr.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.AnimRes;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
Expand All @@ -18,6 +20,7 @@
import com.fueled.flowr.internal.FlowrDeepLinkHandler;
import com.fueled.flowr.internal.FlowrDeepLinkInfo;
import com.fueled.flowr.internal.TransactionData;
import com.fueled.flowr.internal.TransitionConfig;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -273,6 +276,10 @@ protected <T extends Fragment & FlowrFragment> int displayFragment(TransactionDa
Fragment fragment = data.getFragmentClass().newInstance();
fragment.setArguments(data.getArgs());

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && data.getTransitionConfig() != null) {
setTransitions(fragment, data.getTransitionConfig());
}

FragmentTransaction transaction = screen.getScreenFragmentManager().beginTransaction();

if (!data.isSkipBackStack()) {
Expand All @@ -288,6 +295,11 @@ protected <T extends Fragment & FlowrFragment> int displayFragment(TransactionDa
transaction.add(mainContainerId, fragment);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && data.getTransitionConfig() != null &&
data.getSharedElements() != null && data.getSharedElements().length > 0) {
addSharedElements(transaction, data.getSharedElements());
}

identifier = transaction.commit();

if (data.isSkipBackStack()) {
Expand Down Expand Up @@ -329,6 +341,33 @@ private <T extends Fragment & FlowrFragment> void injectDeepLinkInfo(Transaction
}
}

/**
* Set transitions to the destination fragment from @{@link TransitionConfig}.
*
* @param fragment The destination Fragment.
* @param transitionConfig The transition configuration @{@link TransitionConfig}.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setTransitions(Fragment fragment, TransitionConfig transitionConfig) {
fragment.setEnterTransition(transitionConfig.enter);
fragment.setSharedElementEnterTransition(transitionConfig.sharedElementEnter);
fragment.setExitTransition(transitionConfig.exit);
fragment.setSharedElementReturnTransition(transitionConfig.sharedElementReturn);
}

/**
* Add shared elements to a Fragment Transaction.
*
* @param transaction The transaction that will.
* @param views The shared elements.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void addSharedElements(FragmentTransaction transaction, View[] views) {
for (View view : views) {
transaction.addSharedElement(view, view.getTransitionName());
}
}

/**
* Set a Custom Animation to a Fragment transaction
*
Expand Down Expand Up @@ -771,6 +810,18 @@ public Builder setCustomTransactionAnimation(@AnimRes int enterAnim, @AnimRes in

}

/**
* Set transition between fragments.
*
* @param transitionConfig builder class for configuring fragment transitions
* @param sharedElements array of shared elements
*/
public Builder setTransition(TransitionConfig transitionConfig, View... sharedElements) {
data.setTransitionConfig(transitionConfig);
data.setSharedElements(sharedElements);
return this;
}

/**
* Don't use any animations for this transaction
*/
Expand Down
19 changes: 19 additions & 0 deletions flowr/src/main/java/com/fueled/flowr/internal/TransactionData.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.View;

import com.fueled.flowr.FlowrFragment;

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

public TransactionData(Class<? extends T> fragmentClass) {
this(fragmentClass, FragmentTransaction.TRANSIT_NONE, FragmentTransaction.TRANSIT_NONE);
Expand Down Expand Up @@ -121,4 +124,20 @@ public int getExitAnim() {
public void setExitAnim(int exitAnim) {
this.exitAnim = exitAnim;
}

public View[] getSharedElements() {
return sharedElements;
}

public void setSharedElements(View[] sharedElements) {
this.sharedElements = sharedElements;
}

public TransitionConfig getTransitionConfig() {
return transitionConfig;
}

public void setTransitionConfig(TransitionConfig transitionConfig) {
this.transitionConfig = transitionConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.fueled.flowr.internal;

import android.transition.Transition;

/**
* Copyright (c) 2017 Fueled. All rights reserved.
*
* @author chetansachdeva on 21/11/17
*/

public class TransitionConfig {

public Transition sharedElementEnter;
public Transition sharedElementReturn;
public Transition enter;
public Transition exit;

private TransitionConfig(Builder builder) {
sharedElementEnter = builder.sharedElementEnter;
sharedElementReturn = builder.sharedElementReturn;
enter = builder.enter;
exit = builder.exit;
}

public static final class Builder {
private Transition sharedElementEnter;
private Transition sharedElementReturn;
private Transition enter;
private Transition exit;

public Builder() {
}

public Builder sharedElementEnter(Transition val) {
sharedElementEnter = val;
return this;
}

public Builder sharedElementReturn(Transition val) {
sharedElementReturn = val;
return this;
}

public Builder enter(Transition val) {
enter = val;
return this;
}

public Builder exit(Transition val) {
exit = val;
return this;
}

public TransitionConfig build() {
return new TransitionConfig(this);
}
}
}
Binary file not shown.
50 changes: 42 additions & 8 deletions sample/src/main/java/com/fueled/flowr/sample/HomeFragment.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.fueled.flowr.sample;

import android.databinding.DataBindingUtil;
import android.os.Build;
import android.os.Bundle;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.Transition;
import android.view.View;
import android.widget.Toast;

import com.fueled.flowr.NavigationIconType;
import com.fueled.flowr.internal.TransitionConfig;
import com.fueled.flowr.sample.core.AbstractFragment;
import com.fueled.flowr.sample.databinding.FragmentHomeBinding;

Expand All @@ -32,6 +37,7 @@ protected void setupView(View view) {
binding.homeOpenViewButton.setOnClickListener(this);
binding.homeOpenLinkButton.setOnClickListener(this);
binding.homeOpenFirstButton.setOnClickListener(this);
binding.homeOpenTransitionButton.setOnClickListener(this);
}

@Override
Expand All @@ -46,14 +52,21 @@ public NavigationIconType getNavigationIconType() {

@Override
public void onClick(View view) {
if (view.getId() == R.id.home_open_view_button) {
displayViewFragment();
} else if (view.getId() == R.id.home_open_link_button) {
displayLinkFragment();
} else if (view.getId() == R.id.home_open_first_button) {
displayFirstFragment();
} else {

switch (view.getId()) {
case R.id.home_open_view_button:
displayViewFragment();
break;
case R.id.home_open_link_button:
displayLinkFragment();
break;
case R.id.home_open_transition_button:
displayTransitionFragment();
break;
case R.id.home_open_first_button:
displayFirstFragment();
break;
default:
break;
}
}

Expand Down Expand Up @@ -83,4 +96,25 @@ protected void onFragmentResults(int requestCode, int resultCode, Bundle data) {
Toast.makeText(getContext(), resultFromStack, Toast.LENGTH_SHORT).show();
}
}

private void displayTransitionFragment() {
getFlowr().open("/transition")
.replaceCurrentFragment(true) // transition works with replace
.setTransition(getTransitionConfig(), binding.flowrTextView)
.displayFragment();
}

private TransitionConfig getTransitionConfig() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Transition changeBoundsTransition = new ChangeBounds();
Transition fadeTransition = new Fade();
return new TransitionConfig.Builder()
.sharedElementEnter(changeBoundsTransition)
.sharedElementReturn(changeBoundsTransition)
.enter(fadeTransition)
.exit(fadeTransition)
.build();
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.fueled.flowr.sample;

import android.view.View;

import com.fueled.flowr.NavigationIconType;
import com.fueled.flowr.annotations.DeepLink;
import com.fueled.flowr.sample.core.AbstractFragment;

/**
* Created by [email protected] on 18/05/2017.
* Copyright (c) 2017 Fueled. All rights reserved.
*/

@DeepLink(value = {"/transition"})
public class TransitionFragment extends AbstractFragment {

@Override
public int getLayoutId() {
return R.layout.fragment_transition;
}

@Override
protected void setupView(View view) {

}

@Override
public String getTitle() {
return "Transition Fragment";
}

@Override
public NavigationIconType getNavigationIconType() {
return NavigationIconType.HAMBURGER;
}
}
Binary file added sample/src/main/res/layout/.DS_Store
Binary file not shown.
19 changes: 19 additions & 0 deletions sample/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/flowr_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:padding="4dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="16sp"
android:transitionName="@string/transition_text"/>

<Button
android:id="@+id/home_open_view_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/open_view_fragment"/>

<Button
Expand All @@ -29,6 +41,13 @@
android:layout_marginTop="10dp"
android:text="@string/open_first_fragment"/>

<Button
android:id="@+id/home_open_transition_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/open_transition_fragment"/>

</LinearLayout>

</layout>
27 changes: 27 additions & 0 deletions sample/src/main/res/layout/fragment_transition.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/transition_message"/>

<TextView
android:id="@+id/flowr_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:background="@color/colorPrimary"
android:padding="8dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="20sp"
android:transitionName="@string/transition_text"/>

</FrameLayout>
Binary file added sample/src/main/res/values/.DS_Store
Binary file not shown.
Loading