This workshop 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 spice things up by adding some color!
Code
int r = (int)(Math.random() * 0xff);
int g = (int)(Math.random() * 0xff);
int b = (int)(Math.random() * 0xff);
int color = (0xff << 24) + (r << 16) + (g << 8) + b;
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
Tapping the widget will now result in
a call to our onUpdate function, but
0:00
that won't make our widgets
change color randomly.
0:04
To take care of that,
we just need to get a random color and
0:07
then set the background of our
frame layouts to that color.
0:10
Let's add some space above where we create
our intent, and then let's copy and
0:14
paste in the code from the teacher's
notes to give us a random color.
0:18
Then on the next line let's
call remoteViews dot and
0:21
if we scroll through the options we can
see that there are a lot of set methods
0:26
that take in a view Id and
a parameter like set text view text.
0:31
This is how you can update a view
that's inside a remoteViews object but
0:36
unfortunately, if we scroll to the top It
doesn't look like there's a set background
0:41
color method, but never fear Android was
kind enough to give us a workaround.
0:45
remoteViews use also come with a bunch
of special purpose set methods, like set
0:50
string, which takes in a string along with
the name of the method we want to call.
0:54
So, instead of calling
the setBackgroundColor method,
1:00
we're going to call this setInt method.
1:03
Then let's pass in our view
ID R.Id.frameLayout and
1:06
then the name of the method we
want to call as a string so,
1:11
setBackgroundColor and
1:15
finally we need to pass in
the argument which is just color.
1:19
Nice, now in this
onUpdate method is called
1:24
we'll update our linear layout
with the new background color.
1:27
Hopefully it all works let's find out.
1:31
After running the app our all ready
existing widget may have gotten the update
1:35
but if it didn't and when we click on it,
nothing happens, try getting rid of it and
1:39
bringing out a new instance.
1:44
And there we go, it's a different color.
1:51
And if we tap on it, we keep getting
a bunch of different colors.
1:53
Great, now let's put in another
instance of our widget.
1:57
And let's make them both change colors and
if I click on this one,
2:05
it changes colors just like it should.
2:09
Then if we tap on the first widget it
2:12
changes the color of the second one and
actually since we're looping over all
2:16
of our app widget Id's should do they both
update regardless of which one we click?
2:21
Let's jump back to
the an update function and
2:27
see if we can see what's going on here.
2:29
It turns out there when we add a new
widget to the screen the resulting call to
2:32
onUpdate only includes that widgetId and
the appWidgetIds array.
2:36
So when we add the second widget it
tries to create a new pending intent.
2:41
But this pending intent
only differs in the extras.
2:46
And that's not enough to make Android
think of it as a different pending intent.
2:50
But what Android will do is
update the current pending intent
2:54
to have this new appWidgetIds extra.
2:59
So now we've got one PendingIntent that
used to contain the widget id of our
3:02
first widget.
3:06
But now it's been updated to only
contain the Id of our second widget.
3:08
And this one PendingIntent is attached
to both of our widgets which is why
3:12
no matter which one we tap the last
one is the only one that will update.
3:17
To fix this, instead of looping over
the appWidgetId's parameter we're going
3:22
to get a reliable list of appWidgetIds and
then just loop over that.
3:27
Lets add a line above our for loop and
3:31
then create a new integer
array named realAppWidgetIds.
3:35
And let's set it equal to
appWidgetManager.getInstance
3:41
pass in a context, and
3:48
then call getAppWidgetIds and then we
just need to pass in a component name.
3:51
So let's type new ComponentName and
then pass in our
3:57
context In the class of
our app widget provider.
4:01
WidgetProvider.class and I will put
this on a new line so we can read it.
4:06
Finally, let's loop over realAppWidgetIds
instead of appWidgetIds.
4:15
And let's also update our
appWidgetIds extra as well.
4:20
Then let's run the app.
4:26
And if we tap on one of the widgets.
4:30
Perfect, they both changed.
4:32
We finally got our widgets changing color,
and
4:36
we've learned a little bit
about remote views too.
4:39
At this point I'd say you've got a great
understanding of the basics of widgets.
4:42
At last the world of widgets is
larger than just the simple ones that
4:46
change colors.
4:50
Coming up,
we'll see how to implement a list widget.
4:51
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