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

[TIMOB-19580] Customize Activity Transitions #7371

Merged
merged 3 commits into from
Oct 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
131 changes: 128 additions & 3 deletions android/modules/ui/src/java/ti/modules/titanium/ui/WindowProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,27 @@
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.util.TiRHelper;
import org.appcelerator.titanium.view.TiUIView;

import ti.modules.titanium.ui.widget.TiView;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Message;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.transition.ChangeBounds;
import android.transition.ChangeClipBounds;
import android.transition.ChangeImageTransform;
import android.transition.ChangeTransform;
import android.transition.Explode;
import android.transition.Fade;
import android.transition.Slide;
import android.transition.Transition;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
Expand Down Expand Up @@ -147,7 +158,7 @@ protected void handleOpen(KrollDict options)
topActivity.overridePendingTransition(TiConvert.toInt(options.get(TiC.INTENT_PROPERTY_ENTER_ANIMATION), 0),
TiConvert.toInt(options.get(TiC.INTENT_PROPERTY_EXIT_ANIMATION), 0));
} else {
topActivity.startActivity(intent);
topActivity.startActivity(intent, createActivityOptionsBundle(topActivity));
}
}

Expand Down Expand Up @@ -205,6 +216,11 @@ public void windowCreated(TiBaseActivity activity, Bundle savedInstanceState) {
if (background != null) {
win.setBackgroundDrawable(background);
}

// Handle activity transitions
if (LOLLIPOP_OR_GREATER) {
applyActivityTransitions(win, properties);
}

// Handle the width and height of the window.
// TODO: If width / height is a percentage value, we can not get the dimension in pixel because
Expand Down Expand Up @@ -455,7 +471,116 @@ private void setWindowWidthHeight(Object width, Object height)
}
}
}

/**
* Helper method to apply activity transitions.
* @param win The window holding the activity.
* @param props The property dictionary.
*/
private void applyActivityTransitions(Window win, KrollDict props) {
if (LOLLIPOP_OR_GREATER) {
// Return and reenter transitions defaults to enter and exit transitions respectively only if they are not set.
// And setting a null transition makes the view unaccounted from transition.
if (props.containsKeyAndNotNull(TiC.PROPERTY_ENTER_TRANSITION)) {
win.setEnterTransition(createTransition(props, TiC.PROPERTY_ENTER_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_EXIT_TRANSITION)) {
win.setExitTransition(createTransition(props, TiC.PROPERTY_EXIT_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_RETURN_TRANSITION)) {
win.setReturnTransition(createTransition(props, TiC.PROPERTY_RETURN_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_REENTER_TRANSITION)) {
win.setReenterTransition(createTransition(props, TiC.PROPERTY_REENTER_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_SHARED_ELEMENT_ENTER_TRANSITION)) {
win.setSharedElementEnterTransition(createTransition(props, TiC.PROPERTY_SHARED_ELEMENT_ENTER_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_SHARED_ELEMENT_EXIT_TRANSITION)) {
win.setSharedElementExitTransition(createTransition(props, TiC.PROPERTY_SHARED_ELEMENT_EXIT_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_SHARED_ELEMENT_REENTER_TRANSITION)) {
win.setSharedElementReenterTransition(createTransition(props, TiC.PROPERTY_SHARED_ELEMENT_REENTER_TRANSITION));
}

if (props.containsKeyAndNotNull(TiC.PROPERTY_SHARED_ELEMENT_RETURN_TRANSITION)) {
win.setSharedElementReturnTransition(createTransition(props, TiC.PROPERTY_SHARED_ELEMENT_RETURN_TRANSITION));
}
}
}

/**
* Creates a transition for the supplied transition type.
* @param props The property dictionary.
* @param key The transition type
* @return A Transition or null if UIModule.TRANSITION_NONE or unknown transition is specified.
*/
@SuppressLint({ "InlinedApi", "RtlHardcoded" })
@Nullable
private Transition createTransition(KrollDict props, String key) {
if (LOLLIPOP_OR_GREATER) {
Transition t = null;
final int transitionType = props.getInt(key);
switch (transitionType) {
case TiUIView.TRANSITION_EXPLODE:
t = new Explode();
break;

case TiUIView.TRANSITION_FADE_IN:
t = new Fade(Fade.IN);
break;

case TiUIView.TRANSITION_FADE_OUT:
t = new Fade(Fade.OUT);
break;

case TiUIView.TRANSITION_SLIDE_TOP:
t = new Slide(Gravity.TOP);
break;

case TiUIView.TRANSITION_SLIDE_RIGHT:
t = new Slide(Gravity.RIGHT);
break;

case TiUIView.TRANSITION_SLIDE_BOTTOM:
t = new Slide(Gravity.BOTTOM);
break;

case TiUIView.TRANSITION_SLIDE_LEFT:
t = new Slide(Gravity.LEFT);
break;

case TiUIView.TRANSITION_CHANGE_BOUNDS:
t = new ChangeBounds();
break;

case TiUIView.TRANSITION_CHANGE_CLIP_BOUNDS:
t = new ChangeClipBounds();
break;

case TiUIView.TRANSITION_CHANGE_TRANSFORM:
t = new ChangeTransform();
break;

case TiUIView.TRANSITION_CHANGE_IMAGE_TRANSFORM:
t = new ChangeImageTransform();
break;

default:
break;
}
return t;
} else {
return null;
}
}

@Override
public String getApiName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,19 @@ public class AndroidModule extends KrollModule
@Kroll.constant public static final int WEBVIEW_LOAD_CACHE_ONLY = WebSettings.LOAD_CACHE_ONLY;
@Kroll.constant public static final int WEBVIEW_LOAD_CACHE_ELSE_NETWORK = WebSettings.LOAD_CACHE_ELSE_NETWORK;





@Kroll.constant public static final int TRANSITION_NONE = TiUIView.TRANSITION_NONE;
@Kroll.constant public static final int TRANSITION_EXPLODE = TiUIView.TRANSITION_EXPLODE;
@Kroll.constant public static final int TRANSITION_FADE_IN = TiUIView.TRANSITION_FADE_IN;
@Kroll.constant public static final int TRANSITION_FADE_OUT = TiUIView.TRANSITION_FADE_OUT;
@Kroll.constant public static final int TRANSITION_SLIDE_TOP = TiUIView.TRANSITION_SLIDE_TOP;
@Kroll.constant public static final int TRANSITION_SLIDE_RIGHT = TiUIView.TRANSITION_SLIDE_RIGHT;
@Kroll.constant public static final int TRANSITION_SLIDE_BOTTOM = TiUIView.TRANSITION_SLIDE_BOTTOM;
@Kroll.constant public static final int TRANSITION_SLIDE_LEFT = TiUIView.TRANSITION_SLIDE_LEFT;
@Kroll.constant public static final int TRANSITION_CHANGE_BOUNDS = TiUIView.TRANSITION_CHANGE_BOUNDS;
@Kroll.constant public static final int TRANSITION_CHANGE_CLIP_BOUNDS = TiUIView.TRANSITION_CHANGE_CLIP_BOUNDS;
@Kroll.constant public static final int TRANSITION_CHANGE_TRANSFORM = TiUIView.TRANSITION_CHANGE_TRANSFORM;
@Kroll.constant public static final int TRANSITION_CHANGE_IMAGE_TRANSFORM = TiUIView.TRANSITION_CHANGE_IMAGE_TRANSFORM;

@Kroll.constant public static final int PROGRESS_INDICATOR_STATUS_BAR = TiUIProgressIndicator.STATUS_BAR;
@Kroll.constant public static final int PROGRESS_INDICATOR_DIALOG = TiUIProgressIndicator.DIALOG;
@Kroll.constant public static final int PROGRESS_INDICATOR_INDETERMINANT = TiUIProgressIndicator.INDETERMINANT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,9 @@ protected void onCreate(Bundle savedInstanceState)
// we need to set window features before calling onCreate
this.requestWindowFeature(Window.FEATURE_PROGRESS);
this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
this.requestWindowFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
}
super.onCreate(savedInstanceState);

windowCreated(savedInstanceState);
Expand Down
13 changes: 13 additions & 0 deletions android/titanium/src/java/org/appcelerator/titanium/TiC.java
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,14 @@ public class TiC
public static final String EVENT_UNFOCUSED = "unfocused";
public static final String INTENT_PROPERTY_ENTER_ANIMATION = "activityEnterAnimation";
public static final String INTENT_PROPERTY_EXIT_ANIMATION = "activityExitAnimation";
public static final String PROPERTY_ENTER_TRANSITION = "activityEnterTransition";
public static final String PROPERTY_EXIT_TRANSITION = "activityExitTransition";
public static final String PROPERTY_RETURN_TRANSITION = "activityReturnTransition";
public static final String PROPERTY_REENTER_TRANSITION = "activityReenterTransition";
public static final String PROPERTY_SHARED_ELEMENT_ENTER_TRANSITION = "activitySharedElementEnterTransition";
public static final String PROPERTY_SHARED_ELEMENT_EXIT_TRANSITION = "activitySharedElementExitTransition";
public static final String PROPERTY_SHARED_ELEMENT_REENTER_TRANSITION = "activitySharedElementReenterTransition";
public static final String PROPERTY_SHARED_ELEMENT_RETURN_TRANSITION = "activitySharedElementReturnTransition";
public static final String INTENT_PROPERTY_FINISH_ROOT = "finishRoot";
public static final String INTENT_PROPERTY_IS_TAB = "isTab";
public static final String INTENT_PROPERTY_LAYOUT = "layout";
Expand Down Expand Up @@ -838,6 +846,11 @@ public class TiC
*/
public static final String PROPERTY_BACKGROUND_SELECTED_IMAGE = "backgroundSelectedImage";

/**
* @module.api
*/
public static final String PROPERTY_TRANSITION_NAME = "transitionName";

/**
* @module.api
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@
// others
"focusable", "touchEnabled", "visible", "enabled", "opacity",
"softKeyboardOnFocus", "transform", "elevation", "touchTestId",
"translationX", "translationY", "translationZ"
"translationX", "translationY", "translationZ",

TiC.PROPERTY_TRANSITION_NAME
})
public abstract class TiViewProxy extends KrollProxy implements Handler.Callback
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
package org.appcelerator.titanium.proxy;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
Expand All @@ -21,14 +23,18 @@
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.TiOrientationHelper;
import org.appcelerator.titanium.util.TiUIHelper;
import org.appcelerator.titanium.util.TiWeakList;
import org.appcelerator.titanium.view.TiAnimation;
import org.appcelerator.titanium.view.TiUIView;
import org.appcelerator.titanium.util.TiWeakList;

import android.app.Activity;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Pair;
import android.view.View;

@Kroll.proxy(propertyAccessors={
Expand All @@ -41,6 +47,7 @@
public abstract class TiWindowProxy extends TiViewProxy
{
private static final String TAG = "TiWindowProxy";
protected static final boolean LOLLIPOP_OR_GREATER = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);

private static final int MSG_FIRST_ID = KrollProxy.MSG_LAST_ID + 1;
private static final int MSG_OPEN = MSG_FIRST_ID + 100;
Expand All @@ -58,7 +65,7 @@ public abstract class TiWindowProxy extends TiViewProxy
protected boolean inTab;
protected PostOpenListener postOpenListener;
protected boolean windowActivityCreated = false;

protected List< Pair<View, String> > sharedElementPairs;

public static interface PostOpenListener
{
Expand All @@ -74,6 +81,9 @@ public static TiWindowProxy getWaitingForOpen()
public TiWindowProxy()
{
inTab = false;
if (LOLLIPOP_OR_GREATER) {
sharedElementPairs = new ArrayList< Pair<View, String> >();
}
}

@Override
Expand Down Expand Up @@ -481,4 +491,39 @@ public KrollProxy getParentForBubbling()
}
return super.getParentForBubbling();
}

@Kroll.method
public void addSharedElement(TiViewProxy view, String transitionName) {
if (LOLLIPOP_OR_GREATER) {
TiUIView v = view.peekView();
if (v != null) {
Pair< View,String > p = new Pair<View, String>(v.getNativeView(), transitionName);
sharedElementPairs.add(p);
}
}
}

@Kroll.method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotation not formatted correctly.

public void removeAllSharedElements() {
if (LOLLIPOP_OR_GREATER) {
sharedElementPairs.clear();
}
}

/**
* Helper method to create an activity options bundle.
* @param activity The activity on which options bundle should be created.
* @return The Bundle or null.
*/
@SuppressWarnings("unchecked")
@Nullable
protected Bundle createActivityOptionsBundle(Activity activity) {
if (LOLLIPOP_OR_GREATER) {
Bundle b = ActivityOptions.makeSceneTransitionAnimation(activity,
sharedElementPairs.toArray(new Pair[sharedElementPairs.size()])).toBundle();
return b;
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public abstract class TiUIView
{

private static final boolean HONEYCOMB_OR_GREATER = (Build.VERSION.SDK_INT >= 11);
private static final boolean LOLLIPOP_OR_GREATER = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);

private static final int LAYER_TYPE_SOFTWARE = 1;
private static final String TAG = "TiUIView";

Expand All @@ -91,6 +93,19 @@ public abstract class TiUIView
public static final int SOFT_KEYBOARD_DEFAULT_ON_FOCUS = 0;
public static final int SOFT_KEYBOARD_HIDE_ON_FOCUS = 1;
public static final int SOFT_KEYBOARD_SHOW_ON_FOCUS = 2;

public static final int TRANSITION_NONE = 0;
public static final int TRANSITION_EXPLODE = 1;
public static final int TRANSITION_FADE_IN = 2;
public static final int TRANSITION_FADE_OUT = 3;
public static final int TRANSITION_SLIDE_TOP = 4;
public static final int TRANSITION_SLIDE_RIGHT = 5;
public static final int TRANSITION_SLIDE_BOTTOM = 6;
public static final int TRANSITION_SLIDE_LEFT = 7;
public static final int TRANSITION_CHANGE_BOUNDS = 8;
public static final int TRANSITION_CHANGE_CLIP_BOUNDS = 9;
public static final int TRANSITION_CHANGE_TRANSFORM = 10;
public static final int TRANSITION_CHANGE_IMAGE_TRANSFORM = 11;

protected View nativeView; // Native View object

Expand Down Expand Up @@ -891,8 +906,12 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
if (nativeView != null) {
ViewCompat.setTranslationZ(nativeView, TiConvert.toFloat(newValue));
}
} else if (key.equals(TiC.PROPERTY_TRANSITION_NAME)) {
if (LOLLIPOP_OR_GREATER && (nativeView != null)) {
ViewCompat.setTransitionName(nativeView, TiConvert.toString(newValue));
}
} else if (Log.isDebugModeEnabled()) {
Log.d(TAG, "Unhandled property key: " + key, Log.DEBUG_MODE);
Log.d(TAG, "Unhandled property key: " + key, Log.DEBUG_MODE);
}
}

Expand Down Expand Up @@ -994,6 +1013,11 @@ public void processProperties(KrollDict d)
if (d.containsKey(TiC.PROPERTY_TRANSLATION_Z) && !nativeViewNull){
ViewCompat.setTranslationZ(nativeView, TiConvert.toFloat(d, TiC.PROPERTY_TRANSLATION_Z));
}

if (LOLLIPOP_OR_GREATER && !nativeViewNull
&& d.containsKeyAndNotNull(TiC.PROPERTY_TRANSITION_NAME)) {
ViewCompat.setTransitionName(nativeView, d.getString(TiC.PROPERTY_TRANSITION_NAME));
}
}

// TODO dead code? @Override
Expand Down