So i'm going to plan on going through so so i'll start recording now, and that weekend discuss this.
Okay, good morning, everyone. I took a poll just now of asking about the assignment.
3 due date. So always so. March 30, fifth. So this is my plan right now is that I will go through assignment.
3 is due today. You really should finish up as soon as possible. I'm going to turn in of course Luther.
It is so if you want a bit more time. But notice, August Thirtieth is there, and you just have a little over a week after that for assignment. 4.
So assignment. 4 will be out by friday so i'll be praying that out by fright.
So, by the way, whenever I use the theme you provide for a 3, it crashes.
Yeah, we'll discuss that in a second here so so anyway. So assignment 3 is, do you know so get it done as soon as possible.
I'm going to discuss it in our sense of solutions when I assign it 3 in a week in between now and then.
Well, today we have a tutorial to go through today.
See how that goes. No, we're not discussing the midterm today, because i'm only gonna discuss the midterm once.
So I think now I can focus on doing that. because so just you all know, there is no more tutorial tech.
You have not gotten marks back yet for the midterm gun marks back for the yeah.
The name of the . So this is the the reason why I got rid of the last of the tutorial is because we're sitting.
We're here the last day of class is the eighth we are here.
I think you all are still trying to just given the number of how people seem to be behind the tutorials.
I think I need to give you time for all you all to catch up.
And basically now you've gotten the last tutorial you'll then have the last assignment, and you have time to just kind of figure things out, and I can I have other topics i'd like to cover about
mobile application development over the next 2 weeks if you all don't have questions in particular.
I'd like to talk about mobile app security and it's nothing.
So we've got this play is stuff, to cover but you should focus on the tutorials in the assignments, and this last tutorial is a little chunky. so I think it's going to take
you some time to So anyway. so that's the that's where we are right now with the class what I'm applying on doing right now is i'm going to walk through getting to tutorial 9 running
and there's a few tricky bits in it so I figure it makes sense to start to go through it, but i'll Well, i'll just I don't want to walk through from scratch.
I have it already set up here in Android studio, and so we can talk about it in here 100, and then we can.
I can show you the parts that matter so first Let me show you it running, and then we'll get it running.
It might take a moment to run soul City sorry professor, you muted. that's really weird, because my okay, what are we doing here can hear, you know.
You can hear me. Fine? Yeah, Okay, that's really weird because nothing changed over here.
Okay, So where did you? Where did I lose you? I can change it. That must be a zoom glitch. So where all did I?
So all I was talking about was just talking about tutorial 9, and I want to go through the code, for it was I talk about anything else.
I don't think so. Okay, so here here it is here's the operating interviewer.
Demo yet continue. Okay, I just what's being slow okay fine so then we have an out here.
Now we have this photo here so looks familiar young kittens.
We can do things like this. We can enter in 90 degrees, or 1 8180 degrees, and we have an upside down.
Kiddies. Then we can with this and that we can make this twice as big as we can make this point 5, and there we'll take this back.
One knows when you delete it, it goes back to the default.
Value this by 100 and the same thing for the Okay.
So that was tracks. You have the keyboard there, but then we also can drag the image and move it around now, and we can click on the image, and it flips between the 2 pictures.
Now one thing to note is I don't have a rotation gesture, and I don't have a magnification gesture.
Those are, of course, possible to implement an android i'm putting that off for 2,600, and one for those of you who don't know.
I am teaching 26.0 one next year so if you all decide to take it.
You're gonna see more of me and android gestures are complicated.
And just yeah I think it's offered in the winter.
Next year 26, and one it's not offered in the fall.
So i'm teaching operating system the I actually think I asked them to move, to win Notice 1,601 is not offered next year.
Do you have to be in the mobile stream i'm not sure I don't think so, but I think you have to have taken this course.
You should be able to override, to get into 26.0 1.
Right now the mobile stream is going away. so so yeah So you get so you so I you should be able to take it if you've taken this course.
Why interest in resources. The it turns out the mob.
Well interest resources and overlap the mobile development. call I mean there's definitely things to be shown in mobile development. It means.
But there's a lot of overlap with other technologies, and so like what's a real thing?
And you know, you know people taking it now isn't so many and frankly, the people who can teach this course, I mean it's like me teaching this points versus teaching operating systems or teaching web development, or something so anyway,
There's mobile stream is going away i'm happy to keep, you know. Teach these courses, but in fact, I find these courses fun to teach, but from a overall curriculum perspective, You but preview of coming attractions we will
talk about proper gestures. and in 26 or one.
And yeah, I would like to get some of this mobile stuff put into the main theme.
One real problem as a computer science curriculum is fundamentally all the mobile technologies are proprietary to some degree, and because they are proprietary, there is lots of churn with them.
Like the the way things weren't one year you have to update.
If the next year or so teaching them in a course on a regular basis, is a pain.
From from that perspective, and conceptually, you can teach in other ways.
I mean that's that's also it's cross-platform, but it's also a moving target.
It's based on proprietary things Oh, you get even more weirdnesses in terms of how it fits up.
Remember when you're teaching courses computer science tack changes constantly the ideas of computer science don't change much at all.
I mean there's there's certain core ideas they are there, and once you really understand them, you'll see them all over the place.
That's why, when I look at a where i'm looking develop and mobile thing is like, okay, yeah, i'm teaching, i'm i'm using Kotlin Okay, I was using swift these are both languages I
didn't know before this course I spent some time but it's like I know other programming languages.
I know the fundamentals of them and things so I know what features to expect, and there's a little differences and stuff. but it doesn't take me long to learn them.
And that's how, in general, you have to be with computer technology, like just knowing Java, or just knowing, see or something like, you should know what it is.
So whatever tools are put front of you, you can figure it out.
Larger discussion. But, anyway, but short to say doing gestures in Android is really annoying, and we'll do that next year.
But so what I did but what I did they've left was this other stuff, and there's a number of things going on with my code for this.
But first let me just give you a quick tour of like the pieces ones and people are having some problem with themes.
So if you look at the themes here, notice the theme depends on this, and this is not an arbitrary constant.
This actually varies based in the name of your project if you Don't give it exactly the same name as mine.
This will change, and where is specified, is actually in Android manifest The this is where the name of it specifying.
See here, it says, Android theme, is this so?
If this doesn't match up with what you put in the themes, you're gonna crash at runtime nursing your crash at runtime not at compile time, because you know it doesn't check which I find kind
of lame. But yeah becomes a run time error so we'll talk about.
So I showed this last time, so I want to go through it too much.
But notice we put a splash screen in. we have we?
You know that this splash screen has the same structure as you originally have the main activity.
I just put main activities a song, you non-exported activity here, so we can call it separately.
And then, if we go to the splash screen code. it's really simple, it just is a basic activity.
That, you know this is all boring. The only thing interesting in here really is this function here, which is what gets called when we click on the button.
And how do we know it gets clicked when we get called?
We click on the button. it's because if we go to the splash screen, which is split.
So this is this here, and if we this button you can see here, what does a button have?
It. says It has an onclack handler which calls start name So that's connected to you.
Know the Splash Green function here start main, and all this does.
Is, it sets up an activity. This is an explicit activity, non implicit activity, which calls the class main activity.
In the in the current package packages. this Remember again.
These packages depend upon how you've named your named your application so don't nest don't if you create a new app.
Don't clobber this keep that and delete the rest.
So this just makes a splash screen. We saw this before.
So what is happening with the main, So the main out here Well, first let's look at the the layout of the screen here.
So what do we have here? We have a picture area so you can see there's an image you hear there are a bunch of text labels which are text views here.
And these are a bunch of edit texts notice they're kind of off to the side.
Here they're actually set relative to the right margin the right of the parent.
It's an offset from there and then these labels are compacted to
The text view that's how you get them all aligned. Now, one of the things I want to what you do is mush these over, and you have to think about what do I center them?
I would suggest, whatever you do, you the text views and then have the labels move with with them.
But anyway, so you have an image you there, and notice if we rotate to landscape, and you see that the image you gets rather mushed.
But these all stay squished over here to the side Oh, by the way I'm: okay.
If you decide to do what I actually am. okay. if you, I say, one of the tasks where you do is to move this either to the center or to the left.
If you want to do something more creative like, maybe do 2 of them over here and 2 of them over there.
Do something, so that at least some of them aren't anchored to the right of the screen.
Why do you see free hand lines like this? I mean, why do I see this sometimes?
And why do I see this sometimes is that What you're asking saw so similar to assignment?
3. The constraints are like wavy lines in them right.
The the wavy lines are are essentially springs they just show you like It's being pulled to one direction or the other like this.
Right now, doesn't have any springs because this is all anchored to the right, and it's just a fixed offset.
So it's not being there's no stretchable space okay.
So you see those wavy lines when it's like there's 2 springs like, Yeah, you say it's supposed to be attached to the start and the end of pair.
So the start and end. How does it do that it basically has to split the difference?
And so it's like you've attached 2 springs to it.
And it's. This resulted in it being centered the way the lines basically is acting like a flexible thing which could shrink or grow based on on on other things.
But here, there's no stretchiness it's just being anchored to the right side.
All right. Okay, and you'll notice it's angers the right side and particular, will they say the margin end is you know, 12 pixels over from the right and bottom it's like it's 11 pixels
up between them. So there's a little space between them so there, So these are the So this is this layout.
Now We, of course, went with this layout. we have to do something with it.
So let's go to main activity. Oh, by the way all the only the reason we have for themes this is the default theme, except for these 2 lines.
So It's So instead of replacing the entire theme you can just replace these 2 lines also make sure when you're doing it.
You've put the if you put the kittens the images in the right directory.
They should show up under drawable They should just appear like i've suggest going to your file browser and stepping.
There's a way to input them here, but I find it easier to just drag.
Just put the files in the right place, and then they just automatically appear.
But this this is all to get rid of the app bar at the top, but going through main activity.
So what do we have here? No, we have a bunch of includes.
We have a you know we have an image view which is P.
And then we have a pick which is the kittens image.
So just like the other drawables we have, are that drawable kitten.
So what this actually is is an int the number we don't know what it is that's defined it runs time.
But technically this variable is an int just to remember that. And then we have a bunch of references to.
So this pick, param watcher, and drag view. So these are 2 custom classes that are defined later in the code.
Then we have our on create in our on create you know we're not.
We actually don't do anything. with the bundle because we don't need to save any state, and you'll notice it actually saves it already.
One question is, but we call the super classes the on create like we do always.
We that our content view to actually remain, and then we initialize the various things.
So we say, P. is the my pick. My pick corresponds to
If you go to the image you it's called my pick So it's referring to this image the big thing here.
So we have we, you know we assign that there and then we assigned.
We to be a drag view, and xy and scale and R to be pick parameter?
These get some arguments, so drag view gets the view that we're gonna do the dragon, which is the infrastructure, and we give it an update function and a toggle image function.
Those are the 2 functions here, and we give pick param watcher.
The update function as well. we give it initial value.
These are the defaults for those those particular parameters, and then we give them the particular view that we're going to be attached to.
So the X Y scale and rotation so those correspond to the actual edit.
We're not doing anything at the labels because who cares about the labels we care about the edit taxes. And then, after doing all this, we call update.
So what does update to this? Should all be pretty you know this is kind of how we're doing things in android.
We set up. We set the picture so notice we're not getting the picture from the Internet.
That's another thing we've putting off to next year, because was looking isn't simply some simple way of doing it.
And it turns out the only simple way I could see of doing it involved pulling in external libraries.
It's like I figure this and and the ways to do it would involve me teaching you about concurrency and stuff, and you that can wait.
So. So instead I just did a built-in image resource.
And so we set the image to be what the image is supposed to be.
And which is again pick, is just a number, but that sets the image resource Way knows which one to use.
Here we we have this conditional here which is checking to see whether there's a flag in drag V.
Called pitcher drag. So what that what this is saying is in this case the user has actually dragged the image, and in this case the user hasn't dragged the image.
And then we set the rotation set and the scale.
So the question is is so. it's kind of like moved. but this it is kind of like moved and picked the analyzed.
Yeah, it are, but it's a what remote pick you are. you Know that text analyzer will pick if you were to not pick viewer that it's very similar to that.
But there's a little bit of weirdness in here so this flag.
The reason we have to do this is because our state it's kind of messed up.
We have state in multiple places that are not synchronized, and so we have to synchronize it.
So let's talk So the so was it the So the image has has a position, but also the what i'm really talking about here is that in in Swift Ui you can designate something as a state and you can make.
Everything, depend upon that state. and then everyone's going to update at the same time.
And so you don't have to worry about it so for example. If we made a text field B a specific value, we could make it so that and then we made the position of the image be a function of that value they automatically stay
synchronized in normal android program in normal storyboard programming.
You don't have that the image has a merit position. it's and other parameters that are separate from any sort of other things that we have like. Maybe a text entry box.
Those are separate things, and we have to implement the code to make them behave as if they're saying we have to synchronize them.
And that's in effect what's happening in this code So if you look here at the know at the you know if the picture has been dragged, what that means is is the values in the image are not this the Xy values of the
image are not the same as in the text thing. so what we have to do is well.
First we say no it hasn't been dragged out because we're updating everything, and then we set the value of the
We set the value of x and y to be P. x py.
And then we tell it to refresh. and so i'll show you what the refresh is, and then but otherwise all we have to do is get the value from X and y you know from the edit text ones and set the picture to be those
positions, and that's we just do that for rotation and scale.
We don't have to worry about doing this whole stuff the separate stuff, because we can only draw the image.
We can't rotate it or scale it using gestures. but we could Then we would have to do something like that for those values.
So that's the update function and then the toggle image function, is it?
Just checks to see if this drawable that's kittens or as it's rosy, so it just swaps between them.
If you're going to add more images you'd have to make this a bit more complicated of course, so the heart of the action is this: pick parameter, watcher, and drag view drag view.
This is basically the circle handling the circle dragon code.
It's essentially the same. there's a couple of little differences.
The main differences, you know. So you have our on touch handler.
We have a construct. so i've dragged this out into a class. The reason I pulled this out into a class is, remember, with the old code.
We ended up duplicating code to do dragging and stuff and it wasn't No, no, we have to duplicate code, but like when you change things around and you you end up having to change a bunch of variables and
like to the names, the names that make much sense because was talking about Red Circle and other things.
So here i've made a generic version and we can just instantiate.
The class, as you're supposed to do with good software abstraction.
We have a but otherwise we just fall for this code it's it's almost exactly the same. the only thing that's a bit different.
Here is i've made the events a bit different here, although I think we talked.
I think we talked about this. This is implementing a movement and a click to.
So if the action is down, we say, the last last action was down, and then you know, if it if the last action was, if we end up dragging it, then we'll get move events.
And so we say it was the last was down. No, it was moved, so we set that to false, and then we calculate the drag offset.
When we say yes, the picture is going drag when we call it update to make sure everything stays updated.
Then if it's up and the last one was down then we called the Click Handler, because the then you know there's been a down, followed by it up without a move in between.
So that's a click that's a top and so we can call our click, camera, and then we have a constructor which just sets over here.
By the way, in Kotlin, the Ide will tell you to turn this.
This is called a secondary constructor, and there's a way for cotton to do.
Primary constructors which have the syntax, which kind of falls off of the very first line.
I find the syntax for the secondary constructor's very confusing, and I just can't keep them straight, and I go like, Where is it all starting and ending I don't like it so I prefer this that function that
says that's that's my personal preference it makes a little more verbose, but it's just a function, and you know this function takes a view as an argument.
And a functions as an argument which all take no parameters and return nothing.
And then there's pick-pam, watcher So this is like in yield it the text, the text analyzer.
Again. we just have. We just have an after-text change method.
And this is basically what we've seen before you know we just.
But this is converting it to a number. Then we have a look.
We actually have a value here that says, So we have a We have a value here.
This is actually the vout, the float value of it.
So convert it from the straight. the textual thing in the edit text.
So we have to keep this in sync, because the rest of the stuff wants a number, and so we should make sure to make that available, and that has to be kept in synchronization with the text value in the text widget that
we included. So this, So all this stuff is basically, as we expect, pulling this into a class makes the code much more compact because we need 4 of these one for each field.
And I normally need to declare this code once so that's nice
But and then I have this constructor which just takes the default value, and I set that to the default value and the initial values. Those get stated the widget.
So the edit text is here. The update function is here.
Then what we do is, we add in text, change lessoner to this.
So this is how we, instead of calling, add text, change, listener.
Otherwise we can just do it here with the past in edit tax. then we call refresh.
Now this refresh is is actually very simple all it Does is it just says that, Okay, we've changed the value, and we set the you know, Widget set text value to string.
Now the question is, why do I need this value changed it's for a really stupid reason which I feel I don't feel this is that elegant.
It works where I don't completely like it when I do a widget set text, i'm changing the value of the text in the widget. So it's since I have changed the value this is the equivalent to someone typing in
the field. So since this is a equivalent to typing in the field after text, change will get called after this completes.
And so if you don't have this I i'm pretty sure this happened in my film.
This will get It was like type verify that i'll have to check that.
I missed a mystical thing to verify that.
So if this basically just prevents this code from running, if it turns out that we had, you know, Basically, if we this in effect calls this function, and I don't really want to do it there, because then you could you know it just is doing
a necessary work, I think I can get a loop in here with when it goes from the drag to there like cause because when this refresh value, you don't want it to constantly be doing, this because then every as you drag the constantly goes
here, and then it goes there and goes back and forth, and it just does not good.
So we need a short circuit, This: Yeah. yeah, yeah, we are volume current.
Exactly. But again this is gross I don't like this but such as it is, gets the job done. Let's try.
I should let's get it let's comment out that code and see if the code works.
Because if I if i'm wrong, that should work fine with it i'm not sure what make sure this code is. so we'll get this back here running here.
Okay, And so the dragon is working fine and notice as we drag it up updates those numbers nicely.
So that's good. Now let's get rid of this code and see if I am right.
So this is the only code that really cares about that and let's red deploy.
Oh, so we're a completely sure of set text actually calls the after text change after being, I wasn't quite sure about that.
I might be wrong. Oh, yeah, did you all See that it just crashed. Let's try that again.
Keep stopping. Yes, you need this that's why I had that in Yep.
It crashes, it keeps blue on itself, and just yeah crashes the app.
So instead of locking up, I think it just android just Texas in a loop.
And or does it crash actually slow back, but yeah let's pick up so.
But now everything's working fine, I think it's like an inescapable while loop. But but just notice the So whenever you do a set tax so it's all because when you do this drag we're changing the value
here. we're doing this, we're basically so the edit tax normally set up so that you have a string, and it gets converted to a value.
But here we're gonna basically take the value from the image and update the text yield.
So we're going the reverse direction. and so if we go the reverse direction, and then we don't go back the other way.
Yeah, I haven't worked out exactly what's happening but yeah I definitely needed to put that code in.
There you can kind of see those that weird loop dependence.
There, and you just need to put some logs in to see exactly what's getting called when and see if it works of it is because I bet it might be kind of interesting to or to go with a debugger set a breakpoint
and watch what happens. questions about the code so as you see this code is, I haven't really introduced much new here.
I really just wanted to put stuff we put together like we have.
A dragable thing was already there from the ball stuff. This stuff is all from the you know.
Text, analyzer stuff, taking text and manipulating it but here we're converting it to numbers I.
We got rid of the title bar the the news stuff is we're actually showing an image rather than a rather than a square or something.
But you see most of the ways of displaying the resources the same.
We just do. We are drawable kitchens kittens versus Roshi.
That's all this same stuff is doing it with the squares circles and stuff.
Though the one thing that is kind of I avoided a lot of code duplication by doing this, because otherwise I would have to define a separate handler for each of these text fields.
And this way I just have one I will tell you for for the tutorial for some of the stuff you're not gonna nest like you.
You may have to split this up, and we implement this in multiple times or do something with it because one of the tasks.
So what are the tasks I want you to do?
Add at least one image. theop makes the old new images display when clicking on the credit image.
This should be pretty easy. Move the scale rotation position entry. So the left.
The center of the screen. make sure that maintain. So this is messing with the lab again, fiddly, but not conceptually hard.
As long as you understand layouts out of Widget.
That shows the name of the current image just above the rotation text entry area that allows a new emission.
You have to be able to add something to It it's going to be a pop-up Menu.
You've done pop-up menus already. in you know with the text analyzer, app So just I would suggest doing that, or you could enter. use the text entry.
I think a pop-up menu would be better But up to you, but you're gonna have to add some code to add in strings to associate them with the image name.
So that's gonna take a little work from stuff we've seen before.
Change the rotation scaling parameters, they automatically set the default values.
The image is not called So you're gonna have to because oh!
By the way, this thing does some weird stuff. so if you if I scale this to.
So that's good. And now, if I try driving it watch how the dragging happens.
Do you see why this is happening. it's because it's dragging the center.
The original image, not of the scaled image i'm not going to ask you to fix this, because to fix this means we have to take this this really shanky code here, and make it do the proper geometry stuff and really
it's gonna be better with we're going to do that next year, you know.
But this is not the way to do it and you need to do a better way of doing this, because this is just, or you could add an explicit calculation to fix this but it's it's going to take some math
26.0 one. Yes, would we do something like a double zoom?
We necessary if statement side. I don't quite understand which one that will do something like double zoom if we nested if statements.
Go ahead. i'll like if you want to add double click to zoom.
Yeah, you could implement double click to zoom. That is certainly a possible thing to do.
But the double clicks a little trickier if Holy Bay, better do a long click.
You have to start taking into account the time in which you pressed it. You're basically doing this all manually, and really what you should be using is higher level abstractions or handling gestures.
And android does have higher level support but again they're not so easy to use, and we'll go through the next year.
But in terms of this yeah doing this part this is again just app applying stuff.
We used previously change the rotation scaling pressure. They always have default values.
This is just messing with the values. make it impossible to drag the image off screen partially, completely back.
So I coordinates. so notice this will make sure that if you're
If the image is not get its default position, the rotation and scaling parameters won't affect it. So you won't basically get rid of the weirdness because it's just gonna lock it into the original position when you
rotate and scale it. but if you start if you make it impossible to drag the image off screen completely, so you have to compute the bounding box and make sure.
So this is going to be interesting, because when the image is at full size.
You know you're just gonna be able to drag it up and down.
So this is Well, I think i'm going to change that a little bit that gets kind of boring. Well, i'll adjust that a little bit. I don't like that.
Because then you can't actually drag it out much you can just drag it up and down.
Yeah, I I don't make at least at least at least a quarter of the image. Have to stay on screen.
Okay, that's relevant and Then change the image click, event to instead load the given image in the browser.
So this is just changing the click thing to Do this So the thing that's most annoying is this one.
You know I think I don't know how we change our right now.
He kept on. Okay, So this half of this is not quite like it's not half in terms of area, but just half in terms of the X or Y.
You and we went through this intent stuff in the last.
In the last lecture 2 so you get a chance to practice that.
But here you'll have to make sure instead of loading you should load the in the Urls. So the image Urls, you have them already, for you know just the this: is this is the location of kittens here, and this is the location of
Roshi. you have to have another Url for your images.
By the way, if you have access to access, you have access to a web server or you just use a publicly available image.
If you just put things in the public underscore Html Directory on on access, you should be able to access under people about Ssd.
Carlton, that's a so the way this zax is on access.
I just have attracted public. Html. and I have my home page in there.
That's it for today unless there are questions otherwise i'm going to stop recording. stop lecture, and i'll stick around, and I can do checkoffs and help you all with your tutorials saw how you want