Android lifecycle



romain guy: good afternoon,everyone. and welcome to the sessionon writing custom views for android. and the title is a bitmisleading, because we won't be showing code, or we won'tbe writing code.


Android lifecycle, my name is romain guy. and this is adam powell. and we both work on the android framework team at google.


adam works a lot onthe ui toolkit. and you have seen his work inthe action bar, the view pager, the support library. he's the mind behindall of that. i focus mostly on graphics,performance, and animations. but i've done a little bit ofui toolkit in the past. so i think i know whati'm talking about. adam powell: so why would youactually want to write your own custom views?


isn't the framework goodenough for that? are we missing something? well, usually the frameworkhas what you need. but between the framework andthe support library, you kind of have what you needto get everything in the design guide. and reusing those frameworkcomponents ensures the user is familiar with thepatterns there. and hopefully the componentsare stable.


but sometimes you just reallyneed to stand out. so just like larry was sayingthis morning, your app is doing something unique. otherwise why areyou writing it? you might need graphs, otherdata visualizations, other things that just arereally unique to what your app is doing. maybe you need somesort of custom interaction with your content.


i mean, not everythingfits within a list view or a scroll view. and touch is a greatway to feel connected to your content. and writing a view gives youfull control over that. so who here uses relativelayout, for an example? a lot of hands. that's great.


probably because thisguy told you to. romain guy: now a while ago,i wrote a blog that was misinterpreted. and now everybody thinks theyshould be using relativelayout all the time. please don't. adam powell: it's agreat view, right? romain guy: it works. we can get to that later,if we have time.


adam powell: sure. so relativelayout will measurechild views more than once in order to solve some of theconstraints that you give it. so being generic has a cost. a little domain knowledgecan go a long way for optimization. really, there should always beone part of your app that can catch someone's eye from acrossa room, something that's instantly identifiable.


if one of your users is usingyour app in a coffee shop, someone clear across theroom should be able to tell what it is. so you want to make yourapp fun and satisfying. and the design guidelinesare great. but apps that do unique thingswill always beg for some sort of innovative ways to do them. so members of the androidcommunity have already given several talks lately that havebeen really great, and given a


lot of information on writingcustom views. and not only that, thereare a lot of great code examples available. and android open source projectitself is a great resource for you to look at. but realistically, we want tokeep this talk a little bit more abstract, as youwere saying earlier. so in writing our own customviews, and helping others write them as well, we founda lot of common patterns


emerged from this. and we found ourselvesgiving the same recommendations over and over. and we're going to spend most ofour time here today talking about those experiences and whatworked well, what didn't, and what can really help youfrom getting caught in a [? rapple ?] of the internal designof your components. so to do that, we still needsome context about how the


system works. so we'll go aheadand start with-- romain guy: but just before onthe previous slide, don't believe the "tips andtrick" bullet. we removed that section. so there won't be tipsand there won't be tricks for you today. adam powell: well, we mighthave some tips and tricks along the way.


romain guy: yeah,along the way. so we'll start withlive of a view. so how many of you haveever seen the activity lifecycle diagram? all right. how many of you understand theactivity lifecycle diagram? you're a bunch of liars. i've been on the teamfor six years. i still don't get it.


i exaggerate. but it's complicated. but the lifecycle diagram ofactivities makes guarantees about the methods that willbe invoked on your activities and when. and we have similarthings for views. it's a lot simpler,as you will see. but we have guaranteesthat we can promise. so the life of a view ismade of three things.


we have the attachmentand detachment. and this is actually a veryimportant part of the life of a view. and i've never or rarely seenarticles online talk about it, or examples focusing on that. then with traversals that youmay know as drawing and layout and measurement. and finally, we have the statesaving and restoring. so let's get started with theattachment and detachment.


actually, another quick poll. how many of you have used thatmethod onattachedtowindow? all right, that's pretty good. so whenever you attach a viewto a parent-- so you call a viewgroup, that add view-- ifthat parent already belongs to window, in ui toolkit[? balance ?] we said that the view gets attachedto the window. so you get this call back,onattachedtowindow. and this is where the viewknows it can be active.


so this is where you shouldstart allocating any resources you might need. this is where you can registerlisteners on other pieces of the application on the system. and for instance, in list view,when you attach a list view to a window, this is whenwe attach a listener to your adaptor after so that listview knows when the data changes in the adaptor. and again, you shouldtake a look at the


source code of android. so if you look at the sourcecode of view.java, or abslistview.java, you will seethe kind of things that we do in onattachedtowindow. but even more important is thesecond callback called ondetachedfromwindow. so we call that callbackwhenever a view is removed from its parent and if thatparent is attached to window. this can happen for anumber of reasons.


maybe the view is gettingrecycled in the list view when you're scrolling. maybe you called remove viewon the parent of that view. or maybe we are tearingdown the activity. when we tear down the activitywhen there's a finished event on the activity, we're goingto remove every view. and we're going to detachthem from the window. this callback is very important,because this is where you can stop doingany kind of work


that was already scheduled. so if you had scheduled ananimation, like a scroll or a fling, if you had a backgroundthread running, you can stop those things right here. also, if you had allocatedresources like a drawing cache of some sort, or any otherresource that your custom view might need, this is avery good place to clean up those resources. a good example is for thehardware renderer.


so in android 3.0, we addedhardware acceleration. and we created a lot of nativeobjects that attached views during the lifecycleof the view. and when the view gets detachedfrom the window, this is where we can destroy thosenative objects, because we know that the view will not beshown on screen anymore. so we make sure to promisewhen you get ondetachfromwindow, you candestroy all these resources. of course, this is a promisethat we make.


but sometimes when you implementyour own custom views, and you try to be, let'ssay, smart about your lifecycle of the view, you mightrun into real issues where the view will be detachedbut it's not. or the view will think itis attached, it is not attached and it is. we've run into a number ofbugs like that in our own applications. adam powell: a couple.


romain guy: so be very carefulwhen you use adview, removeview. and view group has a numberof methods where you can temporarily detach a viewfrom the window. so if you're using thosemethods, be very careful. and that's about it for thelifecycle of a view. so what is missing? what is missing is all theevents that you get on an activity, so things likeonpause, onresume, onstop.


and we have a lot of requestsfrom people who are asking to get those lifecycle eventson view itself. the reason why we don't havethose lifecycle events on view is about abstractionand layering. the way the android framework isbuilt, we try to layer our packages on top of each other. so what you see on the sideright here is actually the layering that we haveinternally. so the android.app package thatcontains activity and


context sits on top of prettymuch everything else. at the bottom, we haveandroid.widget, where you have your text view, your listview, your image view, things like that. and that sits on topof android.view. so you could actually build aversion, i would say the fork of android, where you getrid of android.widget. and you just keepandroid.view. and the system wouldjust work.


so instead of adding thoseactivity lifecycle events to views, what you should do iscreate your own sets of listeners or callbacksin your custom views. so here, there's a very simpleexample of custom listeners that you could specifyon your view. and it will be theresponsibility of the activity to invoke those callbackson the view. another way of doing it is justto add methods straight to your class.


if you have used gl surfaceviewthat's used to do opengl rendering, thisis what happens. this view has itsown on pause, on stop, on resume methods. and it is your responsibilitywhen you add that view to an activity to call those methodsat the right time. so we don't need to add support for that in the framework. you can do it yourself.


we know it's a bit more work. but you can easily write utilitylibraries or classes in your code to helpyou do that. i briefly mentionedtraversals before. and traversals are scheduledin three different ways. they can be scheduledby animations. and we're talking about the newanimation system that was introduced in honeycomb. the old animation system isactually part of drawing.


traversals can also be triggeredby requestlayout and invalidate. and this is what the traversallooks like. and if you want to be reallyscared, go look at viewrootimpl.java in thesource code of android. and look there's a method calledperform traversals. and try to understandwhat it does. once again, i've been writingcode in that method for years. and i still don'tquite get it.


don't laugh. it's true. so we first startwith animation. so with a new animationsystem, there will be callbacks related to animationsthat will be triggered at the beginningof a traversal. then we're going to do themeasurement pass, then the layout pass, and finallythe drawing pass. the order that you see thoseevents on screen is


guaranteed. if you see a layout, there willalways be a draw after. you can't see a draw andthen the layout. what can happen, though, is youcould have a measure in the layout and not a draw. or you could have a draw but nota measure in the layout. the only tricky part here isthat the measure and the layout always happen together. you cannot have one without theother, unless you're doing


something really bad inyour application. adam powell: all right. so let's dive a littlebit deeper on some of these topics. so measurement and layoutis where we'll go ahead and begin. all views know how to measurethemselves and lay out their content. and leaf node views that don'tactually have any children


should measure their internallydisplayed content and go ahead and laythat content out during these two steps. so viewgroups on the other handorganize, measure, and lay out a seriesof child views. so requestlayout is the firststep in this whole process. at some point, somepiece of state changed within your view. requestlayout is the signal tothe view system that it needs


to recalculate the measurementand layout of the views. so it means somethingvery specific in terms of what changed. i means that something changedthat can alter the size, and by extension the layout withinall the ancestors moving up the hierarchy. so requestlayout is recursive. a change in the size of a leafnode way down at the bottom of the tree can influence the sizegoing all the way up the


tree as well. romain guy: and this is actuallyone of the reasons why we often mention that youshouldn't have too many views in your application,in your ui. and more importantly, we saidthat you shouldn't have too deep of a tree. and this is one of the reasons,because every time we call requestlayout, we have towalk all the way back up. so when you call requestlayoutonce, it


doesn't really matter. but if you [? update ?] a lot ofviews and every one of them tries to go back up the tree,it can take up a significant amount of time. we have optimizations in theui toolkit to avoid doing extra work. but every bit can help. adam powell: that's right. so because of this process,anything can change.


it can dramatically change theway that the view's parent, grandparent, orgreat-grandparent measures and lays out the otherviews around it. so on measure, it'swhere your view implements the measure step. it's called by the actualmeasure method within view to determine the view's size. in a viewgroup, again, thisis a recursive process. so viewgroups will go ahead andcall measure on each one


of their child views. and then they can usethe results to help decide their own size. so the parameters onmeasureare these packed measure spec values. they're packed intoa 32-bit end. so the make measurespec methodgoes ahead and packs a size and a mode code intothese values. and then the getsize and getmodemethods listed here


unpack them for you. and we'll go ahead and talk alittle bit more about measure spec modes in a bit. when a viewgroup is measured,it has a responsibility to make sure that it's childviews have been properly measured as well. a layout request may haveoriginated from a leaf node deep down the hierarchy. and depending on how a viewgroupdecides to arrange


its children, one small changein size down the leaf node can drastically alter thelayout above it. if this sounds expensive, it'sbecause it really can be. multi-pass measurement ina viewgroup is sometimes necessary when you're tryingto resolve different constraints for a layout. but because of that, it canreally add up fast. and this is usually a goodtime to dust off your algorithm analysis techniques.


so finally, onmeasure doesn'tactually return a value. instead you callsetmeasureddimension to set width and height explicitly. this is enforced. if you forget to do this, thenthe framework is going to throw an exception andcrash your app. the sizes that you set hereare reported by the getmeasuredwidth andgetmeasuredheight methods, not the normal getwidth andgetheight methods you may be


familiar with. this is because the processis two step. getwidth and getheight don'tactually have their values initialized until layoutis complete. so you can use the measured sizeof these child views to decide your own size or performany other bookkeeping after the child'smeasure returns. so back to modes. there are three differentmodes.


the first one is exactly. and it means exactlywhat it says. this mode can be used if there'sa fixed size specified or if the parent view hasotherwise calculated a fixed size for it. so if you're familiar with thematch parents that you might set in the layoutparams orweight that you might use in linear layout, these are goodexamples of when we might use the exactly mode.


it's common to go ahead and doa second pass to finalize a measurement in a multi-passscenario. and weight is one of these. since we distribute whateverleftover weight is still remaining after we've measuredall the child views, we use exactly to go ahead and lock inthe extra size to each one of the child views. so at_most specifies an upperbound with the implication that the view should usuallybe conservative with that.


the measured size should alwaysbe less than or equal to the size reportedin the measurespec. when you give a view width ofwrap content, then the stock framework layouts will useat_most to measure that child. the view has the option ofconsuming up to that specified size if it really wants to. and finally, you have theunspecified mode. this is where we just reallydon't know anything enough to tell you how to measure in thisparticular dimension.


the view has potentiallyinfinite space available to it. so this is really common forthings like scroll containers, so scroll view, listview, et cetera. the limits are based only on thecontent that you're trying to place there. so most views still treatthis the same way that they do with at_most. they just don't impose theupper bound constraint.


the implication is that the viewshould still try and be as conservative aspossible and wrap tightly around the content. so making sure that you actuallyget the right measure specs that match what your childviews want, it can be a little bit tricky. there are few utilities in theframework that can help out with this, though. one of these utilities is thegetchildmeasurespec method.


it understands the standardframework patterns for how layout params and measurespecs should interact with one another. it's kind of a handshake betweenthe two that happens during measurementand the parent. so for example, if a parenthas exactly 300 pixels available to it and a childwants to wrap content within it, then the spec that we'llactually send to that child is 300 pixels in theat_most mode.


so once measurement is complete,layout is just a matter of positioningthe child views that we've already measured. so usually this is where weapply offsets, padding, margins, so on and so forth. and while viewgroups can oftenimplement multi-pass measurement to get thingsjust right, layout will only happen once. if there's some expensivecomputation that you need to


perform during the whole measurelayout sequence, then you should really try and deferit to layout if you can to be more efficient. that way you don't get caughtup in these multiple measure passes that can happen. and even if your own customview doesn't do multiple measure passes, some view that'sfurther above you in the hierarchy may beperforming that. so you still want to be asoptimal as possible.


so this two phase measurementin layout means that you'll often want a way to get at someof the data that you've already computed in onmeasureso that you don't have to compute it twice. getmeasuredwidth and height arealways there for you to use for this purpose. but sometimes you need to havemore info than that. you'll want to wait for childviews to communicate extra configuration data to yourlayout code in general, such


as gravity, for one example. romain guy: we're going totalk about layoutparams. but just before we get started,so we mentioned the three different measurespec modes. it's real scary and intimidatingwhen you're trying to write a custom viewand you think about how can i implement all those modes? you don't have to. if you write a custom view andyou know exactly how it's


going to be used in your ui, youknow it's always going to be match parent, match parent,just implement the measure spec exactly. that's the big differencebetween what you can do in a custom view. you can cut corners. you can cheat. you can make it a lotmore efficient. and what we can do in our viewsin the framework is we


have to make them work inall possible situations. so our code is a lot morecomplicated and harder to [? optimize ?] than what you can do. and this is why we keep tellingpeople, you should try to create custom views wheneveryou can, because you can make them a lot easier towrite and much more efficient than the ones that we have. for instance, if you are tryinguse all the different


widgets that we have in the uitoolkit to create a really complex ui and it doesn't quitework, you can write a custom view instead. it's going to be easier. you might spend less timewriting that java code than trying to come up with the magicxml incantation that's going to do what you want. and it's also going tobe more efficient. so to create the measure specsfor your children, if you're


writing a custom view thatextends viewgroups, or if you're writing a custom layout,you will be very interested in layoutparams. so layoutparams, you knowwhat they are from xml most of the time. they are all those attributesthat sell to layout underscore, and a map to a classthat is typically called layoutparams. and it's static in your classof the layout it belongs to.


so the base class is calledviewgroup.layoutparams. but we also havelinearlayout.layoutparams. we have framelayout.layoutparams, and so on. you don't have todo it this way. this is just the recommendedway. the base layoutparamsclass will give you a width and a height. there's another oneyou can use.


it's called marginlayout params. it will give you the extramargin parameters if you need bespoke margins in yourcustomer group. so layoutparams are reallydumb objects. they are just hereto store data. they just store the argumentsthat you're getting from the view when it's addedto the viewgroup. so either from code-- when you say add view, you pressthe view, then the set


of layoutparams-- or from xml, you can[? import ?] the layoutparams from xml. and you know about thewidth and height. but in linearlayout, wementioned the weight. this is one of the paramsthat we store in linearlayout.layoutparams. it's always a mouthful[inaudible]. adam powell: it is.


romain guy: we needto rename them. beyond layoutparams. so if you create customlayoutparams because you want more than the width and theheight, there are four other methods that you shouldimplement in your custom viewgroup. so we have one calledcheck layoutparams. this is invoked when you adda view to a viewgroup. if that group already haslayoutparams attached to it,


we're going to call checklayoutparams to see if those layoutparams are compatiblewith the viewgroup. so usually what viewsdo here, it's just an instance of check. so if you look at linearlayout,it just does the parameters instance oflinearlayout.layoutparams. but you could do a lot more. if you have a lot of customparameters, you could vary the constraints, for instance, andthrow an exception if they


don't work. generic layoutparams, thetexture layoutparams attribute, can be usedto do conversion. so if you add a view that waspreviously in the frame layout and it has frame layoutlayoutparams, and then that view is added to your viewgroup,and if you know how to convert those frame layouts,layoutparams in your layoutparams, you can doso in that method. generic layoutparams within anattribute set, this is what's


used when we inflate thelayoutparams from xml. so the default behavior herethat we use-- actually, that's what we use all the time-- we just call the constructoror layoutparams [inaudible] the attribute set. and all the workis done there. and finally, defaultlayoutparams. if you don't specifylayoutparams when you add a view from code, we're going totry to guess what's the best


configuration for viewgroup. so typically in the framelayout, we're going to do match parents, match parents. a linear layout will dosomething like wrap content, wrap content, somethinglike that. but don't forget thatlayoutparams can also be used to store private data. so if you do a lot of expensivecomputations during the measure pass or even doingthe layout pass, you can store


all that data per childin the layoutparams. so if you go look at the sourcecode of relativelayout, for instance, that's exactlywhat it does. it does its own private fieldsto keep track of what's going on. i want to talk brieflyabout drawing. we won't spend too much time onit, because we have a lot of other sessionsabout rendering. but the way to trigger a jointtraversal is to call


i'm sure a lot of you arefamiliar with that method. and just like with therequestlayout, it's a recursive algorithm. so it's going to walkup the tree. so i'm going to call invalidateon the parents [inaudible] something calledinvalidatechild. and those methods are actuallypretty expensive. requestlayout is pretty cheapbecause all it does, it sends


a flag saying i wantto layout. invalidate has to keep track ofanimations, of bounds, of transforms, things like that. so again, if you go look at thesource code that occurs, you'll see that it's not atrivial method to call. again, we try to optimizethose calls. so if you have two siblingsof a viewgroup that call invalidate, only one of themwill go all the way up. calling invalidate without anyparameters will mark the


entire view as dirty. there's a variant of invalidatethat takes four parameters. it's a sub-rectangle of the viewthat you want to redraw. so whenever you can, if you haveenough information about what's going on inside theview, try to use a second variant of the method. it will be a lot cheaper forthe ui toolkit and for your application to do the redrawwhen we come back down.


so once we call invalidate,we're going to call the draw method on your view, andpossibly on other views. so the draw method in the baseview class is final. you cannot override that method,because it does a lot of bookkeeping that we don'twant you to mess with. and trust me, you reallydon't want to have to deal with that. draw will invoke the methodsthat you can override. so the first one iscalled ondrawing.


so how many of you have everimplemented the ondraw method? that's really good. adam powell: they havelots of experience. romain guy: so the only goalof the ondraw method is to draw the content of the view. you don't have to drawa background. the base view class, the drawmethod will do that for you. but any other content you wantto draw, like text view. that's where you do it.


there's a little trick. we have a method that-- i hate that name. it's so confusing-- setwillnotdraw(true). again, after six years, stillget it wrong every time i try to use it. and it's even worse, becauseinternally it's implemented as a bit inside the [inaudible].


so with all the mess thatyou have to use, it gets really confusing. viewgroup by defaultwill set that flad. so when that flag is set, youpromise that you do not want to do anything. your children will draw. but you're not been goingto draw anything. you don't have a background. you don't want to draw anything


on top of your children. so in that case, we're goingto skip the ondraw call. and we're going to call directlyin the other method called dispatchdraw. and dispatchdraw is anotherpretty complex method. but you can override it. it's responsible for drawingthe children. and this is where we apply allthe transforms, like the alpha, rotation, scaling, andanimations with the old


animation system. and for every child, wecall a method called viewgroup.drawchild. so if you want to override thatmethod entirely, make sure that you call the drawchildmethod for every one of your children. otherwise you're not going toget animations working or transforms. there's a big difference betweensoftware and hardware


rendering in the way we callthose drawing methods. so as i mentioned before, weintroduced hardware rendering in android 3.0. and in software, if you callinvalidate, we're going to call the draw method of everyview that's a parent of the view that called invalidate. we are also going to call thedraw method of any view that intersects with thedirty region. so if you have views stacked ontop of each other, and even


if they're siblings, we aregoing to call a draw method on every one of those views. so it can be pretty expensive. in hardware, however, we are acompletely different system. and i won't go intodetails here. there was a talk two yearsago explaining how it works exactly. but only the view that callsinvalidate will see its draw method invoked.


this is much more efficient. you can imagine that if you have10 parents, and suddenly we have to call only one methodinstead of 11, it's going to be a lot faster. so you can refer to that talk,"accelerated android rendering," where we explainedin detail how the new rendering system works. so a lot of your views are goingto have instant state. this is some extra informationthat you're going to want to


be able to save for later. android app componentscan come and go at any time, remember. so process containersget killed. activities get recreated if youchange the orientation or something else changes. but views can actually savetheir own state for later in a way that can be persistedby the system. so two methods control thissave and restore process,


named onsaveinstancestate andonrestoreinstancestate. and the easiest way to writeone of these instance state objects that gets persisted isto extend the base saved state in a static inner classof your view. and this establishes conventionsfor how sub class and super class state getorganized within this persistent bundle. so the standard namingconvention is just in a class called saved statewithin your view.


views need to have an id fortheir instance state to be saved and restored. this is really important. this also needs to be uniquewithin your view hierarchy. this is how we actually match upwhat data to pump back into the onrestore method when yourviews get recreated. so if you duplicate the idwithin multiple views within your hierarchy, we're going torestore that same state to multiple views, which probablyisn't what you want.


so the mechanisms behindactually saving the instance state are pretty welldocumented. but what you save is a moreinteresting question. don't bother saving anythingthat's a part of your data model. instead, save things that area reflection of the views state as it relates to theuser's interaction with it. so you really want tokeep these concerns as separate as possible.


normal data loading within yourapp is going to take care of reflecting the stateof your data model. there's really no reason to saveit a second time and have multiple sources of truth. instead, the view instancestate should take care of leaving the details wherethe user left them. so things like uncommitted userinput can be a little bit of a grey area in this, liketext entered in the field if you have a really longform, for example.


in many cases, we'll go aheadand save this for you. so edit text will automaticallypersist whatever text the user's entered. romain guy: so basically you'retelling people to not be like a webpage-- like when you reload the webpageand all your stuff disappears? adam powell: yeah, basically. so next we have touch events.


touch events are fun. they're really a keycomponent of any interactive view these days. so the basic event handling,again, is well documented. but what happens when itgets more complex? what happens when you actuallyhave views at multiple levels of the hierarchy thatneed to negotiate? well, first off, it's importantto know what a consistent event stream means.


android has this idea of aconsistent event stream when it comes to motionevent objects. this is a guarantee from otherparts of the view system to your views. you really shouldn't break thisguarantee you when you write your views andyou end up sending events to other views. you want to make sure thatthese guarantees hold. so action_down startsa new gesture.


it's really the beginningof a touch interaction. it's when the first touch pointcontacts the stream. and then throughout the courseof a gesture, you might get additional action_pointer_downand action_pointer_up events as more touch points beyondthe first enter and leave the screen. now each one of these pointershas an id attached to it. and these can be used to trackthe same touch point when you have multiple touchpoints active.


action_pointer_down is the startof a specific pointer becoming valid. and up is that pointerbecoming invalid. so while a gesture is inprogress, you'll get the steady stream of actionmove events as those pointers move around. these events contain info aboutevery touch point that's currently in contactwith the screen. and you'll have been told abouteach and every one of


these through either theinitial action_down or action_pointer_down events. and if any of them leave thescreen, you'll be told through an action_pointer_up or thefinal action_up event. action_up or action_cancel endsthe current gesture in progress entirely. it means the user is doneinteracting with the screen for the time being. action_up means thatit ended normally.


action_cancel means thatsomething else took the user's control away from your view. so what this means is thataction_up is where you should do things like fling, oractually apply a click event. whereas action_cancel shouldnever commit an action, because you never really knowwhat took the user's control away from that view. now when you have multiple viewsworking together to form your ui's full touchinteraction, it's important to


factor that interactionappropriately across your different views. now android gives you severaltools for views to collaborate and decide which view shouldactually be responsible for handling a current touchinteraction. now ontouchevent is thesimplest of these. if a view returns true fromontouchevent for an initial action_down, then the rest ofthe event stream will be sent to that view.


so it'll try and find thedeepest view that will accept a touch event. it's kind of like focus fortouch events, really. now parent views have anadditional method that they can use for this, and that'sonintercepttouchevent. this will be called for eachevent that one of the parent views' children receives. by returning true for this, theparent can go ahead and steal the event stream awayfrom the child view.


the child will get anaction_cancel event, since that's what a view receiveswhenever the event stream is taken away from itfor some reason. and the parent will receive therest of the current events stream through its ownontouchevent method, not through theonintercepttouchevent method. now onintercept is a great wayto implement things like scrolling and dragging. but it can really beinsufficient if you have


several levels ofnested views. now list views inside view pagesare a great example. so to handle this case, wehave this method that-- what is it with our frameworkhaving all these mouthful of constants and methods in here? romain guy: we have to be veryspecific in the names. adam powell: right. so we have requestdisallowintercepttouchevent. now by calling this method on aparent view, a view can stop


the parent's onintercept methodfrom being called for the remaining eventsin the gesture. and in the case of somethinglike the list view inside the view pager, list viewinvokes this method. and then it actually will lockthe pager to the current page. the pager or has no idea thatyou're moving back and forth left and right. and so therefore you won't movebetween pages if you just want to make a really sloppyscroll within that list.


so speaking of sloppyscrolling-- well, in a second. one way or another, thesethree methods, when put together, it means that youcan write custom views and viewgroups without being tooconcerned about how you're going to compose them. and this is really important. it means that you can keep allthese concerns separate within the different custom viewsthat you might write.


the right thing will just happennaturally as long as you don't nest strollingalong the same axis. i mean, how many times have weall been using a webpage, and we'll go ahead and scroll witha mouse wheel or something like that, and then suddenlyscrolling stops because there was this other internallyscrolling region that your cursor just happened tobe hovering over? you don't want to build thatwithin a touch ui. for this whole game of rock,paper, scissors to work, you


really an opportunity todetermine the user's intent before committing to one actionversus the other. and view configuration is aclass in the framework that has a lot of constants and othervalues that control how the framework tunes thesesorts of things. in this case, you havegetscaledtouchslot. now this is going to be adistance reported back to you in pixels adjusted for thedensity of the current screen that is the distance that youhave to travel in terms of


touch motion before you actuallycommit to scrolling within that view. so having this slop within thatgets checked within your onintercept method for ascrolling container means that the child views have anopportunity to say, no, actually i want this eventstream, and call requestdisallowintersepttouchevent up to the parent, so on and so forth. romain guy: and viewconfiguration is a very useful


class if you're doing anythinguseful with your custom view, like touch handling, or evenanimations or drawing. you might want to take a look atview configuration and the kind of data it exposes. because everything in that classis meant to help you be consistent with the existingui toolkit. so if you need a duration, theremay be a duration in there that matches your needs. so make sure to takea look at it.


and the class is actuallypretty well documented. you can once again look at thesource code of the android platform and seehow we use it. so we have four minutesleft for questions. so if you have a question,please walk up to the mics in the aisles. and before you leave theroom, there are bar codes by the door. you can scan them if you wantto rate the session.


and we'll be at the office hourson the floor to answer all your questions throughoutthe day. thank you for coming. [applause] audience: hello. i have a question. i want to implement view that'slike a heartbeat, like it's pulsing. but what i want it to do is iwill have that method like it


posts every second or so. and i wanted animationthat posts back. so how should i do that? should i have in my view somekind of timer that draws the circle smaller and smallerevery 20 milliseconds? should this be partof the view? romain guy: so you shoulddefinitely use the animation framework. and tomorrow i'm giving a talkwith chet haase on animations.


and this is the kind ofanimation that we're going to talk about. audience: and the other quickone is some phones send you back an app event after 15seconds, something like that, that's in the original[? matrix. ?] i want to have a little buttonwhich is press and hold. but after 15 seconds, itgive me app event. how can i do that? adam powell: that was thesame on the motorola


zoom, wasn't it? romain guy: yeah. sounds like a bug in the[? touch dryer. ?] audience: any workaround forthis, that you know about? [interposing voices] adam powell: unfortunatelythat's one of those things where there are some devices outthere with touch firmware that try and do this. it's basically because thedevice is trying to account


for a noise or other sources oferror that might be in the environment so that you don'thave this permanent touch point down. unfortunately, it ends up beingway too aggressive. because if you're in a casewhere you're holding down the gas pedal in a racing game, orsomething like that, that becomes really problematic. and unfortunately, there's justnot a whole lot you can do about it.


audience: thank you. audience: hi. so when you started, youmentioned that there was a blog post about relativelayoutsthat was yeah, it was misinterpreted. everybody i know follows that. so could you elaborateon that a little bit? romain guy: so i think theoriginal post was about not using a linear layout with animage in the text view and


using only a single text view. or maybe you could use only-- no. it was about using arelativelayout to avoid nesting linear layouts. audience: that and weights,i think, as well, right? romain guy: yeah, somethinglike that. adam powell: it was specificallyin the context of list items, too, right?


romain guy: that's correct. so it was the context of listitems to avoid nesting a vertical linear layout in ahorizontal linear layout. so it's still true, ifyou're using weights. but using your relativelayoutto do everything is not the right answer. so if a firm layout does the jobbecause you need to stack views, or if you just want toput the view side by side, go view linear layoutor firm layout.


a relativelayout will alwaysdo two measure passes. so when you nest,then, you get an exponential measurement algorithm. romain guy: last question. audience: hi, i have acustom view that was a background shadow. and i noticed that itworks ok until 4.2. and in 4.2, i get some visualartifacts that are strange. is there anything that changedin the rendering?


romain guy: not thati can think of. it might be a bug on our side. or you might have beenrelying on the but that existed before. i would need to see codeand a running example. send me an apk that[? repositions ?] the issue. and we can take a lookat it and see if it's a bug on our side.


adam powell: or if you'd likewe'll be in the sandbox. romain guy: for officehours, yes. audience: if possible,another question. is there an easy way to addmargins to a list item entry? romain guy: to what? audience: to a list viewentry to add margins? because the margins arecut by the list view. romain guy: oh, you shoulduse the padding instead. audience: even if wehave a background?


romain guy: well, use paddingin the parent view. and then you put thebackground inside. audience: ok, thanks. romain guy: thank you. we are out of time.


Android lifecycle

come to the office hoursin the sandbox. adam powell: yep, happy toanswer your questions at office hours. thanks.



Android lifecycle Rating: 4.5 Diposkan Oleh: PaduWaras