Placeholder Image

字幕列表 影片播放

  • (enlightening music)

  • (audience claps)

  • - Thank you.

  • Can you hear me?

  • Okay, yeah.

  • Welcome everybody, thank you for joining me today.

  • First of all, remember to join the conversation

  • in Twitter, #gotocph.

  • Remember to engage so you can rate

  • my actual session and ask questions.

  • My name is Israel Ferrer Camacho.

  • I'm an Android developer at Twitter.

  • You can follow me on Twitter too,

  • and ask me questions there too.

  • I work on the Moments teams which is a

  • nice experience, fullscreen experience

  • horizontal scrolling where you can add

  • a list of tweets, and it's a story.

  • It doesn't have to be following a chronological order there.

  • For those who are not an English native speaker as me,

  • smoke and mirrors is an expression used

  • to describe something that is

  • obscuring or embellishing the truth.

  • It's usually used for magicians because they do magic

  • which is simply not real.

  • It's just a trick, just so you know.

  • Sorry if I spoil you guys.

  • The reason for this title

  • was in the last Google I/O during the RecyclerView talk,

  • where Adam Powell and Yigit Boyar,

  • by Adam Power and Yigit Boyar.

  • Adam Powell actually started the talk by saying

  • UI developers, we have a lot of things in common

  • with magicians, and that is actually true.

  • If you think about some of the animations that we do,

  • and some of the components that we use in the framework,

  • and that's the idea of this talk.

  • I'm gonna be showing some examples in the Android framework

  • or where we are using this smoke and mirrors

  • to make an application just great, flawless, and smooth.

  • After that I will start talking about one of my

  • favorite apps in Android, and how that experience

  • is actually built, and I will do a demo with that.

  • So let's just start with the Android framework.

  • So these are Timeline.

  • Hopefully you know what is Twitter.

  • So theoretically, anytime like you have infinite tweets,

  • as you can see we're scrolling really fast,

  • performance's really good by the way,

  • so it is a problem right?

  • The problem is we have infinite amount of views

  • that we wanna show but we have limitation.

  • We cannot just instantiate thousands of views

  • at the same time.

  • Actually, what we have really do is

  • which is need to do this.

  • We are showing one, two, three, four views in the screen.

  • We don't need to actually show any

  • or instantiate any order view.

  • Just five at the same time, seven, eight tops

  • if the tweets are really small

  • but Jake likes to talk a lot so they're just big.

  • So, anyway how we do that?

  • We use this component called RecyclerView,

  • the name will give you a hint of

  • what it's actually doing, which is recycling.

  • I wanna talk about it, how internally works

  • because I think it's interesting.

  • Internally, it has the linear LayoutManager,

  • which actually recycles,

  • which actually is responsible for measuring

  • and positioning the item views,

  • and as well as determining when to recycle those views

  • that are not shown anymore.

  • So when you try to actually show the next position,

  • the LayoutManager is gonna go to the RecyclerView,

  • and invoke the method getViewForPosition.

  • When that's called, RecyclerView will go to the Adapter,

  • and will ask for the type of that view

  • because you can have many types of views

  • in your RecyclerView so example

  • if you want to have different headers or you want

  • to have a cutout so for showing ads for example, okay.

  • So yeah, we get the type the RecyclerView is gonna

  • go to the RecyclePool, which is where all the views

  • that ViewHolders that we can recycle.

  • It will get a ViewHolder for that type.

  • If there is none, it will go the the Adapter

  • and then create one.

  • But if there is one, it would just send it

  • back to the Adapter and say hey,

  • can you find this ViewHolder with a new data,

  • with a data for that new position that we wanna show,

  • the one that was showing on the animation.

  • Once it holds the information, it just return it back

  • to the RecyclerView, and then the LayoutManager will

  • actually lay it out in the screen, that item.

  • This is a really simple explanation of how the RecyclerView

  • actually recycles views, and you can learn a lot more

  • in the Google I/O talk that I was talking about,

  • the one that inspired this talk.

  • It's called RecyclerView Ins and Outs,

  • and they talk a lot more about how to animate items,

  • and do transitions in between the states.

  • Another example on the Android framework is this one

  • that I'm showing in the Twitter app.

  • As you can see, there is a list of images,

  • and when you click one with transition to fullscreen.

  • Those are called Shared Element Transitions.

  • Shared Element Transitions, they have smoke and mirrors too

  • but first let's dig in on how it works.

  • The way it works is the activity has an activity transition

  • a state which persists a state of that transition,

  • and it has like the most important part is the shared views

  • that are gonna be transitioning from one screen to another.

  • When activity life cycle is invoked, for example

  • it goes through onDestroy, or onPause so it's disappearing,

  • and then we are gonna start a new activity,

  • it will call the activity transition state to start

  • a new transition which will actually call to the

  • activity transition coordinator.

  • The ActivityTransitionCoordinator is a base class.

  • There are actually two.

  • There is entering and exiting coordinator,

  • so one handles the enter transition,

  • and one the exit transition,

  • and that has a transition manager,

  • and it will begin the transition.

  • So by the default the transition is a translation

  • but you can change that on your theme,

  • and you can actually customize your own

  • transitions between activities.

  • But you must be thinking, you're talking a lot about

  • how this works but what is the actual smoke and mirrors

  • in transition in the shared elements.

  • Well, think about it.

  • When an activity is being, going to hide

  • or to the background, and another one comes in the top,

  • how they are actually re-enabled to do that transition

  • from one to another.

  • Well what they do is they hide the target activity,

  • and they have a list of the views that are transitioning

  • from what position they are transitioned

  • so they pretty much in any activity do that transition,

  • that's what they are doing.

  • How they do that, well, they use ViewOverlay,

  • which is used by the default transition in the framework.

  • ViewOverlay provides a transparent layer

  • on the top of a view,

  • to which you can add any type of visual content,

  • (mumbles), and that doesn't affect the

  • layer hidden (mumbles) on the top so that means

  • that you can pretty much animate anything,

  • and it just works and doesn't mess with

  • the layer hierarchy, it's great.

  • It's gonna be your best friend forever in animations, okay.

  • Think about that, that word of what I said.

  • So let's imagine this, you can see there is two layers.

  • There is the LinearLayout which has a nice image view

  • with a Saturn illustration,

  • and then this is the ViewOverlay.

  • In order to make an animation,

  • I'm gonna add that to the ViewOverlay.

  • How do I do that?

  • Well LinearLayout, any view has that,

  • LinearLayout, getOverlay, and then you add to that overlay.

  • What is gonna happen is that suddenly that ImageView

  • is not gonna be part of the LinearLayout anymore.

  • It's gonna be in this temporary ViewOverlay

  • that we're gonna use for animations.

  • When you do that, the rect of that ImageView is

  • invalidated in the parent so that force a re-layout

  • so you have to be careful if you depend on that view.

  • Otherwise you will mess the whole hierarchy.

  • But the good thing is, any type of touch or animation,

  • touch depend on animation, it gets delegated

  • to that ViewOverlay with that ImageView.

  • So if you are actually, imagine you have a reference

  • to this ImageView, and you try to do animation,

  • it will animate even if it's not part of

  • the LinearLayout anymore, which in this case

  • is part of the ViewOverlay.

  • So unfortunately, shared element transitions are real nice

  • but there are limitations.

  • The first one is that the user can't control

  • the transition with a touch.

  • It just an simple animation from one place to another

  • so the eye of the user gets caught,

  • and doesn't lose the context between the screens

  • but it doesn't allow the user for example

  • to pinch and zoom, and control the transition

  • with a pinch and zoom, right.

  • So that's a limitation.

  • Another limitation is that one,

  • actually when I was doing the code, I saw that here.

  • The transition doesn't track the target destination

  • so if you don't eat all the touch events

  • while the transition is running, it looks terrible

  • and it's just a limitation.

  • I mean, we can simply fix that

  • by using this TransitionListener.

  • Thankfully, we can hear all the life cycle events

  • of the transition so what we can do is onTransitionStart,

  • we are just gonna eat all the touch events, pretty much.

  • Then when the transition finishes, we'll just set the

  • touch listener again to the right place.

  • Easier right?

  • Okay, so before entering into the interesting part

  • of the talk, which is the demo,

  • let's talk about two important attributes for an image.

  • Consistently these are the attributes that are actually

  • might as well be thought type of

  • rendering outside the parent.

  • So first of all is the ClipChildren.

  • The ClipChildren attribute is an attribute of

  • a ViewGroup and by default is set to true,

  • which makes sense because it clips the children

  • to the bounds of the parent ViewGroup,

  • and that's exactly what we want right.

  • By default, we want that to happen.

  • So it looks like this.

  • Right, you're not allowed.

  • That's me actually, that's my avatar

  • so I'm not allowed, my ImageView is not allowed

  • to draw outside the parent view

  • unless I set ClipChildren to false.

  • In that case, I'm gonna be able to draw

  • outside the first parent but not the second,

  • not the following parent.

  • So what I have to do is, spoiler alert,

  • I have to set that to false in all the parents,

  • which is kind of like, but that's how it works.

  • So, yeah okay, really bad animation that I got there.

  • It just shows the point.

  • Okay, so ClipPadding, so ClipPadding is the same.

  • So if you have the ClipChildren false

  • but you have a padding, the view is still

  • gonna clip to that padding, yes, that happens,

  • especially with RecyclerViews, happens a lot.

  • So just remember if suddenly a view of yours gets cut,

  • in a RecyclerView, maybe it's because there is a padding

  • and you didn't set that to false.

  • So this is what it looks like.

  • It gets clipped to the padding,

  • and pretty much already at some point,

  • I think a long time ago,

  • was creating this type of utility,

  • which allows me to go through all the parents of the view,

  • and just set everything to false,

  • which is not super difficult.

  • Anyway, let's talk about one of my favorite apps,

  • yeah this is Google Photos.

  • Have you think about it?

  • Do you have it?

  • Do you like it?

  • I think before I never had such a

  • great UI experience in a gallery.

  • I was actually, it's just top-notch,

  • it's really well thought and for a long time,

  • I was thinking, how did they pull that off?

  • It looks so good,

  • but let's check it out how it works actually.

  • So there is one layer, two layers and then fullscreen,

  • and really what I've, fullest, I pinch this so much,

  • you can see that, I'm not really accurate,

  • but anyway so that's how it works.

  • It's just like super smooth, it has three levels of zoom,

  • and then it goes to a fullscreen.

  • As you can see, they're able, the user is able to control

  • the transition to fullscreen, which we were saying

  • that Shared Element Transition can't do.

  • It's a limitation.

  • So the way you figure out how something works in the UI,

  • pretty much these developer options.

  • You make them 10 times slower, which is too slow,

  • maybe five times is fine,

  • and you make the animation 10 times.

  • The duration and the animation is scaled 10 times slower.

  • Then when you do that, so this is what it looks like.

  • Yeah, the other is just (mumbles).

  • So with that you are able to see what is going on

  • because one, you will understand why that's really important

  • soon but for now and other developer option that you want

  • enable these flames, yes I like flames.

  • So show layout boundaries,

  • and you should enable it all the time.

  • It's such a beautiful UI right now.

  • It's wonderful for your eyes.

  • No, but really, this is really useful for developers.

  • That is the blue line which are the clip-out,

  • the clip bounds, whereas there is the red line,

  • which is the optical bound, which is something

  • into a zoom 4.3 that I actually didn't have.

  • Never to use but maybe you need it, so check it out.

  • And the pink area, which are the margins.

  • These not only helps to see the alignment

  • when you hold the screen but it will help us

  • to feel that, I did ultimately but I wanna show

  • if we were doing together so you see what is

  • the trick of that will work for us, application.

  • So now this application looks like that.

  • It's pretty much the same but with some

  • layout boundaries, right.

  • Yeah this is Google I/O,

  • we had such a great time by the way.

  • Anyway so now, just pay attention to the video.

  • I'm not gonna say anything, just think yourself

  • how this is happening, and then I will go deeper

  • into what is really happening.

  • Okay, so I pinch and zoom, this is my,

  • that was the concert, anyway.

  • So three levels, zoom scrolling, going back.

  • Are you seeing what is happening?

  • You see, we don't see that before

  • because it was fast enough right?

  • And now yeah, picture zoom is more difficult

  • once you put it at scale 10x.

  • It's super difficult actually.

  • You have to do it like it really, huge span in order

  • to go to fullscreen.

  • So what happened?

  • Did you noticed what happened?

  • Okay, let's cut to the real part,

  • which is, okay this part of the zoom in.

  • Let's get closer.

  • Did you see that?

  • Can you see the two different RecyclerViews.

  • There is another invisible RecyclerView with

  • a destination size, with a bigger size,

  • and not only that but they're actually cross-fading

  • between one and another.

  • It's all smoke and mirrors.

  • They're just tricking us but you know,

  • that's magic guys.

  • That's what we do, we do magic.

  • So the lesson here is,

  • sorry let's put it back, it's really good.

  • Magic, magic, okay, yeah.

  • So the lesson is anything fast enough will look good enough,

  • and that's true for everything.

  • When you just try 24 hours to make all your animations

  • 10 times slower, and you are gonna see how the application

  • suddenly doesn't make any sense any more

  • because they all actually use that.

  • It's fast transition, fast animation that hides all the

  • problems in implementation, right.

  • There is one more thing that I wasn't able

  • to get on that video but in this video,

  • you will figure out.

  • When you try to zoom in to the fullscreen.

  • Uh-oh, here we go, what is going on?

  • It's the same image.

  • Right so, they are kind of faking it.

  • They're copying the same drawable maybe,

  • and they're using it in order to do the transition

  • to the fullscreen.

  • So that's another trick but if you do it fast enough,

  • and the scale is not enough, 10 times slower,

  • then it just works.

  • So that again, more magic.

  • These Google Photos guys are just magicians.

  • So fake it until you make it.

  • Pretty much, fake it until you make it.

  • That's what we just do all the time in the development.

  • So I showed you how it works but now I tried to be sure

  • that I wasn't doing it wrong.

  • That my assumption wasn't wrong so I actually create

  • a demo, well I created a demo, which is a simplification

  • of Google Photos but it's pretty much it.

  • It's like two zoom levels,

  • and then the last one is, goes to fullscreen.

  • So you can see all these smoke and mirrors,

  • and you can actually see the code.

  • It's gonna be in the GitHub repo so you can check the code,

  • and you can actually apply all those tricks

  • to your applications.

  • So let's go for the demo, yes fireworks, so good.

  • Again, fireworks.

  • So this is the application.

  • This is some nice drawings, by my wife,

  • this illustration, is an illustrator.

  • So zoom in, zoom out, okay,

  • and then fullscreen, fullscreen, fullscreen.

  • So how did I implemented that?

  • So these are the layers.

  • I have a container, a medium RecyclerView,

  • a small RecyclerView, and a fullscreen container.

  • So the container is gonna be the root of

  • the whole hierarchy layout,

  • and of course it's a FrameLayout.

  • It's an obvious choice because we need to stack all

  • those layers on the top of each other,

  • and they are gonna take fullscreen.

  • Why do I need to put a fullscreen container on that screen

  • is because, as I said before, the transition,

  • the shared element transition doesn't allow the user

  • to control the transition to fullscreen

  • but I wanna do it because that's the nice experience.

  • So I put everything here, and you can just do that

  • by creating your own NavigationManager,

  • and depending on the state, you have a stack,

  • and depending on the stack, you can just inflate the,

  • sorry, instantiate the presenters and the view delegates

  • that you need for each of the layers.

  • But let's talk about the important part which is

  • the medium RecyclerView and the small RecyclerView.

  • From now on, I'm gonna call the small images,

  • the small RecyclerView, and the medium,

  • which is a terrible word, I didn't know how to say bigger

  • than a small, which medium is fine,

  • because it's not too big so medium is fine.

  • So medium and small RecyclerView will be the

  • higher level of zoom before going into fullscreen.

  • So we are using two RecyclerViews because that's the trick

  • that allow us to do that nice zoom in effect on the gallery

  • but before doing that, we have to talk about some thing.

  • Really when I pronouncing this word,

  • nobody actually understand me

  • so it's pivot or something like that.

  • Otherwise you have this nice meme from my favorite

  • episode of Friends, which was the pivot, pivot, pivot.

  • If you don't know it, you maybe too young

  • so you should watch it because it's really fun.

  • It's still fun, incredible, still fun.

  • So yeah, let's talk about pivot.

  • So the pivot by default, it sit in the center of the view.

  • So what happen is when you try to actually scale something

  • it scales from center, and it goes in all directions

  • so it looks, that's not what we want, right?

  • What we want is to actually to scale right down.

  • So the first thing that we have to do is

  • said the pivot, the pivot, to (mumbles)

  • to that top left point of the view,

  • which is the RecyclerView

  • because it's the one that we are scaling.

  • That's important for scaling and rotating too.

  • So then it looks like this, which is actually what we want.

  • We want that type of scale.

  • Okay, so we have two RecyclerViews,

  • and my approach is to use two Adapters

  • bind with the same collection back in the map.

  • Because really they are actually using the same data.

  • They're just the same image.

  • They just have different size, right.

  • It's important to set on the setup

  • the medium one to invisible because we only want to show one

  • first which is the small one, which is the one that is gonna

  • be zooming in the first time.

  • Then let's talk about touch events.

  • There is different approaches but the approach that

  • I like it, was to create this eat and touch dispatcher

  • which is a class that gets all the touch events,

  • and depending on the state of that view,

  • we go to do, we delegate that touch to one or another class.

  • So pretty much what I did was create this class,

  • and then add that class to both Adapters.

  • So how does it look like?

  • Well, it looks like this.

  • It has more stuff but the touch event is probably

  • the most important part.

  • So since both the RecyclerViews are using the same

  • we can get the ideal RecyclerView.

  • So in all the Moment we know

  • what is a RecyclerView getting the touch been.

  • For that, what we do is we have this gallery

  • adjusts the texture which I will talk about it later.

  • It's the scale adjust to the texture

  • that we will use for scaling the RecyclerViews.

  • What I do is in case the small RecyclerView

  • is getting touched, it means there is only one way,

  • which is it can only go the medium RecyclerView,

  • it can only zoom in, right?

  • So that's what it's doing.

  • It's pretty much delegate that to the gallery

  • adjust to the texture, which will know

  • and will do that zooming.

  • Then in case of the medium RecyclerView

  • we have the same.

  • The gallery adjust to the texture will know,

  • will know how to do it.

  • It has both logics.

  • The important part here though is that

  • we have zoom out, which goes from the medium to the small

  • but we have zoom in or in this, actually I was kind of lazy,

  • and I just did click but when you click,

  • you go to the fullscreen.

  • Then how we do that?

  • Well we use the span.

  • The span is the, it's actually not the correct span,

  • it's the delta between the last span and the current span.

  • A span is the distance between your fingers

  • so with that if it's (mumbles) I know

  • that it's now pinch and zoom in, it's just clicking.

  • With that, I ask the RecyclerView, which in this case

  • we know is the medium RecyclerView,

  • give me the view on that coordinates,

  • and then I just perform a click.

  • So that's how the zoom in, zoom out between

  • this medium RecyclerView and the small RecyclerView works.

  • Now how do we scale them?

  • So this is what we're missing, right?

  • We weren't scaling, we were just sending the touch events.

  • We're not a scaler, right.

  • For that, we have convenient contract in the platform

  • OnScaleGestureListener, and it has

  • onScaleBegin and onScaleEnd.

  • The names are pretty self-document

  • but onScaleBegin, you just set up everything,

  • first starting the scaling.

  • On a scale, it's a constant stream of the scale gesture.

  • And onScaleEnd is pretty much the user just stopped

  • touching the screen so it just reset the position

  • to the state that you want.

  • So onScaleBegin, what we wanna do is show both

  • small and medium RecyclerViews because what we wanna do

  • as you saw in the video is add the middle of that

  • zoom in or zoom out, we are gonna do a fade in, fade out

  • in between both RecyclerViews, right.

  • So both have to be visual.

  • You can do it different but this approach works

  • because the smoke and mirrors,

  • it comes out the end onScaleEnd.

  • But on the onScale is pretty much all the maths

  • of the talk which is, while there's a gestureTolerance

  • which applies a low plus filter to avoid the flakiness

  • because our fingers are not that accurate

  • so even if you think you're not moving your fingers,

  • the screen is getting some events so there's

  • a constant signal that can prelude a small increments

  • and decrements on the scale.

  • So we want to apply a low plus filter

  • so we know that a minimum span was met,

  • and it's a span on that same duration

  • that will work scaling before.

  • So that's the gestureTolerance.

  • As I was saying, this code is all on the repo

  • so you can actually read that method later.

  • Then we have the scaleFactor and scaleFactorMedium,

  • which are the scaleFactor.

  • As you can see, on a scale give us are the texture

  • that the texture give us a scaleFactor,

  • and we use that as scaleFactor with a clamp function

  • to limit the minimum and the maximum

  • scale of both RecyclerViews.

  • Of course, one is the inverse of the other,

  • and the minimum and maximum, they have to match.

  • Otherwise in the middle of the transition,

  • they would not have the same size,

  • and then the fade in, fade out will look terrible, right,

  • because it will not match.

  • So the numbers are whatever I like but you can actually

  • modify that and make it as complex as you want.

  • Then the outfit's the same, we want that outfit to be

  • in the middle of the transition,

  • half or both of the RecyclerViews,

  • and then at the beginning, a small RecyclerView want,

  • and the medium to see to,

  • and at the end the other way around.

  • So that's how the onScale works

  • but what happen if suddenly the user stops

  • touching in the middle of the transition?

  • If we don't do anything else, if we leave it as it is,

  • it's just gonna look like two RecyclerViews

  • and half half of both of them,

  • or you don't know, it depends right?

  • But it will look weird,

  • we're just getting a weirdest state.

  • So onScaleEnd, what I wanna do to hide this implementation,

  • this smoke and mirrors, what I want to do is just

  • finish the transition automatically to one of the states.

  • For that, I just use a TRANSITION_BOUNDARY

  • which transition one that is just like I calculate a delta,

  • and so I know how much is missing for the transition

  • so if it's below 20 or 30%, and you can change it

  • for whatever you want, I will assume that the user

  • didn't wanna go fullscreen and he actually wanna go back

  • to this small, right, that's what I do.

  • Otherwise, it fits that both that TRANSITION_BOUNDARY,

  • it means, okay, he wanna go to fullscreen

  • but he was just, doing really quick the move.

  • If you don't do that, what happens is like

  • everything just gets stuck in one place.

  • We don't want that because that will

  • show the trick to the user.

  • So with that, we have the container,

  • the medium RecyclerView, and the small RecyclerView.

  • But then let's talk about the fullscreen image container.

  • The fullscreen is a black, it's a friendly art,

  • which are black background,

  • and that shows in a full with the image, so exactly this.

  • So to do that, there is this requirement by a RecyclerView.

  • When you add an item to the RecyclerView,

  • the following, so you add one item and then another item.

  • The second item is gonna be in

  • a higher level base from the first one

  • so if you try to actually scale that first item,

  • it's gonna be drawing below the second item

  • so it would just not look right.

  • That's each item has an elevation in a RecyclerView.

  • So there are different approach.

  • This is probably the most difficult which is just create

  • a custom LayoutManager that knows

  • when we're clicking that item.

  • When we're clicking one single item,

  • we want that item to be on the top of everything,

  • and be able to draw above all the other items,

  • which I will not do because that's too much work

  • when you can fake it, exactly, I like to fake things.

  • So yeah, then you can use this one.

  • This is middle ground which is you see, is just a callback,

  • and then what you're gonna do is when you get that callback,

  • you set the elevations to the rest of the items

  • so they're in that we wanna scale,

  • is gonna be on the top of all of them.

  • But remember we talked about it five minutes,

  • no, not five, 10, 12, I don't even know.

  • At the beginning of the talk, we talked about your best

  • friend forever in animation from now on, ViewOverlay.

  • That's what we can use.

  • We can just use the ViewOverlay on top of the RecyclerView

  • for the transition for the pinch to zoom to fullscreen.

  • Then we just add that item, that view to the frame layout,

  • which is the fullScreenContainer.

  • Why you wanna make it more complicated

  • when you can do it easily, right?

  • That's it, it's like five lines.

  • So how does our, it's more than five lines.

  • There are some methods there and some instruction but okay.

  • You get the overlay from the fullScreenContainer.

  • You're gonna clear the state of that overlay

  • because you don't know if previously

  • maybe another item that was zoomed in.

  • Then you're gonna add a new item.

  • As you can see this was in onClick.

  • That's the perform click that we were doing before

  • on the itemTouchDispatcher, itemTouchListenerDispatcher.

  • Yes, that one.

  • What we're gonna do is, we animate that itemView,

  • and then animate to fullscreen,

  • and what we have to do is withEndAction,

  • which is gonna be setting the click listener

  • so we can go back to the gallery,

  • to the medium RecyclerView.

  • Let's take a look at that method.

  • So that method is actually pretty trivial too,

  • and as you can see, of course that is more things

  • going on like setting the background to BLACK,

  • setting the background to TRANSPARENT

  • or setting the visibility to GONE

  • but pretty much the idea is

  • you are just using the overlay to do your transitions,

  • and then at the end of the state,

  • when the transition is done, you add that view

  • to the real parent where we will actually add

  • all the logic to do, if you wanna did that image

  • or you wanna change the name of the image

  • of whatever gallery application does on a fullscreen image.

  • So what we are gonna do when somebody clicks on

  • that item on that fullscreen image again,

  • we just have to transition back to the medium RecyclerView

  • so we add that item again on the overlay.

  • Then we're just gonna animate it,

  • we're just gonna set the originX, originY

  • and then scale it to one,

  • which is the original size for that image.

  • Finally, don't forget to remove the item from overlay.

  • Otherwise it will just still be there until somebody,

  • something on the framework decides to recycle that.

  • That's it, that's how easy you can allow the user to

  • interact on the transition without using the

  • shared element transition.

  • Just by creating layers, layers on the top of it,

  • and just one activity.

  • Then you get this, you get zoom in, zoom out,

  • click listener fullscreen.

  • Not bad for a 20 minutes or 30 minutes of talk.

  • Again, magic guys, this is all magic.

  • That's what we do, we do, you're development, we do magic.

  • Magician is your new job role from now on.

  • So let's recap, let's recap.

  • Magic tricks that you can use for animations.

  • ClipPadding, ClipChildren to draw over parents and paddings.

  • That's important one.

  • If you see something is cutting your views,

  • it's probably one of those are not set to false.

  • The ViewOverlay, best friend forever for animations, really.

  • It allows you to draw over the whole layer hierarchy,

  • and to do any type of things without messing with it.

  • Shared element transition has, it doesn't allow the user

  • to control the transition without events.

  • So you can actually allow the user to do that

  • by just creating a single activity,

  • and then creating your own navigation,

  • which is not, it doesn't have to be super complex.

  • We don't need to have 300 life cycle events

  • or anything like that.

  • It should be just show, hide, and maybe something like

  • animate to next, or enter, or exit the screen.

  • That's whole idea for another talk.

  • Then finally, fast animations hide

  • any problem with implementation.

  • If you do it fast enough, as we saw during the talk,

  • it's just gonna look right, and nice, and smooth,

  • and good anyway.

  • So remember that, make it fast enough so the eyes

  • are not able to see the trick,

  • which is pretty much what magicians do.

  • With all that, thank you.

  • Here is the repo.

  • You can check the code right now.

  • You can ask me questions there too,

  • and if you want more examples of smoke and mirrors,

  • these great applications by Nick Butcher's Plaid

  • has many more examples.

  • So remember to rate my session, thank you.

  • (audience claps)

(enlightening music)

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

GOTO 2016--煙霧與鏡面背後的神奇UI在Android中的應用--Israel Ferrer Camacho。 (GOTO 2016 • Smoke & Mirrors the Magic behind Wonderful UI in Android • Israel Ferrer Camacho)

  • 68 7
    colin 發佈於 2021 年 01 月 14 日
影片單字