Skip to content

Conversation

@farfromrefug
Copy link
Collaborator

@farfromrefug farfromrefug commented May 6, 2018

Follows issue: #5785

  • switch to AppCompatActivity
  • added “transitionName” property
  • added prepareFragment optional function for navigate
  • allow access to _fragment for page
  • use manager.popBackStack();

I should mention that switching to AppCompat actually changed to default fragment enter animation. With support it is a "push fade" animation (quite fast one). Without it was a fade animation.

For now i have let some commented code so that you can review it.
I am also not very good with tests. Let me know what tests you want me to add.

- switch to AppCompatActivity
- added “transitionName” property
- added prepareFragment optional function for navigate
- allow access to _fragment for page
@ns-bot
Copy link

ns-bot commented May 6, 2018

Please sign CLA at http://www.nativescript.org/cla

@ns-bot ns-bot added the cla: no label May 6, 2018
@ns-bot
Copy link

ns-bot commented May 6, 2018

CLA signature found, happy contributing!

@manoldonev
Copy link
Contributor

@farfromrefug Thank you for taking the time to make this PR! We will need some time run our automated tests and review this as the proposed changes are related to some core logic inside the NativeScript framework for Android.

public context: android.content.Context;
public foregroundActivity: android.app.Activity;
public startActivity: android.app.Activity;
public foregroundActivity: android.support.v7.app.AppCompatActivity;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you elaborate a bit why is the change to android.support.v7.app.AppCompat* APIs necessary for supporting shared element transitions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually i made a all replace. I think you ate right in this case it should still be an activity as you can start another activity which would not be an AppCompatActivity

Copy link
Contributor

Choose a reason for hiding this comment

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

I am still trying to get my head around why we need the AppCompat* API switch at all. Can you elaborate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@manoldonev You need to compat switch to get access to many methods, like startPostponedEnterTransition on fragments and activities.
You also need supportFinishAfterTransition to make sure transitions are applied when closing an activity.
Also i really want to point out that in P, they deprecate the default FragmentManager so you need to start using the support library anyway.
On a side note it wont make apps bigger as your already include it.

}

get transitionName(): string {
return this.style.transitionName;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think transitionName should be registered on Style but on ViewCommon. Check automationText:
https://github.com/NativeScript/NativeScript/blob/master/tns-core-modules/ui/core/view/view-common.ts#L1000

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Great i am all new to nativescript. Will change that.

_updateTransitions(backstackEntry);
}
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
manager.popBackStack();
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently we are not using the backstack functionality of FragmentManager but we are managing the fragments on our own. Could you elaborate a bit why are you proposing this change?

Copy link
Collaborator Author

@farfromrefug farfromrefug May 8, 2018

Choose a reason for hiding this comment

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

This one is quite important because otherwise shared element animation wont work. Or you need to do it manually (re add the shared element but the other way around). I think you did not use it to get listeners and be notified when transition finished. Which still works in this PR

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we should explore doing this manually as I don't see us replacing our back stack management logic at this point (or adding the FragmentManager's one on top of it).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@manoldonev i don't see how it breaks your back stack management? You still get the transition end event, and your stack is updated.

@manoldonev
Copy link
Contributor

@farfromrefug btw as far as I can see even with support libraries shared element transitions are supposed to work on Android API Levels 21 or higher, right?

Also, this is obviously Android only and ideally we would like to provide cross-platform support for iOS and Android. I did a quick search and there are iOS options (here and here) or cross-platform solutions like this one that we might need to consider as alternatives as well.

@farfromrefug
Copy link
Collaborator Author

farfromrefug commented May 8, 2018

@manoldonev not in the support library. Was added in support 22.0.1 i think
Now about the iOS part that s a lot trickier
In my last framework i did noy manage to do it. So it was kind of an android thing. But now that you talk about it that would still be doable. For me the tricky thing is not technical as already do it, it is more with the expectation of the default transition. The default ios transition is the modern push in the navigation controller which would not work with shared elements (i have not tried with the lib you shared).
I will try and report

Edit: the react native version is wrong in what they are saying because they dont seem to be using a navigationcontroller. Their defaut transitiom animation is wrong

@manoldonev
Copy link
Contributor

test

@manoldonev
Copy link
Contributor

@farfromrefug btw we are actually working on a sample custom animation showcase that mimics shared element transitions and works on iOS and Android: https://play.nativescript.org/?template=play-ng&id=iDY4kF&v=10 (work in progress). Would this approach work for your scenario as well?

@manoldonev
Copy link
Contributor

manoldonev commented May 9, 2018

@farfromrefug we tried to run some of our test suites to estimate the potential impact of the proposed changes and whether merging this is feasible but currently the unit test and e2e apps are crashing:

System.err: Error: java.lang.NoSuchFieldException: No field animation in class Landroid/view/animation/AnimationSet; (declaration of 'android.view.animation.AnimationSet' appears in /system/framework/framework.jar:classes2.dex)
System.err:     java.lang.Class.getDeclaredField(Native Method)
System.err:     com.tns.Runtime.callJSMethodNative(Native Method)
System.err:     com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
System.err:     com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
System.err:     com.tns.Runtime.callJSMethod(Runtime.java:957)
System.err:     com.tns.Runtime.callJSMethod(Runtime.java:941)
System.err:     com.tns.Runtime.callJSMethod(Runtime.java:933)
System.err:     com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__AttachListener.onViewAttachedToWindow(Object_frnal_ts_helpers_l58_c38__AttachListener.java:12)
System.err:     android.view.View.dispatchAttachedToWindow(View.java:15520)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2916)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err:     android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err:     android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1526)
System.err:     android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
System.err:     android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
System.err:     android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
System.err:     android.view.Choreographer.doCallbacks(Choreographer.java:686)
System.err:     android.view.Choreographer.doFrame(Choreographer.java:621)
System.err:     android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
System.err:     android.os.Handler.handleCallback(Handler.java:751)
System.err:     android.os.Handler.dispatchMessage(Handler.java:95)
System.err:     android.os.Looper.loop(Looper.java:154)
System.err:     android.app.ActivityThread.main(ActivityThread.java:6119)
System.err:     java.lang.reflect.Method.invoke(Native Method)
System.err:     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
System.err:     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
System.err: File: "file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/fragment.transitions.js, line: 633, column: 59
System.err:
System.err: StackTrace:
System.err: 	Frame: function:'initDefaultAnimations', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/fragment.transitions.js', line: 633, column: 60
System.err: 	Frame: function:'_setAndroidFragmentTransitions', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/fragment.transitions.js', line: 29, column: 5
System.err: 	Frame: function:'Frame._navigateCore', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 250, column: 32
System.err: 	Frame: function:'FrameBase.performNavigation', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 235, column: 14
System.err: 	Frame: function:'FrameBase._processNextNavigationEntry', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 227, column: 22
System.err: 	Frame: function:'Frame._processNextNavigationEntry', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 138, column: 58
System.err: 	Frame: function:'Frame._onAttachedToWindow', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 114, column: 14
System.err: 	Frame: function:'AttachListener.onViewAttachedToWindow', file:'file:///data/data/org.nativescript.UnitTestApp/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 38, column: 27
System.err:
System.err: 	at com.tns.Runtime.callJSMethodNative(Native Method)
System.err: 	at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
System.err: 	at com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
System.err: 	at com.tns.Runtime.callJSMethod(Runtime.java:957)
System.err: 	at com.tns.Runtime.callJSMethod(Runtime.java:941)
System.err: 	at com.tns.Runtime.callJSMethod(Runtime.java:933)
System.err: 	at com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__AttachListener.onViewAttachedToWindow(Object_frnal_ts_helpers_l58_c38__AttachListener.java:12)
System.err: 	at android.view.View.dispatchAttachedToWindow(View.java:15520)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2916)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
System.err: 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1526)
System.err: 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
System.err: 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
System.err: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
System.err: 	at android.view.Choreographer.doCallbacks(Choreographer.java:686)
System.err: 	at android.view.Choreographer.doFrame(Choreographer.java:621)
System.err: 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
System.err: 	at android.os.Handler.handleCallback(Handler.java:751)
System.err: 	at android.os.Handler.dispatchMessage(Handler.java:95)
System.err: 	at android.os.Looper.loop(Looper.java:154)
System.err: 	at android.app.ActivityThread.main(ActivityThread.java:6119)
System.err: 	at java.lang.reflect.Method.invoke(Native Method)
System.err: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
System.err: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
System.err: Caused by: java.lang.NoSuchFieldException: No field animation in class Landroid/view/animation/AnimationSet; (declaration of 'android.view.animation.AnimationSet' appears in /system/framework/framework.jar:classes2.dex)
System.err: 	at java.lang.Class.getDeclaredField(Native Method)
System.err: 	... 28 more
ActivityManager: Process org.nativescript.UnitTestApp (pid 6707) has died
ActivityManager: cleanUpApplicationRecord -- 6707

You can run the unit test app locally like this (it is located inside the tests folder in the repo root):

cd tests
cd tns run android

@farfromrefug
Copy link
Collaborator Author

@manoldonev will look at the test error tomorrow morning!
Thanks for looking at this.

About your example it might work. Right now i see it does not handle different size from one view to the other? Also you don't animate the fragment transition itself right? Would it work with explode or fade transition? It would need to.
About the iOs counterpart, i really think i see a way to do it and i might have a look at it soon.

Thanks

@farfromrefug
Copy link
Collaborator Author

@manoldonev i fixed the unit test app. Will be more careful with this from now on.
Thanks

@farfromrefug
Copy link
Collaborator Author

@manoldonev found a great library to do that on iOS. It's actually based on android transitions.
https://github.com/lkzhao/Hero
What's the rule about using native external lib within the nativescript core?

@manoldonev
Copy link
Contributor

test

@manoldonev
Copy link
Contributor

@farfromrefug about the iOS library -- we do not have a precedent for this and at this point we would prefer not to reference native external lib within NativeScript core. For one thing we would need to get much better understanding of this lib and its potential implications / effects, also adding it and not using it for anything else besides shared element transitions does not seem like the best strategy.

As for the Android part -- we had a discussion internally and we agreed that we would need to address Android P support first with highest priority due to its deprecations and breaking changes before even considering how to proceed with this PR (or alternative solution that adds support for cross-platform shared element transitions) as the proposed changes tamper with some core Android internals in NativeScript core (as discussed above one of the things we are concerned about is the backstack management changes and would not like to revert to a situation that #4951 addressed several months ago).

Btw, do you think it is feasible to extract the changes you are proposing in a NativeScript plugin? If we can agree on an approach and API to expose maybe that would be the best option for the time being (note that exposing the necessary API might not be that easy as currently this platform-specific implementation is intentionally hidden but at least we can try to discuss it).

@farfromrefug
Copy link
Collaborator Author

@manoldonev i do understand. I don't think it can be made as a plugin because it requires to change the "extends" of the basic Nativescript Activity. At least i think it's not possible.
Especially when we can't use generics in extends.

Now in my opinion and seeing the very limited amount of changes in the code, it could be part of the Android P support. Especially when you need to change the transition frame code because of the Android P security. If i am correct the way to get the default transition won't work anymore (same for my code).
What i mean is that i think it could be part of the Android P support sprint.

But whatever you decide, i will understand.

Thanks

@NathanaelA

This comment was marked as abuse.

@danielgek
Copy link
Contributor

I agree with @NathanaelA, also consider this a major feat that nativescript needs!!

And there is androidX now, that brings among other things, support for the material-components-android(also available under the support.design lib), been using some of these components but it take to much to make it work.

This with android P would be great!

@manoldonev
Copy link
Contributor

@NathanaelA this PR is currently on-hold as we felt it required significant effort on our side to complete at the time. As for AppCompatActivity / deprecated native fragments -- we will revisit those building blocks separately from the shared element transition support in the coming weeks and we'll agree upon a course of action. Will update this thread when we have more info.

@danielgek are you referring to AppCompatActivity or the shared element transition support that this PR originally targets?

@NathanaelA

This comment was marked as abuse.

@farfromrefug
Copy link
Collaborator Author

@manoldonev What's the effort you are talking about? is that testing? Cause on the implementation side it seems like there is nothing else to do

@manoldonev
Copy link
Contributor

@farfromrefug testing is part of the effort too, yes (tests did not pass with this PR at any point in time) but as discussed above the proposed changes tamper with some core Android internals in NativeScript core and our main concern is the backstack management changes as we would not like to revert to a situation that #4951 addressed several months ago.

To summarize -- this feature is on our radar but we will handle breaking changes and deprecations like AppCompatActivity and native fragments first and then we will go back to the task of adding shared element transitions.

@danielgek
Copy link
Contributor

@manoldonev was talking about AppCompatActivity !

@shiv19
Copy link
Member

shiv19 commented Jul 27, 2018

Until we get the native shared elements animation support added to {N},
it is possible to implement something close to shared element transition,
that works on both Android and iOS, using existing {N} APIs
I've demonstrated it in this repo,
https://github.com/shiv19/nativescript-set-demo

@demetrio812
Copy link

@shiv19 from a design point of view that's not a nice solution, the fact that you see the rest of the list disappearing has made my designer completely not adopting it.

The problem is clients keep asking for these kind of transactions because all the major apps are doing it and at the moment this is a big limitation of NS in my opinion, especially if we want apps that looks nice and native.

@shiv19
Copy link
Member

shiv19 commented Jul 28, 2018

@demetrio812
I totally agree with you!
I'm not happy with that implementation either, but that was a close as I could get to it back then. Maybe I can make a better solution now. But then, nothing beats native shared elements support.

Another important support that is required is this:
#4908

Not sure if it is on their radar.

@demetrio812
Copy link

Hello @shiv19 , thanks for pointing out the other issue, yes I think we really need to be able to create nice looking apps that follow the design guidelines from each OS to be really confident that ANY app can be built with NS, I'm really looking forward to it!

@manoldonev
Copy link
Contributor

Migration to support library APIs PR #6129 is now merged in the master branch of the NativeScript repo. Can be tested via tns-core-modules@next.

@ghost ghost removed the ♥ community PR label Aug 11, 2018
@farfromrefug farfromrefug deleted the shared_element branch August 11, 2018 09:36
@demetrio812
Copy link

@manoldonev @radeva @shiv19 now that version 6 is out, can you have another look at the shared elements? In general it would be cool to have a general solution that would work on iOS too as it's really needed to step up the UI capabilities of the apps written in Nativescript, especially after how much Flutter is focusing its efforts in UI quality and animations

Thanks a lot

@demetrio812
Copy link

I'd like to add that in case you don't want to include them inside the NS Core, the new material components could be an opportunity to address it in a multiplatform way but keeping them in an external library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants