1
00:00:03,920 --> 00:00:10,440
G'day everyone, welcome back. Okay, let's
have a look at plurals string resources.

2
00:00:10,440 --> 00:00:16,040
I created someone I pasted the resources
into res slash values slash strings

3
00:00:16,059 --> 00:00:22,840
underscore settings.xml. In there we've
got three sets of units; for seconds,

4
00:00:22,840 --> 00:00:29,950
minutes and hours. Each unit is inside a
plurals resource and has the units when

5
00:00:29,950 --> 00:00:33,980
there's only one of it,
and the units for zero or several.

6
00:00:33,980 --> 00:00:41,200
For example, the quantity equals one value for the little units is second, singular.

7
00:00:41,200 --> 00:00:48,800
The other value, when quantity equals
other, is seconds, with the s on the end.

8
00:00:48,800 --> 00:00:53,440
Android takes care of choosing the
appropriate string for us, and contains

9
00:00:53,440 --> 00:00:58,149
all the rules for every language that
Android supports. You can find more

10
00:00:58,149 --> 00:01:12,000
information in the Google docs, at https://
developer.android.com/guide/topics/ resources/string-resource

11
00:01:12,000 --> 00:01:14,300
Scroll down a quarter of the way,

12
00:01:14,300 --> 00:01:19,980
and there's a section headed
Quantity Strings Plurals.

13
00:01:20,070 --> 00:01:24,360
I won't read through that option, but it
shows you all the options available to

14
00:01:24,360 --> 00:01:30,160
you. In the syntax box, you can see the
quantity names that are available.

15
00:01:30,160 --> 00:01:34,710
Android will select the correct one,
based on the user's language. Of course,

16
00:01:34,710 --> 00:01:38,160
you will have to provide a resource file
for every language that your app will

17
00:01:38,160 --> 00:01:42,450
support, and you'll need someone to do
the translations, unless you can speak

18
00:01:42,450 --> 00:01:47,620
all the languages yourself. Going back to
our strings underscore settings file,

19
00:01:47,620 --> 00:01:52,950
I've set up quantity strings for the
seconds, minutes and hours. We're not

20
00:01:52,950 --> 00:01:57,900
using hours, but you could easily extend
the deltas array to do that. Be careful

21
00:01:57,900 --> 00:02:03,330
though. If you have too many values, then
it can be very hard for your users to

22
00:02:03,330 --> 00:02:09,600
control the slider. Okay, that's how we
create plural string resources. Let's see

23
00:02:09,600 --> 00:02:15,120
how to use them in our code. We set the
seekBarValue initially, in the onView

24
00:02:15,120 --> 00:02:24,040
StateRestored function,

25
00:02:24,040 --> 00:02:29,900
and we need to check to see if we're displaying seconds or minutes.

26
00:02:37,080 --> 00:02:42,540
We get the correct quantity string by
calling the resources dot get quantity

27
00:02:42,540 --> 00:02:48,210
string function. We have to provide it
with the plurals resource ID, and also

28
00:02:48,210 --> 00:02:53,100
the value that we're trying to display.
It's a bit clumsy, having to provide the

29
00:02:53,100 --> 00:02:57,630
ignoreLessThan value twice, but the get
QuantityString needs to know the

30
00:02:57,630 --> 00:03:02,580
quantity. That lets it use the language
rules to return the appropriate string.

31
00:03:02,580 --> 00:03:07,180
Alright, that deals with the seconds, if
ignoreLessThan is less than 60.

32
00:03:07,180 --> 00:03:12,400
For larger values, the code's almost the
same, but we use the big units instead.

33
00:03:12,400 --> 00:03:17,500
We also divide the seconds by 60, to get the minutes.

34
00:03:25,690 --> 00:03:35,890
Run the app again, and we get the correct
number of seconds, and the singular or

35
00:03:35,890 --> 00:03:41,200
plural units appearing in the seek bar's
title. The next step is to update that

36
00:03:41,200 --> 00:03:46,810
text, when the slide is dragged from side
to side. To do that, we need to listen to

37
00:03:46,810 --> 00:03:52,450
changes to the seek bar. We've seen on
ClickListeners a lot. The seek bar has

38
00:03:52,450 --> 00:03:58,450
an onSeekBarChangeListener. It works
in the same way - we'll get call back,

39
00:03:58,450 --> 00:04:04,060
whenever the seekBarValue changes. I'll
set the listener in the onViewCreated

40
00:04:04,060 --> 00:04:09,000
function, just before we set the button's
listeners.

41
00:04:15,580 --> 00:04:21,579
The onSeekBarChangeListener interface
contains three functions, which means we

42
00:04:21,579 --> 00:04:26,440
can't use a simple lambda here. Instead,
we have to implement all three functions,

43
00:04:26,440 --> 00:04:31,540
even though we only need one of them.
I'll get Android Studio to create the

44
00:04:31,540 --> 00:04:37,650
stubs, using ctrl i with the cursor,
inside the control block.

45
00:04:51,580 --> 00:04:57,400
As I said, we have to implement all three,
so select them all from the dialog.

46
00:04:57,400 --> 00:05:03,340
For the onstartTrackingTouch and onStop
TrackingTouch functions, which we're

47
00:05:03,350 --> 00:05:08,380
not going to use, I'll just a replace the TODO with a comment.

48
00:05:32,690 --> 00:05:38,070
The code in onProgressChanged is very
similar to the code we used in

49
00:05:38,070 --> 00:05:40,060
onViewStateRestored.

50
00:05:40,060 --> 00:05:42,280
Whenever the seekBar's value changes,

51
00:05:42,280 --> 00:05:46,320
we'll find the number of seconds that
corresponds to the value, then display it

52
00:05:46,320 --> 00:05:50,090
along with the quantity string.

53
00:06:12,750 --> 00:06:17,820
There's another change I want to make.
Google haven't yet got around to

54
00:06:17,820 --> 00:06:24,030
annotating the seekBar parameter, as not
null. It can't be null - you can't get a

55
00:06:24,030 --> 00:06:29,310
notification from a null old seekBar - so I'll
remove the nullable type marker from the

56
00:06:29,310 --> 00:06:38,550
seekBar parameter. If you're not
comfortable doing things like that, then

57
00:06:38,550 --> 00:06:43,050
don't do it, but by the time you watch
this video, you may find that the seek

58
00:06:43,050 --> 00:06:49,980
Bar's been annotated as non null, anyway.
Okay, that should work. I'll run the app

59
00:06:49,980 --> 00:06:54,200
and drag the slider around to test that
it does.

60
00:07:04,540 --> 00:07:10,000
That's looking good - well goodish. Be
careful when displaying dynamic text

61
00:07:10,000 --> 00:07:15,010
like this in a dialog. It's very easy
to have the dialog jumping around,

62
00:07:15,010 --> 00:07:20,650
as it's with changes. It's not the best user
experience, and makes it hard to set the

63
00:07:20,650 --> 00:07:26,830
slider reliably. Fortunately, it's easy to
fix. Let's have a look at our Settings

64
00:07:26,830 --> 00:07:44,230
Dialog layout. Select ignoreSecondsTitle in the component tree, and check

65
00:07:44,230 --> 00:07:50,110
the attributes and the constraints. It
can take some careful thinking to work

66
00:07:50,110 --> 00:07:54,880
out what's going on here. I've got a
dialog that resizes itself, based on

67
00:07:54,880 --> 00:08:00,310
its contents, because that's what
dialogs do, and we've got a TextView

68
00:08:00,310 --> 00:08:07,140
whose contents change. That's why our
dialog keeps resizing. To fix the problem,

69
00:08:07,140 --> 00:08:11,800
we need to set the width of the TextView. The tricky bit is working out what

70
00:08:11,800 --> 00:08:16,450
to set it to. The only thing we really
know is the maximum number of characters

71
00:08:16,450 --> 00:08:23,050
we'll be displaying - that's 35 characters
in this case. Fortunately, Android does

72
00:08:23,050 --> 00:08:30,400
provide a way to do that. In publishing,
there's something called an em, spelt em.

73
00:08:30,400 --> 00:08:35,049
It's the width of the widest character,
which is usually an uppercase M, hence

74
00:08:35,049 --> 00:08:42,909
the name, em. If we set the em's attribute
to 35, then our textView can display 35

75
00:08:42,909 --> 00:08:51,340
characters without resizing. You'll find
ems in the extended attributes.

76
00:08:51,340 --> 00:08:58,920
Set it to 35, and then run the app again.

77
00:09:08,900 --> 00:09:14,640
That's much better. That approach should
work for all languages, because the TextView's

78
00:09:14,640 --> 00:09:18,980
height is set to wrap content. If
there are more than 35 characters in

79
00:09:18,990 --> 00:09:24,510
some languages, the TextView will wrap
onto another line. Alright, we'll finish

80
00:09:24,510 --> 00:09:28,620
the SettingsDialog in the next video,
when we'll add a title to the Dialog.

81
00:09:28,620 --> 00:09:31,820
I'll see you then.

