Splash Screen, Login Page & UI Tests (Social Network with Ktor) - Twitch Recording Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello hello how are you doing guys can you hear me for some reason i hear myself let me ch because my twitch tab is open okay yeah so welcome to the stream in case you have missed the last stream in the last one we did these mock-ups for the app we will build together in this stream or in the future streams here that will essentially be a social network app for my community for you which is quite complex actually let's see how how well that goes in the stream um so we just have a simple splash screen we have login registration we will use a caterer backend that we'll also make in the stream here in a future stream not today we have our main feed with just um posts by people we actually follow we have a post detail screen here it's it's similar to instagram in the end then what is that oh that is a chat screen which we'll probably make towards the end of this project because i think that chat is the most complex thing here um you can see just yeah real-time chat we have an activities tree uh screen similar to instagram just you can see hey this dude liked your post commented and stuff like that and a profile we can add little uh programming languages badges or whatever we can add github instagram and linkedin links and simply yeah edit our profile it's in the end just a social network um so that you can see how i approach a project that you can see how i struggle with projects and how i yeah soft bugs that i will encounter because on youtube everything is perfect because i record it i perfectly cut it together but in a stream that won't be the case so that is the goal of this of these twitch streams also a lot of people asked me if i will record these streams which i will do right now i click on record um so yeah i will record these and i will upload these on youtube and future for channel members so that will be for a very small fee um around five euros a month should be affordable for most people um yeah that i will set that up in the next days and i will also upload the the first few streams for free so you can just just get an impression um of of how these look like on youtube so in case you missed all of these and yeah as always if you have any questions oops then just put these in the chat and i will take a look here and there um is there an option now for choosing the video quality that was another common question from the last time because i have researched a bit and it looks like this transcoding stuff so that you can choose the quality is only available for like twitch affiliates and twitch partners which i'm not yet um but yeah maybe maybe you only have full hd right now but in future hopefully it will get better i think i missed the previous stream and can't find the vod in the channel no because i forgot to enable the recording option last time i will upload it soon on my youtube channel so not a problem but there was actually a technical issue that 30 minutes weren't recorded the last time so these are these are lost but like three and a half hours are not so most of the stream is not yeah but today we can actually use these mock-ups and start coding so now that the more exciting part starts we will use jetpack compose which is now officially stable in case you've missed it so we can use the normal android studio which hopefully gives us less issues and less pain and yeah the plan for today is that we implement i don't know if we implement the whole ui yet but at least some of these screens in jetpack compose so that we can see these in the app that is usually what i do first when i have mockups that i just implement the ui so i actually created a little product in here you have to tell me now if this is too small because i can zoom in a little bit if that's too small like the font um like maybe like this if this is better yeah looks like it's too small this is very weird for me but is this fine now i also by the way added oh come on do i have to make this for every screen every file uh more than fine okay let's let's do it like this and check the settings where i can change the font size for everything um use custom font i don't want a custom font so sounds good bro that looks more like it let's shoot something like 22. um yeah that's really big for me but if it's fine for you then it should be cool so all i did in this project is um that i added the dependencies i don't know if they say all yet that's a little bit too big let's make it you're right make it 18. yeah that's that's a lot better for me i hope for you it's uh big enough as well um so all i did was i added the dependencies which is yeah the the composite penalties here we have navigation curtains just the standard stuff dagger healed retrofit obviously we need to communicate to our cato back end later timber for logging and all the testing dependencies here not sure yet if you really need all of these but that is basically just my my standard dependencies i just include in all of my projects by default and maybe we will need to edit this later nevertheless the first thing i want to do is i want to set up kind of an app theme here so in compose we always have this theme that anderson creates for us which we can find here in our package i'm not sure if i can change the font here so i think you have to live with that if i leave it like that but the code is the most important thing here so if we take a look in theme then we have our dark colors and our light colors question is do we want to have a light theme i don't think we want that because we only created mock-ups for the dark theme so i will simply do whoop and only use the dark color palette um and here for the colors we can simply then remove that and set this to our dark color palette if you don't know what this theming stuff is for in compose it basically just defines some standard colors like primary premiere variant secondary and we can define some more here which we'll do to just access these values from all over europe and simply yeah if you want to change that theme you only need to do it here and it will affect your whole app then yeah which colors do we want to have um hey phil can you make your app support multiple screens yeah we will take a look at that um i'm not sure if i will make it for i will support tablets as well but if something looks weird on different phone screens then obviously we will fix that um let's take a look in our color file we actually don't need this purple colors and stuff here it's a little bit bad that i need to switch screens all the time here um let's see which colors we need so the background color is always the same that is this which is it yeah this color let's define that as dark gray yeah just our gray then what do we have we have the text color the white um which is six times e i like to call that text white because i don't choose a total white color for my text only a slightly slightly darker white um the reason for that is that this is a little bit better readable in terms of usability if you have a slightly darker white or on a dark background um instead if you don't do that the contrast is very very high and it's the text is basically screaming at you and i don't like this too much how much ram does your pc have philip i have 32 gigabytes of ram where can i find the previous videos nowhere yet soon on youtube for channel members um we of course want to have our accent color this green here which is my standard green um how do we call this green accent i would say and this gray for hints val what do we call this light gray i would say and simply paste this and yeah we don't even have that many colors let's take a look that's actually not a lot of colors we have here um i think this is the gray i paste it no it's not the same one but it's very very similar um what's this this gray is something different here yeah four zero four zero four zero i call it medium gray this yes i will be using ktor i hate firebase you will probably not see me using firebase again in future at least for stuff like databases and authentication um i think that's it for for the colors so let's define that in our theme obviously these ones are obsolete now so we have a primary color which should be our green accent then we don't really have a primary variant do we have a secondary color um i don't know how which which of these color values i assign something to definitely we have a background which is our dark gray we have on background which is the color that is on our background which is our text white and what else do we have here error colors fine [Music] on primary that is the color on our primary color so on our green which is our dark gray so that is for example this text color here on our button and i phillip have you ever tried flutter yes i have tried that flutter is cool but dart is pretty much that's why i don't use it um i have to say for freelancing flutter is pretty cool because most clients actually ask for android and ios app but i rather want to dive into km in future don't have a mac yet but my plans to get one once the new macbooks are out the macbook pros um which colors are we missing on secondary we don't we don't have a secondary color on surface what's the difference between surface and background i'm not actually not really sure yet i think it's which color are we missing light grey is the the text color medium gray let's make that our surface color on medium gray which is this one here for example you can see that is our background color here that the top gray and this is our surface and then we have on surface which is this lighter gray um what is it i think it's it's very similar to the hint color what's this now let's make this an additional color i will call this hint gray not sure if that's the best naming but yeah because i want to call this one light gray and then pick that for on surface like a light gray welcome florian how's it going will i upload the project in github after the session yes that will always be public in my github repository by the way we can actually do that right now pushing that to github i'm also fine thanks um first of all we're going to get rid of this dark theme and then we will push this initial project to github um question is do i run this first i hope android studio doesn't lead to um twitch dropping frames or rather my pc dropping frames when i build this let's try this just see if this actually compiles and runs and if it does then we can push it to github and meanwhile i can answer some questions we will have these situations quite often here i guess that gradle is building for ages what kind of stuff are you using to inspect colors not sure which software you mean do you mean this one that is adobe xd it dropped frames yeah i guess that but it shouldn't happen too often because only for the the first build it usually lags a little bit it doesn't need to build that much if we do it frequently hello red death bk how's it going why you prefer wxd on no particular reason it's as good as figma you can also use figma any collaboration expected possible with coding and flow for twitch sessions yeah i don't know i think florian doesn't like to stream at least what he told me but yeah that's good idea yeah sure always open for collaboration next time i visit phillip yeah then we go live together maybe also with with codepellers that would be cool did you decide what db will you be using i guess you mean the database back inside i think in order to finished um the database backhand side not yet we will also not be doing this in this stream but it will be either mongodb or postgresql one of these so um where's my emulator hello android that looks cool so let's push this to github uh social network bridge let's oh my old account you can see how many of you followed me so early who still know the this name where does the architecture use mvi and we'll use mbvm um hello philip time to kick some indians from the whatsapp group um yeah it's not the group is not only related to coding it's just a fun group but if if some people violate the rules just tag me and then i will take a look we'll use coin for di for the the android app i will use dagger hilt and for ktour probably co in yes okay so project is on github if you check out my github repo now you should be able to see that my github profile i mean let's start to implement the ui let's get rid of this first of all we have a surface which i usually just wrap around everything man that is so unused that this font is so big here and the problem is i have quite a big screen and that makes it much smaller for you um let's make this first of all fill the whole size another question would be that should i make open this amulet here in android studio as a window so now there's an extra window because android studio does have the option should be better i guess i think we can do this in the settings let's close this one launch a tool window this one if we now launch this which whatsapp group is it something related to channel to discuss coding yeah i do have a whatsapp group which is quite filled with people whatsapp does have a limit for that i created that over a year ago but there is not much space in it anymore i think but you can also always join my discord server it's it's basically the same just without limit i don't have the link right now it's on my phone so share your github link made here let's take a look you just need to use google github philip lucknow it's that easy see there you go and here is the repo let's simply take that oh someone was faster discord server i don't have the link let's take a look here take my channel okay this one doesn't have any any limit so you can always use it to draw my discord and there you have a bunch of channels to ask your questions then let's see uh we are here in emerson i think that is a bit better if we take the emulator on the right hand side here like this um so we just have our blank screen let's first get rid of this damn purple bar um here's status per color just color primary variant we don't want that it's quite weird and composed that we have two themes but yeah i will just yeah let's let's define this colors again like here we have our dark gray color we have green accent um medium gray light gray and in the gray i don't think we need this in the theme and i would say let's let's take the text wide which is this um like gray this that looks better let's now take this question is which color do we make this toolbar i think our accent color is too bright so if we if we take our color green accent here i think that's the bride i'm not sure how do you like this finding color next versus an object yeah so for our app itself we define these colors here and in our theme but the thing is we still have our themes xml which defines these the stuff that we can change and compose i think like this app bar the status bar here i think i just make it gray that's too bright just our dark gray so we have the same background now the the same color for this as for background yeah like this it just looked like a full screen app yeah i can see a white that's fine so let's go back okay so you can find the discord link if you scroll up a few messages here let's let's take a look which screens we need here um first of all our splash screen um do we start with this i don't know if i really always want to see the splash screen i mean we can we can just put the delay to zero questions do we even want to make this a separate screen and compose because i have a video where this is actually also possible to have a splash screen without any screen but i don't know i haven't used that in compose yet not sure if this this works um let me import my my logo i think i can open my project here how did i call it splash screen i really like to just open ola project and copy stuff over that i have done in the past it just speeds up your coding so much but also just to find out what i actually did back then because i can't remember will you make it full screen hide notification but i don't see any reason why we should make this app full screen it's not like a game or anything that really needs other space so this one looks like full screen but we still see the notification bar i am miraculous thank you um let me close this chord again let me check here in my other project in here yeah so so basically what we do is we go to our themes xml and in here we we have a property that is called window background and this window background is the the color or the drawable that appears when your app is actually launching so you can see that if we rerun this app not sure if this gets clicked here yeah now we have a wide screen and we can change that with the window background property and we can apply a drawable to that so our splash screen would really only display as long as our app needs to boot and not longer because usually some apps have splash screens they just delay and just show for like five seconds but if we're honest we are only annoyed by these apps we don't want to see splash screens it's only only the developers who will love their logo but the users usually don't care so what we do is we just show it as long as the app boots and for that i want to import my logo and let me see i don't want to show you that here where is my desktop here this one i think yes there it is we call it ic logo this is quite big let's make it smaller like 200 dp maybe even 150. we import this and then yes let's add that to good then we have it here and we can now create a drawable file let me check how i did that yeah so we define a new drawable file called resource file which i will call splash screen and we make that a layer list in which we can now define items on the one hand we want to give this drawable a background color for our splash screen which is android drawable which is just our dark gray and then we can draw an actual xml drawable that we just imported on top of that so another item which is our we also define a drawable this time our ic logo and we set the gravity to center so that will just center it not sure if this now works with compose if we now go to our themes xml and um do we make it a separate theme i mean both we we only have one activity anyways so it should be fine window background and here we now pass our splash screen drawable let's try that out relaunch the app and if it launches now and doesn't work okay that's weird um what if we make this a separate theme so style let's call it splash screen theme the parent is something with no action bar let's take this one and we just do this window background stuff here and what if we then i don't think that will work no because we already defined that here i think but let's try that splash screen theme set that to our activity no it doesn't look like that okay then we need to do differently fine let's remove this stuff again and this too here you have to apply theme in manifest yeah it is applied by default here that is our theme from our style i mean it also changed something when we did this with a dark gray here so if you really launched the app then the the bar here will turn gray again can we use bitmap i think you can also use bitmaps and drawable files yeah so you can see now it's it actually changed something when we changed something in the theme here i don't know why the window background doesn't work in xml it did but let's let's do it differently and first structure this a little bit so i want to use a clean architecture approach here which i'm also a little bit new to so like using use cases and the usual mbvm stuff in the end we have a presentation layer domain layer and the data layer if you don't know why we separate our app like that the reason is simply it it makes it so much easier to extend it it makes it so much easier to test it and also if we separate our our app into presentation so everything that's visible on our screen into domain which is the the business logic and into data which communicates with an api or a database then if we change something in one of these layers that that also means that we can usually only break something in one of these layers so we don't actually want to change something in the domain layer and break something in the data layer that shouldn't happen and if we separate these layers like that then yeah then this shouldn't happen the ui package is something that comes from compose i usually like this in the presentation layer um the main activity as well because we're composed we just have this single activity and in this presentation layer we will then have packages for our signal screens so let's make this splash screen let's just call it splash and i want to have a util package as well in which i will now create the navigation stuff navigation so let's define that here i have a detailed tutorial about navigation and compose so i won't go into that in detail here we just have our nav controller we can use to simply navigate between screens we define here and then we have our nav host where we can pass the snap controller we don't want the graph instead of start destination and here now we need to think about how we call our different screens for that i'd like to create a helper class for each screen which is a sealed class um and this here class takes a route so an xml that was different then we defined this nav graph here we don't have this instead it's more like for web development we have these routes which are the equivalent to urls and then we have our screens here so first we have our splash screen and the route will just be splash screen um yeah then we have a lot more screens here we have a login screen register screen um how do you call it main feed screen i would say why do you define it as object because these don't need any parameters if you want to pass some parameters to these screens then you need to make these data classes so you can see then you would do it like this and here pass on parameters but if you don't have parameters you can't define data classes and you can simply make these objects it's the the easiest way um what else do we have our post detail chat messages then we have a profile screen edit profile screen we have a search screen personalist screen activity screen and that is a lot of screens person list screen then create post screen activity screen and i think one is missing this third screen is the new energy stable have you experienced any problems with it not yet no seems stable i've heard from some people that some configuration changes but i haven't noticed any of that yet okay so now we have our screens that we defined here obviously we need to change the names for these post detail chat screen edit profile screen you can choose anything you like here for these names it's just to identify a specific screen what's sonalint that is a simple linting tool if you don't know what linter is it's basically a tool that analyzes your code and gives you warnings more warnings than android studio gives you by default it just helps you to have a clean code and sometimes you you do something unintentionally and it notifies you about that i would always use a similar tool and finally search screen fine let's take a look back in navigation can you have support multiple backstack um i personally haven't worked with that yet but i think the android team talked about something like that in the past don't know if it's with the old navigation component or if it's with a compose navigation maybe it would be something to find out but yeah let's let's not prioritize that for now we now just define our start destination and now we can use man i can't do this on one line it's too big we now define the start destination using our screen class a dot splash screen dot route so now we can always easily access these routes here yeah the new update for nav components has that but in compose we don't use navigation component we use navigation compose are these route objects singleton yes these objects are singletons so we can easily just access these routes like that and if we need to put it in more data for a screen we can simply make that data class and put it in the constructor okay so let's have our composables um if you don't know how this works if you haven't used compose yet we just define these composable blocks here in which we define a route for that composable so these are basically just screens of our app like our splash screen then we have this block here in this block we just put a composable that should be displayed when we visit that route it's it's very easy let's also do our next composable block here i won't do all of this for now we will first implement the splash screen um the route will be [Music] yeah what what is the next screen should be login i think this one so i will do how will we do this um let's first commit this implemented basic package structure and basic navigation setup mid and push is it my internet or his i think that's your internet i mean i see my bit right here that's it's quite stable unless more of you say that it's laggy or whatever what keys do you use to highlight every word for example in brackets not sure what you mean with that to highlight every word do you mean like this so when i have the cursor here i press ctrl shift and right arrow then i select the whole word i think i also set up a shortcut too no okay that wasn't planned um you can also set a shortcut to select the whole line but it's it's get used to this this speeds up your coding so much you can just easily select this cut it paste it whatever i just joined how much i missed ah you you missed not too much we just implemented the basic theming for our app and now we're at the navigation stuff so we now want to put in a composable here in this block that defines our splash screen we do this in our package here called splash screen like this and this will need a reference to our nav controller because we want to navigate from the splash screen to the next screen how long will the stream last yeah the last one was four hours and yeah maybe maybe today will be similar i'm not sure yet how frequently i will stream i actually want want to stream more frequently than just once a week but i'm not that consistent yet with having the same day um not sure i mean sunday itself is a good day but sunday is also a day where i'm not always at home like next week for example i can stream sunday um so how how how many of you could actually also watch streams at a similar time between monday and friday that would also be cool to know because in in the week so not on the weekend then i'm usually at home how many words can you type per second ah i don't know i think it was something between 90 and 100 last time i made the test but not with coding stuff with normal words so yeah splash screen what do we have we want to have our logo display in the center of the screen so let's define a box we use a box to center stuff um modifier will be modifier film exercise and content alignment will also be center and then i actually recorded a tutorial for a splash screen today so i'm quite quite in it in the box you want to center an image with the painter resource our drawable our logo import r i see what did i call it why don't i have it here where's my logo it's gone where is it i deleted it really okay nobody saw that here is it um i see logo let's let's try that again yeah i think i yeah when i had the the previous splash screen approach you're right um i think we chose 150 here we can change this anyways i see logo i have a content description of logo um [Music] then do we want to animate this a little bit like little scale up overshoot or so where did you draw this logo this complex svg sometimes studio doesn't support these complex path lines i didn't draw this i'm not that talented that made a graphic designer from fiverr so if we just go back to your navigation staff here and use our splash screen here and pass the nav controller and take the navigation composable put in our surface we should be able to see something here i think off-topic questions should be answered later on small breaks it's slowing the flow a bit um yeah um how many of you also see it like that is it annoying if i keep answering questions that are not related to the the coding here i mean we can also do to like every 30 minutes or so we just make a five minute break we answer questions how's that and my recording again stop man i don't know what that is i have to look into that last stream that also happened no yes no yes man that's not so helpful let's try the the the break approach and then see how you like it some people agree some people disagree yeah let's let's make let's work a little bit on this project i will answer questions that are related here to this project and then we'll have some breaks where you will answer other questions or if you have a question that is only answerable right now then yeah i'll also just do it okay you can see my splash screen displays looks cool is a little bit too big in my opinion we can change this here let's let's animate this a bit bell scale is equal to remember and want to use an animated build um in which we can define an initial value for our scale zero f so we want to scale it up and then we have a launch defect block in which we can trigger this animation we pass through for the key so in case you don't know this launch effect block it's a so-called effect handler that is used to handle effects um so we basically have a curing scope here we can delay this crew routine and we also have this key that we can pass here this key is used to basically fire off this block again this curtain whenever the key changes so we can pass some kind of state here for example a boolean value and whenever the boolean changes the the current in here will be cancelled and relaunched that is the purpose of launch defect we don't pass a state here instead we just pass through because this true will never change um that means the the block here will never be fired off again so all we achieve here is this launch defect block will just fire off once when flash screen is composed for the first time and then it will just display our animation yeah let's do that so we can use our scale we could say animate two so we can animate it to another value the target value which is well this would be scale one that is too big i want to make it like half of that let's say target value is 0.5 f so 50 and we can define an animation spec to give it a duration we can use a turin and set duration millis to 5 or 400 500. um and what's interesting because right now if we if we launch this we should be able to see something no not really because yeah we don't apply this to our image obviously let's do that modify is modified at scale and pass or scale that value now you should see an animation yeah more or less so that's a shitty interpolator which you want to change to like an overshoot interpolator which i think would look cool here we can do that here because compose doesn't have that by default the overshoot interpolator we can define how is it called easing a custom easing function so we basically get a float value here which is the fraction of the animation that is already played so if we are at like 200 milliseconds then this fraction would be 40 so 0.4 and we can now take this fraction and return the actual target value the um the scale the scale state here should have at a very specific time so we already have an overshoot interpolator here we can also define that up here um which is implemented in android in the android framework but not in compose as an easing function we can easily write that on our own make this remember overshoot interpolator and just define some kind of tension let's say 2f and here we say overshoot interpolator.getinterpolation which takes our fraction and returns the target value and if we if we increase this like to two seconds then you should be able to see this animation quite nicely you can see there is the little overshoot animation obviously that is way too slow that's better and what is the overshoot yeah it means that it will not just animate to our target value instead it will animate a little bit um more than that so maybe to 0.6 or 0.7 and then go back to our target value so maybe let's make it to 5 seconds then you can see that how overshoot looks like so it first gets bigger then it gets really big and then it gets a little bit smaller again that's just what's an overshoot animation is called i will choose 500 here and maybe is it i think it's a the size is fine what happens if the app is launched in landscape mode yeah that shouldn't be an issue how can i do that here with the emulator not sure here no this one probably and is there rotation oh i have to click then you can see it it just works perfectly fine all right that's it for the splash not yet we have to also delay it so [Music] um what do we do here after we animate the scale value we want to delay the creatine and for that i like to create a constant make a util package for that just for how long we want to delay this stuff a clone spell splash screen duration let's set it to three seconds and the later crew team and after the delay we use our nav controller and navigate to our next screen um our login screen so if you now implement the login screen just a very basic version of that and we should be able to see this how this works also pass the nav controller here and let's for now just have a box in here um modify fill max size and content alignment center and form it this bit um and then in here we can just display a little text for now this is the login screen and give it a color of white if we now go back to navigation and put in the the login screen composable here for the login screen route um then we should be able to see that so now after three seconds we should navigate to the login screen there we go one two three and there we go there's a login screen so the the splash screen is working fine i've learned composure should i be here or not you can surely be here you probably won't understand everything but you will learn something um question is do we want to start writing ui test cases for compose or do we want to implement the other screens first will it clear the stack no it does not clear the stack yet i think of course we want to do that um i think we can do that here in this block can we say pop up to so how does this work pop up to id you pop up we can choose a route here and the route is screen that splash screen.road so let's hope this works um because what i'm doing right now and what um who said it and and some kind of number um what i meant is that we don't clear the backstag net yet with this approach so if we click back our splash screen will just fire off again obviously that's not what we want we want the app to quit so after we navigate we try to pop everything up to the splash screen and maybe this works now yeah it looks like people really want to see ui testing and compose i'm also very new to that i have to say i haven't really worked a lot with ui testing and compose and we don't use espresso for that it's it's another kind of ui testing but i think what i've tried for now um in regards to ui testing and compose is that it seems to be a little bit better than espresso because we don't have all these um activity and fragment scenarios like in espresso and i think what we can also easier test now i haven't tried that out yet but i will definitely in this app is that we can better write end-to-end tests that if we like navigate through our whole app and make sure some ui elements are on the screen or so because we don't have these different fragment scenarios anymore that was always a pain with xml so i now change this line here to pop everything in our backstack now we should be navigated or we should close this app if we click back and no it's not the case maybe we need to pass our login screen i don't know if this is inclusive or exclusive go back no it doesn't work why pop up to builder we have here what is that inclusive is true let's try that and then set this to splash screen again what does it do up to a given destination before navigating you can first pop backs like the navigate yeah i wonder how this how this function here works um and now it crashes doesn't seems seem like it works like that um nav graph cannot be cast to oh come on yeah let's let's try that that we pop it before so we say nav controller pop backstack and yeah now it works perfect um so yeah you really want to see your eye test well all week all we can test right now is if the splash screen works so i will also need to figure this out here but let's do that so how many of you actually know testing here that would be cool to know so on the one hand unit testing and integration and ui testing because it's good to know how much i explain here okay it looks like most people don't um not really proficient at testing but i know the basics i don't i don't yeah cool because i also i didn't talk too much about that on youtube i have a playlist about testing but yeah it covers the basics and also nothing about compose okay looks like i will explain quite a bit here and i will also have to learn quite a bit here um so maybe a little bit introduction to testing we have three different so-called source sets here in android um i'm sure also if you haven't done testing you have noticed these we have com we have com android test and we have com test and probably you only have used this com source set that is your main source set in which you put your source code of your app the two other search sets android test and test are used for your test cases obviously the test source set is used for unit tests unit tests just test single classes and single functions of your of your app so that these kind of tests should make up the majority of your test cases you have a lot of these these run really fast these run on the jvm so you don't need to run your emulator to run these test cases and they test business logic in the end so stuff in viewmodel stuff in use cases that's basically it and that's also a reason why we design the architecture like we designed because it it allows us to really easily test it um yeah so unit tests should make up about 70 of your test cases then the next step would be integration tests this should make up about 20 of your test cases and integration tests they they don't just test how a single class or function behaves they test how two classes work together so um but let's take the example of xml you for example want to test how does your fragment work together with your viewmodel that is what an integration test would do um then finally the last missing ten percent are so-called end-to-end tests those are the closest to reality you can say so you really want to see um you want to simulate how your user would use your app and these are also the the most which is the most painful to write the longest tests but they they cover a lot of stuff in your app so that could for example be hey the user logs in the user adds a node the node is saved the then the user clicks on edit edits the node and saves it again and just verifying if everything in that in that activity in that action works as expected that are end-to-end tests and now these two sources we have here android test and test are used for different test cases the test directory contains tests that run on the jvm so we don't need to run these on the emulator which makes these very fast those are used for unit tests um on the other hand we have android test android test contains all the other test cases that are integration tests and ui tests so in this android test directory we can actually access android components for example the contacts we can't access context in the test directory and yeah also stuff like fragments activities everything related to android that's not included in plain java kotlin and these run on the android emulator or on your physical device and that makes them a little bit slower because your app needs to run to to make these tests run if we want to do ui testing here and see if our splash screen works we need to put this in android test so yeah i don't know if i have the dependencies for that um yeah so here i commented this with instrumented unit tests an instrument test is just a test that runs on the emulator in the end and we have local unit tests which are the tests that run on the on the jvm we have different kinds of dependencies here test implementation this dependency only applies to the test source set and these android test dependencies only to the android test source it so these won't be included in your production build obviously because you don't want these test dependencies there um yeah i don't go through the detail dependencies here now i will do this as we go on in this project um because yeah that would overwhelm you overwhelm you here if we don't even use these now but i'm wondering if we have composed testing here i think that is it so junit that's important to know that is the basic testing framework in android and for java it's basically the test runner it makes sure that your tests run it makes sure or it rather shows you hey these tests failed that was the reason not always what's the reason but it's it maybe if it crashes it tells you that it is the foundation of your test cases you can say and we can assign a version here by the way i think we already have that down here we can remove this good so let's take a look here i think what we can do is you can press alt plus enter and say create test oops and the testing library won't be junit 3 it will be junit4 we can use the unit 5 and android for local tests local unit tests i'll just use junit 4 for everything here i'll call this splash screen test and now it asks us where we want to put this test we're going to put it in android test because it is a ui test so every test that we write must be put into this into such a test class so in this test class we just have a bunch of test functions that have some values given and then the functions do something with our code and then after that these functions check if specific conditions are basically fulfilled or not so in case of our splash screen what you want to do is oh man i don't really know my streamless always um cancels my recording that is super annoying maybe i have to record it with a different software next time but then i don't have all the other streaming stuff here in the in the recording let me quickly check that why it does it it's really annoying because i want to upload that i'm using streamlabs obs it is not fully recorded that was also an issue last time the recording just stops without telling me anything about that and then some parts of the stream are missing but i mean this time i also enable that and that you can see it on twitch afterwards so twitch will definitely should definitely have it and in the worst case i just um watch it on twitch and record my stream my screen there if i can't download it directly this stream shouldn't be lost um yeah i plan to upload for channel memos that's true but the first streams will be free for anyone just so that everyone can see how these streams are and if you then like it then yeah you can you can subscribe but let me i will check that later this will be on let me quickly just just verify that i enabled the option on twitch that streams are recorded um i think it's called vod or so right yeah no at least it tells me it's broadcasting and it displays in my video list here on twitch last time it didn't i think um yeah let's see after the stream uh so back to android yeah maybe there's a limit to how much you can record through streamlabs not really because last time it recorded like for two hours and then broke now i i'm already pressing record for the third time in like in just one and a half hours when will be the q a break i'm just doing that right now so let's let's have five minute q a before we write the test case here you can you can ask anything anything you like what are the specs of your pc um i already set 32 gigabytes of ram i have an intel i7 7700k and graphic card is actually like a geforce super um 2550 or so have you tried linux yes i have tried linux i also have kali linux installed next to windows but i never really use it i can't really use linux in my daily workflow because i depend on all the adobe software don't really depend on it i know some linux people will come now hey there's an alternative no there's not i love adobe software will stream in the afternoon german time usually yes so that the time will always be around 4 5 pm here in germany right now it's half past 6. did you graduate yes i did how's the new table it's great it's a standing table i'm an electrical standing table and i'm daily working on it standing for three hours and the rest i'm sitting it's really cool it's also nice to record videos when standing it's more like a presentation mode will the stream be available on twitch after the session end yes i hope so but i i checked the box what a song i learned i already talked about that it's a linting tool it tells you additional warnings that android studio doesn't give you helps you to make your code cleaner um bro should we write tests for every stuff in our project you should write test cases for as much stuff as possible it's rare that you can get 100 test coverage but you should get you should write as many tests as possible i mean not as many as possible you should write as many as possible but also as many as necessary i mean you shouldn't go ahead and write like 100 test cases for a single function just as many as you really need to cover that function to test all the edge cases and stuff like that how's marika going it's it's great yeah i was visiting a friend and we played a lot of mario kart when is the next stream you said you're not available next sunday yes i am not there yet next sunday i'm thinking about doing a stream on thursday so yeah let's let's make it official i'm streaming next thursday same time also 5 p.m german time um are you going to use composing this project yes i will have you any backlogs no i don't i'll i'll just take the mock-ups and implement them here and do the rest link to table i don't think that will help most of you here because it's a it's a german shop i don't think they ship worldwide i'm thinking of building a new pc soon can you help me what specs should i use i'm on a budget yeah we usually we are usually on a budget i'm not that up to date in regards to pc specs and hardware i mean if you want to do android development then you should have a decent one but you don't need a high-end machine wait let me let me try something out oh i just i'm just realizing something guys um it looks like my my shortcut to to mute my microphone is the same as stopping the recording and that is why the recording always stops let's change that better yeah press f please um okay now now it doesn't stop anymore professional today let's see which other questions let's let's forget about that then at least i know that for the next stream it will record till the end and this stream we have the recording on twitch so everything is saved and in the worst case i don't know if i can download my streams that are saved on twitch that would be the best if not then i will just leave it open and record the stream i'll record the screen in which the stream is running which is probably a bit bad quality-wise but at least for the next stream it will be fine as long as i remember recording it um yeah let's see where have i been which question how can i save crashlocks on a physical device i'm not sure how far that's possible i had a similar issue recently with a client um don't know i mean you can save logs that your app makes but i'm not sure if you can save crash logs in a file you can definitely use something as someone [Music] said here you can definitely use firebase crash analytics that's actually actually what it's used for can you spot a little bit about your next course yes i can which i will actually start recording soon which is about canvas in jetpack compose so it will be a course that covers everything about canvas so you will really learn how to make custom ui with functionality with animations and there won't be any open questions regarding canvas can you upload your planet twitch yes i have tried that with a schedule but for some reason i can only um enter days that i stream regularly so every sunday every saturday or so and i don't have such a day yet where i say okay i can definitely stream every every sunday because that's not the case so probably i will choose a day between like monday and thursday because i'm usually at home at these times um are you backbencher i don't know what you mean how how high were you how were you at studies in high school not how high i was uh um how were you at studies in high school yeah here in germany we don't have such thing as high school but i know what you mean i was decent i wasn't like the best but i also wasn't the worst like slightly above average i would say what is a classmate reaction about your youtube work um yeah which classmates i'm i mean sure i'm not studying anymore but in my university i actually didn't have that many people i regularly did stuff with so i rather had i always just have friends that are not in my same studies that are doing something else um just in my experience people in uh in computer science degrees usually just um a lot of these are just these typical nerds and i i always felt like i couldn't really do much with with these people because i'm thinking differently i'm acting differently um so yeah my friends obviously they they like what i do otherwise they probably wouldn't be my friends um at least it started is it the same reason why we can see previous beauty um yeah for the previous stream on twitch i didn't know that i have to explicitly say i want to put that on twitch so that's why it's not on twitch but there i have the recording except for 30 minutes so yeah that will be soon on youtube for for free so let's let's make three more questions and then go on here man i watch i love watching these they show me even professionals like you make stupid mistakes like this yeah i'm sure we all do um you can download your streams that's cool this cater course was really awesome yeah thanks glad you liked it do you do web dev now or have you left it i did that for like a week or so no it's i like web dev itself but i didn't really like teaching it on youtube like it's so tedious with all that html and css stuff all the time and then there are thousands of different frameworks and yeah no android and kotlin's cooler do you play any games no not really did you have any startup plans and if yes then what no don't have any plans but i could imagine doing something in future i don't know if it started but i want to have my own company definitely in future do you know python yes i do push the code i will do that after we write the tests you like do not keep up yes best thing in the world no pizza is the best thing but that comes afterwards okay guys um short toilet break and then i'll be back in two minutes okay welcome back let's write some test cases okay so how we are going to do this what actually do we want to test we want to test i mean there is not that much to test we just want to test that our image shows up our splash screen image and that after the delay here we navigate to our next screen that is what we want to test so in j unit if we want to have a function that is a test case we annotate it with test and then let's say how do we call this um splash screen displays and disappears i would say okay now i'm totally new to compose testing um let's open the good old android documentation so we have our composed test rule so we can define these rules here with junit which just give us specific behavior in our test cases so let's do that um val compose test rule and that is it what was it crate it is android compose rule yeah i've used that before like this and here we need to define our activity which is just main mainactivity and with this rule we can now yeah so you can see we can use the rule to set our content for this specific test case and then we can just do some actions we can perform we can simulate clicks we can then make sure that specific text is displayed or whatever that is ui testing so we want to make sure that we use the compost test rule and set the content it's the same function as here in our activity just that this only applies for the test case here we want to use our theme this one and then set it the content to our splash screen and the nav controller yeah good question where do we get that from but that we need something that's called a mock yeah we are already diving quite deep into testing so a mark and testing is basically an yeah how do i say it's an object that doesn't have the real behavior so usually we have the nav controller that's used to navigate between our different screens but in our test case we don't have access to the nav controller we use here so we just define a so-called marked nav controller that just has a bunch of functions that don't do anything or we can also define what this function should return for this specific test case and the good thing about that is we can track or the mark itself tracks how often which function of it is called so we can then later check that um if we wait for this delay we can then check if the the pop backstack function and navigate function of the mark is actually called or not so that is how we test if the navigation works um so for that i will use the the library mock k there's also marquito which is popular but mark k is the this is a kotlin implementation of a mocking library i prefer that um and we can define these marks here on top nav controller and well let's let's make a delay in that variable and have controller and we can annotate this with relaxed market so a relaxed mark is as far as i know just a mark with empty functions so these don't oh these functions don't have implementations um we use these annotations to mark this as a mark and then we have in testing what we need all the time a function called setup and we annotate the setup function with before so the setup function is called by junit before every single test case so it's used to initialize objects to initialize marks for example and that just makes it very easy so we don't need to do that in every single test case over and over again instead the setup function does it for us so i think what do we need to do here mark k annotations i think dot init and we pass our test class and then this should actually initialize this as a mock and then we can pass that nav controller here why is there no run with annotation for the class oh we can do that that's true no the reason is just because i created the test class and didn't think of that i think it's android junit unit 4 is it class runner or runner let's try this android junit for class runner oh it's just class i think yes uh android j unit yeah let's let's take this i think it's just class yeah um so we now have our mark here and what do we want to do now now it's also tricky because we want to test a crew team and there is a delay here in our splash screen here and we obviously don't want this delay in our test case so what we do is we say that is equal to run blocking test that's a test function um [Music] let's put this up here and with this run blocking test we can manually forward a croutine and that is quite helpful i haven't done this in quite a while let's see how this works so first of all we um what is experimental current api that is just yeah this this run blocking test is just annotated with this experimental coordinates api means maybe this changes in future um i think it's unlikely that's that function already exists quite a while but it gives you a warning if you don't have that annotation so now we want to make sure that first of all the splash screen is displaying the image how do we do this we use our compose test rule um or do we yeah i think so and here we have these functions on node so a node is basically just a ui element on our screen and we can we now need to somehow find the image that we want to check we want to search something for and we have different ways to do that we have a node with content description so we can find a specific composable with a content description and we actually have that for a splash screen here logo so we can say a node with content description the label i think that is the content description let's also do it like this so you can see that the label is logo and then we can assert exists um i would say so i think with that we just check if the if there is a composable that has the content description logo which is our image here so we first check if it is actually on our screen then what we want to do is we want to how do we do this we can now use this which refers to our test creatine scope um we can use advanced time by so we can advance the time of the curtain to skip the delay i think that is it this this could totally fail here what i'm doing but we want to advance it by our constant dot splash screen duration and then we can use verify which comes from mark k and there is no need for advanced time by why i think oh yeah i think you're right i think run blocking test already skips all delays by default yes you're right thank you so we can we can remove this and now we can use verify which comes from market and with that we can we can verify that a function of a marked object was called and we can do a lot more with that but in our simple case here we just want to make sure that the pop backstack and navigate function was called so we use a nav controller and say that pop back stack and navigate and it even checks if it was called with specific parameters so we can say screen dot login screen that route so we make sure that the navigate function was actually called with the router for our login screen and let's see if this fails and it's actually cool that we have a lot more average viewers as in the last stream probably because we we do coding here i think i need 75 average viewers in multiple streams so i can become twitch partner that that's my goal man so let's see you can now see that the test case will launch in our emulator and it failed so i would not set up hidden api man what is that um add splash screen test what is that could not set up hidden api exemptions um is this actually the the correct test runner i'm not sure it's oops let's google that um android testing example let's see yeah it's just android j unit 4. maybe that's not even it but that's definitely one issue okay unit 4 let's try that again nope no still same error um mark okay agent exception let's let's google yeah we're not the first one and nav controller is not connected to nav graph yeah question is does it really need to need to be connected because it's a mark um they say they run successfully in api 29 but fail on 30 i'm also using 30. let's try if it runs on on 29 will probably drop a few frames oh yes and launching an emulator is always the most difficult thing for android studio in terms of lag let's see okay we wow no locket output for this device thanks for nothing android studio let's run again yeah it showed something and now it gives us output verification failed pop backstack was not called that's already a very tricky test case actually um so i'm not sure if it actually waits for these two functions to be called that is tricky so let's just make sure that the test itself works if we remove the verify block why do we even need to test the splash screen because yeah if we change something later we want to quickly verify that everything works as expected that's why we write test cases at all and i also want to learn composed testing let's run this again like this so this should now succeed yes it does so the test itself is working but the the mocking stuff doesn't why i have the feeling that this launch effect block launches a different curtain in a different scope and it doesn't use the the scope and the the scope that this one uses might not um might not cancel the delay not sure how we can can we actually assign a protein scope here no how do we test this launched effect that's the question let's let's comment this delay out and see if this actually works yeah you can see now that works that's the issue so now it actually verifies that these two functions are called but the issue is that it doesn't skip this delay maybe we can try this i'm not i don't think it it helps us but we can try advanced time by advance and buy but whoever said that was right i also have that in my mind that run blocking test actually skips delays i think it also says that here isn't that something like isling resource that espresso has i don't think so i mean i don't know um no this doesn't work oh man what we can try is let me quickly see there is a special creatine test rule that we sometimes need and it basically makes sure that we use the main dispatcher for everything i think um wait a second can i do this i'll just quickly copy this over from another project and then show you that so let's go in here and i will paste the youtube package here that's basically just a specific rule here that we usually only apply to unit tests i think i mean local unit tests and it here you can see it sets the main dispatcher to our test dispatcher so there's a special kiriti in this patch here and this is usually helpful for local unit tests because the main dispatcher relies on the main looper which basically just keeps the thread alive and in local unit tests we don't launch our app on the emulator and we only have that main looper on the emulator and not on the jvm itself so what this rule does for a local unit test is it just makes sure that we use a different dispatcher as the main one so it doesn't rely on that main looper um i'm really not sure if this does anything here so curoutine rule is equal to creatine scope i know main crew team let's go rule and annotate this and then we can say curtin rule that run blocking test i don't know have you tried the new splash screen api now not yet and i think it's only for android 12 is it no i don't think that works no no it doesn't finish at all nah not a good idea that is really tricky already for the first test case all i actually want to do is i want to replace the the curtain scope here with our test routine scope maybe i doubt that there are people who actually also had this issue but um we don't want to use delay in test cases test cases should be quick um but let's google for jetpack compose test launched effect recruitment scope maybe doesn't look like people had these issues before oh man what do we do i mean if we could pass a scope here that wouldn't be an issue but we can't is there maybe a test version of that launch defect no not really so the thing is if we would use delay here i think it should work so if we delay the test case which we obviously don't want maybe it even skips that i think so but espresso can be used in compose if you like um i think the composed testing stuff is actually cool now this also doesn't work but there's also nothing we want that is tricky what do we do launch the effect swap out scope oh look a little video suggestion here [Music] um yeah that's the issue with compose you you barely find anything helpful for such issues so i think what we all we can do for now is we can't really make sure that we navigate afterwards um i'm thinking about if we can maybe get rid of this launch defect stuff here i mean there is a curtin scope in compose we can get but we shouldn't use this in composable itself we should only use that in callback functions which this here is not something we could try i'm not sure if that's a good idea is using a normal side effect and then using a curtain scope in there i don't think that's a good idea and there are adding resources to handling let me check that it's a very long while since i worked with these resources compost can synchronize tests and the ui so how does this work register idling resource i mean let's just try that um let's do this up here i guess register idling resource and what did they pass for that well how do we get this um idling resource man this is how is this helpful i i want to know how i can create this of the idling resource i mean they they just use an idling resource variable here but they don't tell me how i can create this then let's try this manual synchronization um compose test remain click auto advanced main clock auto advance is true let's oops let's do that here what did they do then wait for idle let's just do oops and paste it here and i think we should put this in between here if i get this right no it's also weird that it doesn't give me any locks sometimes now it runs forever that is that is weird wait for idle because maybe i should remove this and let me quickly ban this guy why doesn't it give me even a little bit of output this is this is very weird so let's see what this actually does this is a blocking call returns only after compose is idle what if we but it says auto advance so i guess it makes that automatically but i'm not sure how far we we need this idling resource for crew teams because usually for crew teens we use this this uh run blocking test scope this already skips delays by default i'm rather thinking about if we can rewrite this a little bit so i don't think that's a good idea what i'm planning but i i will try it out we will have a curtin scope here and set this to remember curtin's go by default i'm not sure if we can launch these in side effect blocks i know that we shouldn't launch this here we should only launch these in call backs but i'm not sure if we can we're supposed to do that in here so what i'm thinking is we say curtinscope.launch and then we put this stuff in there like this let's quickly check if the app works as usual i mean if the splash screen still works it looks like that um and now we can um [Music] here for the splash screen we pass our controller but we can now also pass a curtain scope which we can just pass our uh run blocking scope for let's see if this works no why not at least it gives us an error this time verification failed um we also need to define a dispatcher like let's try that but that also shouldn't be it um dispatcher is equal to dispatchers dot main and then we say curtin scope here and we pass the dispatcher here then we can pass or test this patcher for that but don't think that's it to be honest um do we have a dispatcher here no let's define that test dispatcher test curtin dispatcher make that private try running with one blocking and advanced buy that's true i can also try that after this here i want to do test dispatcher.run blocking test now and here i want to pass the dispatcher here for this one yes here but that is exactly what i want to show you here that behind the scenes nothing is perfect and i'm also struggling a lot with simple things you can see it doesn't work again yeah let's try that as a last thing what lolin suggested here i also don't feel like that's a good solution even if it would have worked so let's let's just undo all of that and in the worst case we just can't test the navigation behavior at the moment well yeah that is something that compose definitely lacks at the moment that just that you can just find something about it online okay that's definitely a good solution right now but let's see if we can test this by just using run blocking oops and do we actually have advanced time here no we don't even have that here let's still try that no okay let's not care about that and say we don't want this maybe i take a look at that off screen of stream i mean but yeah if we leave it like that then the test is actually running i think what is the warning the unit test should you return unit oh okay yeah it's not even running what is it i mean we have tested that why isn't it running anymore yeah no it's running weird well okay so the test case is working that we check if the if the image is actually displaying um yeah thinking about if we can somehow test the animation but yeah let's actually continue just implementing the app for now and as we go we implement further tests because we hanging on the splash screen for quite a while already let's take a look next up is this login screen so how do we do this i think we just have a box here that we center on our screen in the box we have a column i think we don't even need the box we just need the column and center it um yeah we the question is what kind of text fields do we use we can either use the material design text fields which look a little bit different than this here or well that's something you can decide now should we make the should we make the textures look exactly like on the markups or should we make material design text spheres which is a bit simpler and they also give us hints the the hints would also be something we would manually need to implement what do you think would look better same hints would be better we would have hints anyways but if we use a basic text field then it doesn't contain hints so we would manually need to create that functionality okay looks like people want material design let's do that so we have our login screen another question is how do we manage our different composables i don't want to create a separate file for every composable but for quite complex screens i also don't want to put them all in a single file but i think for the login screen that's fine because we only have a few text fields and a button and little text here but i think for stuff like the profile here so we would definitely split this up a bit so we have our box here which we don't want let's swap this out with a column remove the content alignment and let's see we want to center it we want to set the vertical arrangement to center we want to fill the mag size do we want to fill the mag size yes um we want to apply some padding so i will just define some default padding here for the sides which we can then use in our app like here as well not sure if we should use it here let's let's define of fixed values for that like constants um in our ui let's create another file for that called dimensions well small let's say set this to 80p heading medium maybe 16 dp and valve heading large is maybe 2040p so the reason i'm doing this is just that whenever we light i want to change our padding values we just need to do it here on the central place and not all of our app and i'm not sure if we can actually pass these dimension values to our theme like here no it doesn't look like that next time we we have also dimension resources that's where i was thinking that but yeah let's let's set the padding horizontal to heading medium i would say so now when we change padding medium we just change it wherever we use it in our app and okay now we have the column first of all we have a text here that says login let's define string resource for that just log in that says login and then we can say that is equal to string resource er that's string um not r did i import the wrong r i think this one maybe no weird are years some of these are uh that says twitch oh come on here this one social network twitch import that and say string dot login now i have it and put these on separate lines we don't want the color to be white we want to choose our material theme that colors that on background that's our text color if you remember here no here on background is our text white and yeah let's set the font size to something like oh do we actually we didn't even import a font do we want to use a custom font or just the default one i think it's roboto i think we used roboto that's fine so yeah let's use roboto what did we actually use here i don't remember quicksand oh does roboto look like and it also looks cool let's let's make a little survey if you like roboto then one in chat and if you like quicksand which is this register text two in chat now looks like quicksand looks better all right then we use quicksand thank you um i don't think i have that font on my pc at least not in all variants let's quickly google for that and yes google fonts just get the whole family say file check that out here downloads oh it's downloading somewhere else all downloads i hate it okay i have it um perfect simply take these and create a font folder no resource directory another resource file directory this one and say we want to have a font and paste this and these are not these don't have the right naming conventions i willed quicksand light android resources oops that's regular android resources always need to be lower letter okay now we have these font files so what we can do is go to type and that defines our basic typography here we can define a font family quicksand is equal to font family and here we can define our fonts actually so one font is out of font um dot oh come on are that font dot quick send light you need to say hey this is font weight that light and we do this for each of our weights regular quick send medium [Music] quick send simi semibolt and bolt i think it's normal yes medium semi bolt bolt then for our typography for the font family we don't use the default instead we use quicksand and here we can now define different text styles so let's think about it we definitely want to have headline style so i think it's h1 yes so now it can just define styles that will apply to all of our headlines font family will be quicksand as well font weight will be bold font size is oh yeah what do we do let's say 30 styling is so much better with compose i agree it was a pain to use all these xml files let's have an h2 we don't need to define all headline variants i think h1 and h2 is fine font weight is let's see me bold on medium that's just medium and 24 sp what else do we have um subtitle one let's actually take a look at our markups so we definitely need a normal font which i would say is our body one but this is a different here different uh textile than this one here let's say this is body to the smaller body um i would say that is actually sufficient so if we just define it body one and body two we can always extend this later textile font family quicksand font weight that is want wait hmm do we use normal or even light for the for the smallest type let's no let's choose normal and the size let's use 12 sp so it's a little bit smaller than the body one font okay so now these this typography variable object will be passing our theme here to our material theme and we can use that in our login screen so let's say material theme dot typography and this one is h1 and it still gives us an error why though what we can also do is we can remove the color and define the colors in the typography let's do that we can say what is this color here i don't even have this color i think in my colors um or do i no well text gray i would say and pass that here and then we can say that we pass this color here to our body one um color is text gray and this will then apply to all of our texts in compose let's say here as well each one will be text wide we obviously can override this later for individual texts but i'm still wondering why we get an error here it says it can't match the function but maybe we pass a string and oh font size yeah it is actually what is that it's a text style right yeah yeah that's how it works um okay we want to align this at the start which is i think the default so let's add a spacer um let's change this actually not padding small instead we say maybe space small space medium and space large um how long will the stream go i think maybe one and a half hours from now then we also have four hours like last time i think it's a good time and then i will stream next thursday again and here we change this to [Music] space medium and here we can pass space small and now we wanted to use a material design field so that's i think just a text field yes so we have a value for that and we actually don't want to put all of that in our login screen let's let's create a composable for that which is the question is i don't think we want to put this in the login screen file because we need these text fields over and over in our whole app we need these in login registration profile editing here for searching so it's it's actually composable that we need in our whole app question is do we put this now in a specific package or do we put it in util or total new package i kind of don't want to put it in in the login package or so make a components package yeah that's that's a cool idea let's do that components remove this file for um how do we call this like standard text field i would say okay we want to be able to pass some default text we want to be able to specify a hint we have a function when the value changes let's see we will see what else we need text field the value will be text and on value changes on value change then do we have a hint here no how is it called placeholder yes and here we can just define a text i think which is hint and the style of that will be huh do we have a style for for hints i'll just say body one typography by one um what else i would say we want to fill the hole with okay i think we just need to see how this looks in the app in the end i'll leave it like that for now we swap this out with a standard text field and then here we have well we should put this value now in a viewmodel right so let's create that login view model so as far as i understood i'm not entirely sure here is that with clean architecture we put the viewmodels in the presentation layer because these are directly coupled to the to the composables in the end and basically just provide data to observe and then the use cases which contain the actual business logic they are put in the domain package but if someone here is really good in clean architecture then please correct me if i'm wrong but that's at least how i understood it we actually need to set up dagger hilt now if we use view models so i'll create a di package and our good old app module if you have any questions regarding dependency injection then just ask these but if not then i won't explain any any specific things here about dependency injection because i think i use these i use it quite often in project and youtube can we use dagger 2 um i don't see any reason in it in using it dagger hill is much easier and i've never ever experienced that like i need a feature that is only available with dagger 2 and not withhild so we install this in the singleton component and then we have our functions do we actually have functions here no not yet we need an application class social network application build android app and in here when we're already here we can set up timber timber dot plant debug tree then register that application what is timber timber is a logging library it's just a little bit more convenient than the default logger they don't need to define tags and you can easily toggle if you want to have logs or not easily disable all of your logs for production from now on we can just do timber.d and have a lock here and it will automatically create attack for us that fits to the current scope then in our view model we have a hiltview model inject constructor what is planned in timber that just initializes timber basically so yeah it's basically it basically just means we planned a debug tree to make sure that we now that we're now ready to debug to use debug logging so in the view model we now want to have two states for for each text field um on the one hand that is uh the email or username username and email so we say let's just call it username username text is equal to mutable state of empty string and an immutable version of that and we have password text oops how to stop in production um i think you mean timber that's not difficult you can just go to your application class and say if i think build config.debug yes only for debugging we want to plant the tree and else you just won't unlock it all um so then we need two functions to actually set that text so function set username text oops now we just say usernametext.value is equal to username and the same for the password like this and then let's clear that up a little bit what is the best practice for view models in japan compose do you initialize rv models in the main activity and provide them as parents in the screen computables yeah you will see how i do that with dagger health we actually have a cool solution for that so we want to now go back to the login screen and here you will see how i do that we can basically scope our video models to the navigation graph so view model of type login view model and that's equal to i think it's field view model yes that gives us our review model and that is as far as i know the recommended way to do it at the moment also another reason why i use hilt it's just much easier to provide these view models here in composables so now we can say here in our standard text field the value is view model dot username text that value and on value change why is it red is it text yes and in on value change we save your model that set the username text to it yeah then what we also need in the standard text field is we need to some somehow pass what kind of text field we have so for the test the password text field we obviously want to have uh we want to hide the password and we want to have the toggle option good question how do we do that i think the text field already has a value for that with material design that is probably easy let's take a look we have and there are a lot of values we actually want to pass this parameter also something like this error then we want um is it keyboard options keyboard actions something of that we can define how we actually want the things to look like keyboard options i think that is what i'm looking for can we say keyboard type keyboard type yeah here password so let's pass keyboard type as well is equal to keyboard type the text by default let's say and here we set this to keyboard type what else do we have here yeah nothing important um so we simply copy this paste it now we have our password field set single line to true that's true we have a password text value set password text to it what is ime action done and here we can oh we actually also want to pass a hint string resource r that string dot password hint a little trickier i usually don't go to strings xml and define these you can just type a name here press alt plus enter and create string resource for that until you can enter a value it's much quicker enter your password for example um and then we also want to hit here let's say username slash email let's change the password hint just password then we have our keyboard type we set it to password one question i have now is how do we display this this eye here to toggle the visibility i'm sure there is an option in compose um doesn't look like there is a parameter trailing icon oh there is one yes you're right but then [Music] it looks like do we already have that as implemented behavior or do we have to implement the behavior on our own because an xml we could just toggle a boolean for that it looks like we need to toggle this on our own fine so here we have an icon um i mean then we need to implement some functionality here let's see if there's an icon for i toggle password let's better google if there's a way to do that um they use a leading icon but yeah they they have a custom icon for that icon's field visibility that is what i'm looking for fill dot there's a okay there is no icon uh maybe there isn't default icon no with what is tacity that is exactly what i want here oh okay we need more icons let's take this and go to our build.gradle that should add our icon that we want so then what we need is definitely a state val var is password toggle displayed and it's initially false like this question is we only want to display it if the keyboard type is password so we can actually do keyboard type equal to keyboard type password do we actually need the state for that yeah because that could change and then we also have a state is is password visible and that also starts now that always starts with false and then we use the the state we have here we actually only want to show the icon if our password toggle is displayed let's make this an icon button let's see what do we need for that i can button on click listener obviously and here for the image vector if is password visible um we choose that's a weird formatting icons that fill that visibility and now we have it then we say visibility off and else visibility okay cool when we click this button we're going to toggle it on the description is if this password visible let's choose a string resource product string password um visible content description and we don't have r again let's see yeah this one and then we can create this so that is hide password and else we use password hidden content description that is show password okay that can be a val so quite a bit of setup to make that work hopefully but also something we can easily write ui tests for what's up with our bug yeah that is weird there are thousands of hours we can import here but it looks like it doesn't always import the right one by default the art that actually refers to our own resources yeah well let's take a look back here what's missing is just this text so let's we need to show this at the bottom for a screen but right now we have a column with which we can't do that um so what i do is i put this in a box modifier.filmex size and then we can put this column in here we can say we want to align this in the center and down here we have a text the text will be our registration call to action so string resource maybe don't have an account yet sign oh no we don't do it like this because we want to show this sign up in green so what we need is an annotated string so we need build annotate a string and in here we can say append string resource now we can define the first part don't have an account yet we append a space and then we append another string resource that just says sign up and with this annotated string builder we can give these individual parts different text styles that's a cool thing oh come on uh what do we even want to do not this i think we can now define no we can't we need to do differently we need to say with style okay we can define a texture you have to make another trolling icon parameter i have to make another text field for passwords because in normal text field it will leave space at the end why i mean we have this this state here if the keyboard type is not equal to password we don't even show this trailing icon here so then it's just a normal text field so yeah we'll see how it works let's set the style to text style the color is this time green oops material theme accent green or green accent no colors it's primary this one i mean and here we can then append this stuff oh and here we don't have access to string resources so let's have a save that in a variable like this and this still gives us an error because that needs to be a span style so yeah we want to take the text give it a style a default style of material theme typography body1 modifier dot i'm going to align this at the bottom bottom center and i think right now we don't even have any padding at the bottom so let's just make this padding from all sides i don't know let's let's just try it out um oh we yeah i think we use that in our navigation yes i'm also just seeing that the emulator is a little bit overlapped with my camera so maybe you can do it like this as long as we test it and gradle is taking ages there's our splash screen and there is our crash let's take a look so we can't have a live update screen of what we're doing in compose like we did with design type for xml uh this doesn't work super well we have live updates for literals so if we change just a string or so it will have a live update but if we add a new composable so it doesn't let's take a look what the crash is no that's not it we need this emulator um main activity does not oh okay yeah i know what it is we simply need to annotate this with android entry point because we inject our review model here let's see there we go so it doesn't look like expected but it looks okay at least we have our fields here the highlight looks quite cool the space is a little bit too low i think and also here there is no space which is oh i think i applied it to the column not with the box um but the password field let's try that that's now quite exciting hello that doesn't work um we oh because it's is it visible no i mean the toggling of the icon works but the password field is not as we want to have it let's first take the box and apply some padding here space let's say space large and we remove this one so let's actually try this out if we click apply changes i think sometimes it does apply these but very often it gives us an error see now it worked so in terms of spacing that looks a little better i want to increase the space here um and i want to actually move this up so let's have a custom padding start space large and top and bottom is just more maybe 50 dp see now it didn't work even though i didn't change anything else than before so i always just relaunched the app if you didn't don't change much you can see it it just it's really quick and i will also remove the delay for the splash screen just for testing stuff nope this one set it to zero so now the spacing looks fine how long will the stream go yeah probably like 45 more minutes and in the end i will make a little q a round for like 15 minutes so half an hour of coding 15 minutes of q a but i really want to figure out this password field at least in this stream this doesn't work right now let's see i mean we do pass the keyboard type right yes i mean otherwise it also wouldn't show the the icon here it's called visual transformation or visual options i guess oh yeah that that's true i think i think what i'm doing here is just that the keyboard is set up for passwords but not the text field actually so let's here let's take the visual transformation visual transformation uh how does that work annotate a string i don't want a fully custom one i just want a freaking password is there let's ask google password visual transformation no there is none visual transformation maybe this one let's see please use dark theme for chrome uh this is firefox but i can do that for the next stream don't think that there is a plugin by default here in firefox password text field check this here oh capital p i see password yes perfect and this only applies if our password toggle is actually displayed or if the yeah password original transformation else we use adjust visual transformation none so that looks like it yes now it displays a password and we can't juggle it why because we don't make this dependent of the state we need to make this is password visible actually if it's not visible we're going to show the the password transformation so let's see yes now it works that looks cool oh that's not cool um why is that if is password visible sure because here it's not visible um so we actually want to make sure that it's not visible and the toggle is displayed now yeah here we see it here we don't and here we can toggle it cool that looks like it's working but to be able to verify that let's write some test cases to finish off the stream and then get over to the q a so yeah we also need to think about if we leave the background here dark i don't know yet we can think about that in the next time in the next stream let's have hopefully a real ui test case here for our standard text field again android test i don't want the junit assertions and we can say completely fill user name text field you will see back why which back yeah we should yeah if you mean that that we should choose a maximum size for that make some length yeah we should definitely do that android j unit 4. i don't actually know if compose renders these native i don't i don't think so i don't think the android team would implement compose stuff with the android view composable no not again not the test yes now we will test you will get nightmares of that tonight um first of all do we set a maximum length here let's quickly do that before we test it a max length and default it to 20 or so and let's say 40 emails quite longer do we have a property here or max length yes we no we don't uh do we have to keep track of that looks like that so when we change here when you change the value we want to check if the text is the text length is less than our max length and only if it is we call on value change with our text i think that's a door is it let's set it to 5 for testing purposes i was talking about space left at the end when you fill user name let's see what you mean but see if the no no it doesn't break at all if the text length is less than the max length then we call on value change that's correct is it no or i mean now we can type it all because the text length what what is our text length it's empty so zero is definitely less than five why doesn't it trigger if oh if yeah that length you're right so now it doesn't work still doesn't work that's weird um that is weird maybe reset the text every time you load the app not sure what you mean if it dot length less than max length only then we trigger our function i mean if we change this sometimes i just try weird things but that doesn't make sense but now it should trigger because we obviously invert if condition no still doesn't um that that is really weird right now so the actual inversion would be this try to pass it on on valid change i mean i oh oh you're right no i don't need to update the state because the state is maintained in the in our login screen not in this standard text field so now it works and we can type four so we need to make this less or equal and then we relaunch this so thank you to you two guys who suggested that and thanks for the follow mr who knows so now we can exactly tap five characters here as well perfect let's increase that to 40 again yeah perfect and thank you heck byte7 for the follow now let's get to the fun part the testing so we have we have quite a lot of stuff to test here let's first test the maximum text size so again compose test rule function enter too long string max length not exceeded i would say and this is a test of course so now we can say compose test rule set content we want to set it to our material theme thanks for the follow black leg sanji 12 and that is the composable here okay we're going to set it to simply our let's set it to the login screen because we maintain the state there i mean i think in terms of code style it's better if you don't use the login screen because we test the standard text field we don't test the login screen let's let's do that and we should then just maintain the state in here so i think we should be able to do that in the before function so we just say oops compose test rule set content and here we use our standard text field on value change we want to have a state for the text text is text um question is no i think we can't do that in the setup function can we because we still need access to the text to restore stuff uh okay and can we put this in here i think no well we don't need to make the assertions with a text state i think so it should be fine let's just try it so we have the text we have on value change and we should just update our text with it bye bye boy trout foodie have a good night thanks for watching um yeah so if we now take our text field first of all we need to detect it we use our compose test rule on node with text no we can actually say on all nodes or how do we do this do we have a content description no can we set a content description no okay then we need to assign a tag so what we can also do is we can say semantics and set a test tag standard text field and with that tag we can then find it on node with tag standard text field what do we want to do we want to type some text perform text input so the default maximum length is 40. let's enter something let's let's just set the maximum length here to something lower like five and we enter something with six letters then we want to assert no we need to do that separately i think then we're going to use the test rule again on node with tag this i want to assert that text text contains text i want to make sure that it's just one two three four five because the maximum length is set to five we enter six letters but we want to make sure that it actually only enters five does that make sense where and when are you going to upload these streams you can find the first streams here on twitch as well as recordings but the future if you want to access all streams of all times they will be available for channel members on youtube and this failed hmm hmm maybe i mean it should actually do that let's run again and take a look at the screen yeah i mean the text field is there but it doesn't it doesn't enter something why the form text input that's always the case that you you need more time to write your freaking test cases then you need to write the actual function ah but it's also because i'm quite new to compose testing perform text input so i think it just doesn't find this standard text field what if we pass a modifier here then we don't need to pass the default tag is that because there are two text fields no there's only one we're not testing our login screen we're testing the standard text field in isolation so see we only have one text field here but now we can apply modifier and we can define the semantics just for a test case but i don't think this changes anything good night mr who knows see you next time thanks for watching um is this the right function to perform text input but it sounds like so perform text replacement no what does the duck say oh man what if we change this it seems like it doesn't even send the text um on let's try on all nodes no semantics matcher no no idea how that works on onenote with text what if we try that and let's say we have our text by default that says test a note with text test and we perform let's say text input and then it should now say test one right because that's five letters think it's just adding up the text and of course we need this as well here yeah i saw that that the text was actually entered so let's try that again and it failed uh no it still doesn't work because this is the standard text this is not what we entered oh man on node with tech we say standard text field again yeah i don't know i mean what if we put this in here i'm sure that's not it but no hmm yeah what do we do hmm this is this is really weird i'm sure it's a very very minor issue yeah you're right i should end the stream for today or at least head over to the q a round and then i'm sure we can solve this next time on thursday 5 p.m central european summer time so yeah if you have any questions again it can be anything just put them here you're welcome harsha's tsuda thanks for watching oh and we also should of course commit this um implemented login screen and started writing test cases oh and we also implemented the splash screen and login screen and start writing test cases for both thank you obi-wan kenosi and shirak commit and push please update it on youtube for normal subscribers too now i will upload it for channel members as i said you know that this is this is work for me and if i do two streams a week four hours then this is a whole work day that i spend here and with twitch itself i earn nothing so i somehow need to pay my bills obviously it's just it's just five euros a month so i think that's affordable for most here hi arturo can you stream on youtube yeah i need to figure that out i can also stream to twitch and youtube simultaneously but i kind of want to build an audience more on twitch than i mean on youtube i have videos i just want to have another platform where i'm present that i'm not fully dependent on youtube sure my audience is on youtube but i can build i mean i can get them over to twitch as well and on youtube i will upload the streams how can you stay so calm when you when you can't seem to figure stuff out i was you i would have flat out every ground under the sun by know i mean you get used to it that's just coding that's how it is if if if these things wouldn't happen it would be boring when will you upload these videos to youtube i will make them ready in the next few days so yeah maybe i can even upload one tomorrow from the last week need to cut that together then i hopefully can download today's stream from twitch then i will upload that also in a few days and then i think the next stream from thursday on that will be the first stream that is for channel members on youtube so in case you missed the the live stream if emulator is hard on your computer while streaming why not use a physical device um yeah i could do that but um don't like to use a physical device in a live stream where all my personal information is on and stuff oh was it really laggy here in this live stream i think only while building it's not too often what time is it it's almost 9 pm and i'm super hungry yeah i will make some good food in a moment after the stream but during these dreams i actually don't feel hungry at all that that's something i mean if you're in a diet then that's cool because i'm always busy it's actually not so easy to to code to take a look at the chat and to to entertain you have you ever thought that you could teach online for example paid curse of 10 people where you talk to them and the goal would be for example associated android developer course do you mean like a live coaching i've thought about doing coachings but i think that's something for the future i personally want to get just somewhat really um practical experience and freelancing and stuff before i would offer something like that because if i do coaching then it should be top notch and you should be able to ask me anything in that case but there's there are also things in in the android framework i haven't worked with yet good night harsha suda sleep well are you working in any company no i'm not i'm working for myself just because you don't feel hungry doesn't mean we don't either you can always eat i can't just walk away in the live stream and make some food i mean i can but i guess i would lose some of yours what do you think about the google android developer certificate yeah i think the certificate itself is good because it's from google they they they must know what's what's important for android developers but personally i'm not a friend of just collecting thousands of certificates because in the end what counts is can you build solid projects but i'm sure many companies will like it if you have that certificate and also maybe on platforms like upwork maybe that helps if you if you can say hey google actually says i'm a good developer but it's yeah as makestar says it's not necessary but helpful for sure how much did you earn from youtube per month uh from from youtube ads that's that's really not much it's it's a lower three figure three figure money yeah see you thursday masked redstoner pro thanks for watching how old are you i'm 23. burning the midnight oil to watch this live stream awesome man you have a car or do you plan to get one yes i just got a car um last friday super hyped it saves so much time for me like usually i mean i'm in the gym literally four to five times a week and if i have to take the bus that took me like around an hour or both ways and with a car i now only need 10 minutes per way so if i if i just work instead of instead of taking the bus then i can easily for the car with the the work that i do when i'm not taking the bus what are you building um so if you mean the app here it's a social network for my community using k tour as a back end see you man on thursday and congrats for the new car thank you shirak see you it's time for an overdrift yes we can make some car vlogs on on the autobahn someone asked for that today feels like that is always special for foreigners who come to germany driving on the other van how many of you have ever been to germany that would be cool to know one two yeah come over we get some ice cream i was in hohenfels where is that seems like a very small village internet was trash i believe that germany really sucks in regards to mobile internet do you play any game no not really if i play something then usually something chill or something you don't you don't need a lot of practice to be good at i thought about with um tutu to play some games here and there with coding and flow and code palace because that's with these people it's really funny but for some games you actually need more than three people for example we thought about gertig phone which is a very funny game it's free and a lot of streamers actually also play this but i think with only three people it's not that much fun let's create a fan meetup in germany here if you could arrange that then come over and i'm always open to do that but i don't think we we get enough people together here because most of my followers are not from germany so how about we end the stream now and then get back on thursday hopefully being able to fix this bug here with the testing stuff maybe in between i'll also get a little bit more into compost testing i'm very new to that and i'm sure that's just a stupid bug or stupid issue but i really want to say thank you for everyone who watched this stream we were a lot more people on average than in the last stream which i think is because we actually code it so i hope this average number rises in future that would be really exciting but thanks for everyone who watches this thank you for everyone who will also be there on thursday 5 pm cst and i will also announce this on instagram again and stuff like that but i wish you a good night good morning wherever you are and yeah you can see the recording on twitch hopefully hopefully but i i think i checked the box otherwise the next stream will definitely be recorded so yeah have a nice night till thursday bye
Info
Channel: Philipp Lackner
Views: 6,437
Rating: 4.9619045 out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile
Id: POfR2BA3Ljk
Channel Id: undefined
Length: 229min 29sec (13769 seconds)
Published: Thu Aug 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.