Creating the Tableau6:57 with Ben Deitch
In this video we'll create a custom View to represent a tableau pile!
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 up