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 a custom View to represent a tableau pile!
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
We're almost done with this puzzle.
0:00
There's just one piece missing and
that piece is the Tableau, but
0:02
it won't be missing for long and after
it's done we'll have a full working UI for
0:06
our Solitaire app.
0:11
First things first,
we're going to need a new class.
0:12
So let's create a new class
named Tableau Pile View.
0:16
And this class is going
to be responsible for
0:21
all the cards in a certain Tableau Pile.
0:23
For constructor parameters,
we're going to need a context,
0:28
And also an index to tell us which
of the seven Tableau Piles this is.
0:36
And just like with foundation pile view,
0:44
this index is going to
need to be a property.
0:46
Then let's make this
extend relative layout,
0:51
And we'll need to pass along
our context parameter.
0:59
Next, iinside the class let's create
our init and update functions.
1:05
Our TableauPileViews are going to work
a bit differently than our other views.
1:15
Instead of actually updating the views,
1:20
we're just going to remove all the views
and then rebuild the Tableau from scratch.
1:23
So inside our init function let's call
a function that doesn't exist yet
1:28
named addViews.
1:32
And let's use Alt+Enter to create it.
1:36
And then put it below our update function.
1:41
Now, in the update function,
1:53
let's just call removeAllViews,
which removes all the views.
1:55
And follow that up with
a call to to addViews.
2:01
And now, the only problem we need
to solve is this addViews function.
2:05
Inside the addViews function,
2:10
let's start by getting a reference
to the cards in this Tableau Pile.
2:11
Val cards = GameModel.tableauPiles Add
2:16
this index.cards.
2:24
Then, lets add an image view to the screen
for each card in our cards list.
2:28
And let's use the forEachIndexed function
to make sure we're going through the main
2:33
order.
2:37
So cards.forEachIndexed i,
card are fine variable names.
2:38
And then inside the loop
let's add the imageView.
2:46
And inside the imageView let's
start by setting the y property.
2:52
And the y property is just the vertical
position of this view within its parent.
2:58
If we set y to 50 pixels,
then the top of this imageView
3:03
would be 50 pixels below the top
of this relative layout.
3:07
What we want to do here is sort
of cascade the cards down so
3:13
that we can see a little bit of each one.
3:16
To do this, let's set y = i x 25 dip.
3:19
And use Alt+Enter to import that method.
3:28
And we'll need to cast this to a float.
3:31
So put parentheses around it and
then type toFloat.
3:35
Moving on to the image resource.
3:40
If the card we're evaluating is faceUp,
3:44
Then let's return the resource ID for
that card.
3:49
Otherwise let's return
our cardBackDrawable.
3:56
Then for the onClick function, All we need
4:01
to do is call
a gamePresenter.onTableauTap and
4:06
pass in the index for
this Tableau Pile which is index and
4:11
the index for this card which is I.
4:16
We should also change the layout
params of this imageView
4:21
to make sure that it's the same
size as the other cards.
4:24
After our imageView function
let's add a call to lparams,
4:28
Which doesn't seem to exist,
which I guess is true for
4:33
RelativeLayouts, but
it's not true for _RelativeLayouts.
4:37
So let's change this to be
extending _RelativeLayout
4:43
And then we need to pass in card width for
the width and card height for the height.
4:50
But unfortunately, we don't have access
to those properties inside this class.
4:55
So over in MainActivity, one thing we
could do would be to pull these two
5:00
properties, And
5:04
make them scoped to the package
instead of the class.
5:09
And this almost works except
we need to have a context
5:14
in order to use the displayMetrics,
or the dip function.
5:18
To fix this, let's just make these
extension properties on context.
5:24
So Context.cardWidth Alt+Enter
to import context, and
5:28
let's tell cardWidth when
this is going to be an int.
5:32
And then let's add a getter
which returns the cardWidth.
5:39
And let's do the same thing for
cardHeight,
5:46
make it an extension property on context,
make it return an int,
5:49
And add a getter to
return the current high.
5:57
Back in the Tableau Pile View, we should
now be able to set our lparams by
6:02
using context.cardWidth and
6:06
context.cardHeight.
6:11
Finally, we just need to add our
view manager extension function.
6:15
Let's copy the one from
foundationPileView, And
6:19
paste it in at the bottom.
6:26
Then let's change the function names.
6:31
So tableauPileView and
then I'll copy this and
6:33
paste it over these two.
6:38
And since they both take an index
parameter, we're done with the class.
6:44
We're almost there.
6:49
In the next video, we'll finish adding
our tableauPileView to the screen and
6:50
play a little solitaire.
6:55
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