This practice will be retired on May 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In this video we'll create the UI for our note-taking app.
Related Links
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
All right, letΒ΄s make a note taking app.
0:00
In this video, we'll create the project
and make the UI for the app, and
0:02
in the next video, weΒ΄ll create all of the
Room elements that tie the app together.
0:07
So if youΒ΄d like to jump ahead and
0:13
see all of the Room part of the solution,
go ahead and click on to the next video.
0:15
Okay, let's get started by
creating a new project.
0:20
I'll name mine Note Pad,
And include Kotlin support.
0:29
Accept the defaults, and hit Finish.
0:38
Now that we've got the app,
let's click over into activity_main and
0:44
set up the layout.
0:48
Let's click on the Design tab and
we can hide the project paint for now.
0:51
And I'll make this a little easier to see.
0:57
To get started,
lets delete the hello world text view,
1:02
and then start from the bottom
right with our button.
1:06
Let's grab a button end from the pallet,
put it in the bottom right, and
1:10
remember since this is a constraint
layout, We need to add constraints,
1:14
so let's constrain it to the bottom right,
and
1:20
we can leave those as 8 DPs
with padding that's fine.
1:23
And for the text,
let's change it to say ok.
1:27
Then we need the edit text that goes
next to it, so let's click on Text.
1:32
And we can go with Multiline Text,
drag that down here.
1:37
Give it constraints to the bottom left
side, and on the right to the button.
1:49
Give it a size of match_constraints for
the layout width.
1:56
Also for the text size which we can
find in the all attributes section.
2:02
Let's start with 18sp.
2:12
Okay, now to add the RecyclerView.
2:18
RecyclerView doesn't come downloaded
by default, so by clicking it and
2:24
dragging it out, it'll prompt us to
add the project as a dependency.
2:28
Let's click OK here, And
now we can use RecyclerViews.
2:32
Just like the other views, we should
constrain the RecyclerView to the edges
2:44
of the screen and
the other views in the layout.
2:47
It looks like the constraints are here on
the screen, but maybe not over here on
2:57
the right, let's check this text and
find out what's real here.
3:01
RecyclerView, Is constrained, okay.
3:07
Not sure what's going on there.
3:15
There we go, okay, it is constrained.
3:19
Another thing we wanna be careful of when
placing views in a constraint layout,
3:22
is the layout width and layout height
being set somewhat arbitrarily.
3:27
It looks like this happened with our
RecyclerView, let's go ahead and
3:31
set these to match_constraints.
3:35
Perfect, also our edit text has an Id of
editText, our button has an Id of button,
3:38
and our RecyclerView doesn't have an Id
yet, so let's call it recyclerView.
3:44
Okay, that should be good for
the layout for now,
3:54
if it's not we'll find out when we
run the app and fix it at that time.
3:57
The other layout we'll need to
create is the layout that goes
4:01
inside the RecyclerView
representing one row.
4:04
Let's create that layout now,
let's open the project pane,
4:07
go into the res directory>
layouts> create a New> Layout
4:13
constraint layout is fine,
and let's call it note_row.
4:17
It's a constraint layout and right now
it's set to fill the space it inhabits.
4:24
Which is not quite what we want.
4:31
We do want it to be as wide as the parent
but not as tall as the parent.
4:33
So for the layout height,
let's set this to 80dp.
4:38
So each row will be 80dp tall.
4:43
Inside this row, let's start by
putting a divider at the very bottom.
4:46
Let's pick Horizontal Divider and
drag it out to the screen.
4:50
Then let's put it on the bottom
with no padding, And
4:56
let's also center it by adding
constraints to the right and left.
5:02
We can leave a padding for each of those.
5:06
Then we need to add a text view
to show the text of the note.
5:11
Let's drag out a textView,
And constrain it,
5:15
To the middle of our constraint layout.
5:25
Then we'll change the layout width and
height to let it use all of the space.
5:28
Next, to make the textView be centered,
5:36
let's go into All Attributes,
and under gravity,
5:39
let's check the box for, let's see
if we can see this a little better,
5:43
center_vertical to move the text
to be centered vertically.
5:48
Notice how before upper_left,
center_vertical and the middle.
5:54
And we can leave this as
an Id of textView, awesome.
6:01
Now that we've got our views,
let's flip back to main activity and
6:05
start writing some code.
6:08
Inside the onCreate statement let's create
three variables to represent each of
6:11
our views in the activity main layout.
6:16
Let's get one for the editText.
6:20
We'll findViewById, and we'll bring
back an EditText, the R.id.editText.
6:25
And let's do val button = findViewById,
6:32
it'll give us a button,
and the id is R.id.button.
6:36
And finally, we've got the recyclerView.
6:44
I'm gonna need to import that, and
the new ID is R.id.recyclerView.
6:54
Once we've got these, we'll need
an adapter for our recyclerView.
7:01
So, let's create a new class, And
give our recyclerView an adapter.
7:06
Whenever I'm not sure what to call it,
I usually just default to my adapter.
7:14
If I come up with a better name later,
I can always change it.
7:18
So let's call this MyAdapter and
7:22
make it extend from RecycleView.Adapter.
7:26
And it'll want us to specify our
ViewHolder class, With the adapter.
7:30
But it doesn't exist yet,
so let's create that first.
7:37
That'll be an inner class and
we'll call it ViewHolder.
7:41
And it extends from
RecyclerView.ViewHolder.
7:48
Then we can auto complete to
add the constructor call, and
7:57
looks like we need to pass in a view,
so we'll pass in a view.
8:02
And we'll need to import the View class.
8:08
And now that we have our ViewHolder class,
let's use it up on the class line, so
8:13
MyAdapter.ViewHolder.
8:18
And let's use Alt + Enter to
add the constructor call, and
8:20
then we need to implement
the class members.
8:23
And if you go into the settings,
8:29
you can make it not give you these
to do lines if you'd rather.
8:32
Okay, now inside our adaptor,
8:41
let's start by creating a list to
represent the data in the RecyclerView.
8:44
And it'll be just a mutable list
of strings, and it'll start empty.
8:51
And then in onCreateViewHolder,
let's create a view first, and so
8:57
that'll be LayoutInflater.from and
to get the context, we can use the parent,
9:02
Then we need to call inflate,
pass in the resource ID.
9:11
So, R.layout.noterow,
9:14
then we need to pass the view
group which is parent, and
9:17
whether we need to attach it
to that route, which is false.
9:22
Now that we've got the view,
we need to return a view holder.
9:28
So just return a new view holder
object while passing in the view for
9:31
the constructor, awesome.
9:37
getItemCount and let's move this over so
we can see that a little better.
9:39
For getItemCount we can just
set that equal to list.size.
9:44
And for onBindViewHolder we'll call a
function in our ViewHolder class to update
9:51
the ViewHolder, so
let's create that function first.
9:56
Since our note row only contains on
view that we need to do anything with,
9:59
the text view,
let's start by grabbing that textView.
10:04
Let's do val textView and
instead of view.findViewbyId,
10:09
and this is gonna be a textView, and
10:14
we'll pass in after we import
textViewr.id.textView.
10:17
Then let's add an update function,
so fun update and
10:23
this will take in the index
of the list which is an int.
10:28
And inside this function, we'll just do
textView.text = list, at position index.
10:33
Finally, in onBindViewHolder(),
we just need to call holder.update(), and
10:41
pass in the position variable, awesome,
that should do it for our adaptor.
10:48
Back in the activity, let's create
a new instance of our adaptor,
10:53
And then finish setting
up our recyclerView.
11:02
So first, we concept the layout
manager = LinearLayoutManager.
11:06
We're gonna pass on the context,
the orientation which is vertical,
11:15
And then reverse layout which is false.
11:22
And after setting the layout manager,
11:27
we need to add the adapter,
recycleView.adapter = adapter.
11:30
All right, and
we've got access to each of our views.
11:35
Let's add a couple lines and start adding
the code that ties it all together.
11:39
When we click the button, we need to take
the text that's in the edit text and
11:45
add it to the recyclerView.
11:50
We'll make this work with
the database in the next video.
11:51
But let's just hook things together for
11:54
the moment to make sure
everything's working.
11:56
So let's take our button and
call setOnClickListener and
12:00
pick the version with the brackets.
12:05
Then inside the brackets we
need to get access to the note.
12:08
Let's create a new variable called note,
and set it equal to editText.text,
12:12
and then .toString() to
turn it into a string.
12:19
Then let's verify that our
note isn't blank, so if note,
12:24
.isNotBlank(), and
then we'll do something with it.
12:30
So let's take our adapter.list,
And add the note to it.
12:35
Then we'll invalidate our adapter, or
12:46
rather notifyDataSetChanged,
and that should update the UI.
12:49
Though if you run the app here,
we should see a couple little issues.
12:57
So if we run it, and we add a message,
13:11
And click OK, so
there's a couple things to notice here.
13:17
One, it looks like our Hello World text is
indented, not quite as far as the divider.
13:21
Ideally, they'd be indented
the same distance.
13:28
Let's check out what's going on there
by heading into our activity_main.xml,
13:31
Or rather the node_row.
13:37
And let's bring in the Attributes pane,
13:40
see the textView is at 8, and
the divider is also at 8.
13:44
But the divider is tricking us here
again by setting a specific layout width
13:49
let's change this to match constraint,
and that should fix that issue.
13:53
So let's run the app again, we'll come up,
put in some text, hit OK and there it is.
13:59
It's over the same amount as the divider,
also the text looks a little small,
14:04
so I'm gonna head back in here,
change the textView itself from
14:10
down the text size and
lets change that to 18sp, as well.
14:15
Okay, then we can run this again.
14:22
Verify that's fixed,
good that looks better.
14:28
Another issue,
the keyboard is not going away and
14:30
the keyboard text is not being cleared.
14:33
So to clear the keyboard text
that one's actually pretty easy.
14:35
Just come in here and
we just set editText,
14:38
.setText, and set it to nothing.
14:45
But to close the keyboard is
actually a little bit harder.
14:49
And if you Google for it,
14:52
You're almost guaranteed to find this
page describing how to solve the issue.
15:00
It's not pretty, but it does work.
15:04
So, with over 4,000
upvotes on Stack Overflow,
15:07
let's just copy this code and
paste it into our OnClickListener.
15:12
And we can hit OK to make it automatically
convert from Java to Kotlin.
15:23
Then we'll need to use Alt + Enter
to add a couple of imports, and
15:28
we should add a comment saying,
close the keyboard.
15:32
Okay, let's run this one more time.
15:38
And then if we add a note, Hit OK,
15:45
the note gets added, it lines up with
the divider, the text is big enough,
15:50
the keyboard went away and
the text is cleared of the edit text.
15:55
All right,
15:59
in the next video we'll finish this up
by integrating room behind the scenes.
16:00
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up