Let's get started! Start Studio We might have a bit of work to do here Create new project Let's give it a useful name Note the traditional convention for company/package names We don't need C++ support To choose an SDK, we don't need to pick the same minimum SDK that matches our system image Take a look at the install bases when deciding this Though we're still going to pick API 23 anyway We don't need to create an initial Activity, but we may as well Let's create the 'Empty' one The other ones mostly indicate what subtype of Activity to begin with, what additional properties that Activity should have, and whether or not to include additional intiial components (e.g. note the 'menu' button in the upper-right of the Basic Activity) We can call this first one whatever we want In a 'real' app, this would probably be a splash screen (if desired), a main menu (for a game), or our initial operating mode (for other apps) But we're not making a 'real' app, so let's go with the default The Layout Name doesn't have to match the Activity Name, but as we'll see soon, they're very closely connected, so it's highly advisable to have them there We don't really care about the Backwards Compatibility yet; that'll relate to the Action Bar (later) And now, we wait... Done waiting? Great! Before we get any further, let's ensure that we have a functional AVD Tools Android AVD Manager Let's create a new one I'm going to go with a Nexus 4 For the most part, this won't affect anything, except for specifically when we're dealing with multiple sets of resolution-dependent resources (later), so pick whatever you like Under the Recommended tab, it should only show 'good' system images We want Marshmallow/23/x86/Android 6.0 (Google APIs) WE'RE NOT DONE YET! The minimal stuff it shows is fine as-is (change if you prefer), but we need to Show Advanced Settings Under RAM, lower it drastically The minimum is 128 MB. 500 is probably plenty; I'll be going with 768, just to be safe Under the VM heap, 50 is fine For Internal Storage, the minimum is 200 250 would likely be plenty, but just in case we need some unusually large files later, I'll go with 300 For the SD card, 20 is plenty fine It'll warn about erasing the contents; that's fine There are a couple other settings you can change if you want, but otherwise, click Finish It'll probably seem to be frozen for a little while; that's normal. Just wait some more... Eventually, you'll be returned to the AVD Manager. From there, you'll see your new device. If you want, you can click the play button to start it, the pencil to edit its settings, or the drop-down for more additional options. Feel free to start it now; otherwise, Studio can auto-start it once we need it.
Let's look at this project we created... If we click on File, we can choose Project Structure There are a few interesting things here, but mostly we're looking at the 'app' Module If it lists a 'Compile Sdk Version' and/or 'Build Tools Version', those are the parts that are most likely to get snippy when you try to migrate to another version of Android Studio So leave them alone for now, but remember that if you ever have problems You might also want to take a look at the Dependencies tab This is where you'll be looking if you want to include additional Android features supported by Studio, but not included as default dependencies Also, before we get any further, try looking at Run Edit Configurations... Feel free to take a glance at the Build menu as well, but we can worry about that a bit later Before we actually look at the code itself, let's take a look at some of those autogenerated files As in, let's take a look outside of Android Studio We have an 'app', 'build', and 'gradle' folder, as well as a few 'hidden' ones There's some interesting stuff under 'gradle', including targeted vs minimum sdk We can delete 'build' and '.gradle' if we ever need to package up for submission Note:.gradle but not gradle! Under app src main, we see three points of interest: The manifest file, which we'll be examining within Android Studio soon A java folder that currently has very little within it A res (resource) folder, which some interesting folders We'll get into these more in two weeks Before we get any further, have we discussed intents and life cycles yet? If not, maybe we (briefly) should... Okay, back to Android Studio now... Let's revisit that manifest file Note how XML works: if you open something, you need to close it We need to list every activity that will be available to the application The 'intent-filter' lets us associate special properties with activities, such that they can perform special tasks (in this case, acting as the main launcher) You might notice that we already have things like an icon, theme, etc. More on that later The initial Activity we're provided with is pretty minimal Note that it overrides the oncreate callback But the first thing it does is to invoke the supertype's standard behaviour We're receiving a 'Bundle', but that isn't interesting just yet That setcontentview, however, is very interesting... As are R and activity_main... Of course, just about all of the standard Java stuff applies here: Commenting, coding standards, annotations, etc. If we need to, we're free to create additional Java classes (i.e. not connected directly to any activity/layout) One minor note: a couple of things will be slightly different; mostly related to how we handle filesystems and especially threading Let's look at the layout file now! The default view might be the Design view, but I'm going to use Text instead Assuming there's room, you'll still have a preview, and can change what it displays on/as The XML is pretty simple Next week, we'll get into layouts and containers properly, but basically this is very similar to how
Java Swing works: you can either have 'a thing', or that 'thing' can be 'a thing that holds more things'; each of which is either 'a thing' or 'a thing that holds things' In this case, the default is ConstraintLayout; for goofing about I'm partial to RelativeLayout. We'll be getting into these more next week Inside that is a single 'View'; in particular, a TextView TextViews are like Swing's JLabels Note that a view will typically have several attributes The layout_width and layout_height indicate its dimensions. These can be either explicit, or it can be a term that indicates how Android should handle it e.g. match_parent to tell it to try to fill the enclosing container, or wrap_content to tell it to resize itself as necessary to just barely fit its contents First, we all understand the connection between this layout file and the code (and thus final product), right? Assuming so, let's try adding an editable text field! We'll use the EditText View We'll stick with wrap_content for the height, but what about the width? fill_parent works. match_parent will probably work better, but may be autoreplaced by the editor We could try something like 360px, but why is that a bad idea? Let's briefly discuss: px dp/dip sp in/mm I think I'll go with 150dip For positioning, it might go with tools:layout_editor_absolutex/y, or app:layout_constraint... Similarly, under RelativeLayout, we could have things like android:layout_centerinparent, etc. We'll revisit this next week, but this is as good a time as any to discuss why it's so complicated For now, let's just use a modification of what we were provided with If we like, we can add some default text by again using android:text Let's take a look at what we have so far (such as it is). Note that, when trying to run it, it may ask us what device to use Let's try rotating the screen Note that the 'Hello World' in the middle has moved! The need for elastic and flexible layouts starting to make sense? Anything else we notice when we rotate the screen? Hmm... that's a problem... we'll need to address that! Before we address that rotation issue, let's add another type of element that might help us understand better. Let's add a Button Note that positioning will be tricky until we learn just a bit more For now, just set tools:layout_editor_absolutey= 100dip or similar Let's give it some text: android:text= button one Note that this is actually a terrible way to do this, but we'll improve in two weeks For ha-ha's, let's add two more as well. Give them text like button two and button three Okay, so we want the buttons to do something. How can we give some behaviour to button one? There's an android:onclick property... perhaps we could use that? Let's just add that property, and try using it... Oops. Okay, so what do we do? We need to add some code, clearly!
Note that it isn't sufficient to have a method with the right name. We need the right signature! So, what should it do? System.out.println? I mean, it works... Try using Log? Well, that works, too, but... Let's talk about Toast! Let's jump straight to the end: Toast.makeText(MainActivity.this,"Howdy!", Toast.LENGTH_SHORT).show(); Okay, that's interesting... huh? There are a few parts to note here. Luckily, the code completion actually gives enough hints to understand the components. Note, however, that providing the String directly like this is a bad idea Hey, let's try displaying the contents of an instance variable! As an interruption, I wonder what would happen if we put added a Toast to our oncreate? So far, so good. Let's try making the second button increment that instance variable's contents. Having any aspect of the code in the layout/xml is poor form Let's instead add a Listener to Button Two This will require creating an anonymous class... We all know what that means, right? What we want is a new subtype of Button.OnClickListener, with the onclick method overridden. We'll then assign that new class via the button's setonclicklistener method Of course, that means we need to grab the button... The button that exists only in the xml layout file. Uh oh... Wait! No! That's not true! It really is translated into Java code! (Somewhere) Super-important time: Go back and add an 'id' to the button: android:id= @+id/buttontwo Now, in the code, we can use findviewbyid on R.id.buttontwo How does that work? More importantly, why doesn't this work? Because it returns a View, that needs to be explicitly downcast Okay, now let's have it increment our instance variable! It works! And now we rotate and... Oh nertz... we'll come back to that... We have a pressing issue: randomly-placed listeners make our code hard to read. Also, who wants to have a separate class per button?!? If we do assign an id to each button, we can just have our main activity become a listener. All we need to do is to implement the interface We can use the more general View.OnClickListener Naturally, Studio will complain until we provide that onclick method Let's verify that the View received is the third button, and, if so, reset the tally This will require giving that button an id, and then comparing our view's getid() against R.id.whateveryouchose Naturally, we still need to assign this context as the button's listener, but that should be easy by now We still haven't dealt with the problem of losing our information yet. First, let's also add an id to the text field, and and then start trying to work that out... What?!? What do you mean it works now? How???
Okay, so one final problem: our instance variables. Everything else is being saved when onsaveinstancestate is called, and restored upon onrestoreinstancestate. Those methods simply don't know how to handle our instance variables. If only we could have a more specialized version of those behaviours...