1 00:00:00,340 --> 00:00:05,170 Now that we've got our chart, let's see how we can add it to our layout in XML. 2 00:00:05,170 --> 00:00:06,358 It's actually pretty easy. 3 00:00:06,358 --> 00:00:14,300 Inside our layout file, Let's just add our ChartView inside our RelativeLayout. 4 00:00:21,737 --> 00:00:26,860 And then let's set width and height to match_parent, and there we go. 5 00:00:26,860 --> 00:00:36,755 Now let's just set android:id=@+id/chartView. 6 00:00:38,240 --> 00:00:43,022 And then over in MainActivity, let's delete these three lines of layout code. 7 00:00:45,961 --> 00:00:50,989 And instead, let's set our chartView 8 00:00:50,989 --> 00:00:58,470 = (ChartView)findViewById(R.id.chartView). 9 00:00:58,470 --> 00:01:05,383 Then let's run the app, And yikes, we got an error! 10 00:01:09,022 --> 00:01:15,081 And if we look through this, It looks like we got a NoSuchMethodException. 11 00:01:16,762 --> 00:01:18,566 It's looking for an init method. 12 00:01:20,389 --> 00:01:24,340 That takes on a Context and an AttributeSet, but it's not finding it. 13 00:01:25,410 --> 00:01:26,670 Over in our ChartView class, 14 00:01:27,920 --> 00:01:31,340 let's take another look at the warning on our class name. 15 00:01:31,340 --> 00:01:33,720 This is the issue it's warning us about. 16 00:01:33,720 --> 00:01:38,460 When we add view in XML, they end up calling one of these three constructors. 17 00:01:38,460 --> 00:01:42,850 And since we added some attributes, like the ID, to our ChartView, 18 00:01:42,850 --> 00:01:47,260 we need to use the constructor that takes in a Context and an AttributeSet. 19 00:01:47,260 --> 00:01:49,690 So instead of taking in a resId, 20 00:01:49,690 --> 00:01:51,945 let's change our constructor to take in an AttributeSet. 21 00:01:53,070 --> 00:01:54,960 And let's name it attributesSet. 22 00:01:54,960 --> 00:01:59,860 And let's also update the call to super to call through to context, attributeSet. 23 00:01:59,860 --> 00:02:04,060 Now we just need to add our resId to the AttributeSet, and we'll be good to go. 24 00:02:04,060 --> 00:02:07,330 Unfortunately, there's not a good default attribute for this. 25 00:02:07,330 --> 00:02:09,180 So we'll need to make our own. 26 00:02:09,180 --> 00:02:13,620 To do this, we first need to create a values file for our custom attributes. 27 00:02:13,620 --> 00:02:19,800 So let's right-click on values > New > Values resource file. 28 00:02:19,800 --> 00:02:23,870 Then let's name it attrs and create the file. 29 00:02:25,050 --> 00:02:29,590 Next, inside the resources tags, let's add a declare-styleable element, 30 00:02:29,590 --> 00:02:34,550 give it a name of ChartView, and then close the tag with a >. 31 00:02:34,550 --> 00:02:40,016 Then, inside our styleable, let's add an attribute, 00:02:41,650 And then let's name it data. 33 00:02:43,800 --> 00:02:49,670 And let's set its format to reference, meaning it refers to another resource. 34 00:02:49,670 --> 00:02:52,550 Then let's close this tag and head over to our layout to use it. 35 00:02:54,170 --> 00:02:56,910 Let's add a line below where we set the ID. 36 00:02:56,910 --> 00:03:03,935 And then let's type custom:, and use Alt-Enter to import the custom name space. 37 00:03:03,935 --> 00:03:12,310 And then let's finish up by setting our data attribute = @raw/goog, perfect. 38 00:03:12,310 --> 00:03:14,104 Now that we're passing in the resId and 39 00:03:14,104 --> 00:03:17,970 our AttributeSet, the only thing left to do is retrieve it. 40 00:03:17,970 --> 00:03:21,180 Back in ChartView's constructor, after the call to super, 41 00:03:21,180 --> 00:03:24,890 let's create a new TypedArray variable named typedArray. 42 00:03:25,970 --> 00:03:34,640 And let's set it = context.getTheme().obtainStyledAttributes. 43 00:03:34,640 --> 00:03:38,626 And then on a new line, let's pass in our 44 00:03:38,626 --> 00:03:43,789 AttributeSet followed by our styleable resource, 45 00:03:43,789 --> 00:03:48,263 R.styleable.ChartView, and then 00. 46 00:03:48,263 --> 00:03:50,780 And I'll hit Delete to make this only two lines long. 47 00:03:51,810 --> 00:03:56,494 Finally, on the next line, let's create a new int variable for our resId. 48 00:03:56,494 --> 00:04:02,150 And set it = typedArray.getResourceId. 49 00:04:02,150 --> 00:04:04,541 And then let's pass in R.styleable, 50 00:04:07,372 --> 00:04:12,953 .ChartView_data for the resource and 0 for the default value. 51 00:04:14,462 --> 00:04:18,830 Also, now that we're done with our typedArray, we're supposed to recycle it. 52 00:04:18,830 --> 00:04:21,451 Let's do that on the next line. 53 00:04:21,451 --> 00:04:24,990 typedArray.recycle, cool. 54 00:04:24,990 --> 00:04:27,000 Now let's run the app and see if it works. 55 00:04:29,110 --> 00:04:30,613 And it does, awesome! 56 00:04:34,880 --> 00:04:39,386 We just finished updating our app to add our custom view in XML instead of in 57 00:04:39,386 --> 00:04:40,790 the code. 58 00:04:40,790 --> 00:04:43,090 We've come a long way from the beginning of this workshop. 59 00:04:43,090 --> 00:04:45,680 And we've created a really cool charting app. 60 00:04:45,680 --> 00:04:49,120 But before I let you go, I want to make one thing very clear. 61 00:04:50,380 --> 00:04:54,710 Adding your views in XML is not any better than adding them in code. 62 00:04:54,710 --> 00:04:55,877 It's just different. 63 00:04:55,877 --> 00:04:59,050 There's no one-size-fits-all approach to this stuff. 64 00:04:59,050 --> 00:05:01,650 If you wanna add your views in code, go for it. 65 00:05:01,650 --> 00:05:04,300 If you wanna stick with XML, that's fine too. 66 00:05:04,300 --> 00:05:05,900 It's your thing, do what you wanna do. 67 00:05:07,320 --> 00:05:09,670 And on that note, if you've got any questions, or 68 00:05:09,670 --> 00:05:13,710 you'd like to share one of your own custom views, be sure to check out the community. 69 00:05:13,710 --> 00:05:14,420 Until next time,