Office Hours — Today, May 13

Tuesday, May 11

May 13
5:55 PM
Mark M.
has entered the room
Mark M.
turned on guest access
6:05 PM
Scott
has entered the room
Scott
Hi Mark, how are you?
Mark M.
Fine, and you?
Scott
Doing well, thanks. I just a couple of softballs for ya.
Mark M.
fire away!
Scott
I'm trying to stick within Android best practices for UI, and am not sure the best way to accomplish providing a common set of options for each activity
ie, the app consists of 5 activities, each one should be able to be launched from any other
the menu for each is filled with activity context based options
where would I put the selections to jump to the other activities?
6:10 PM
Mark M.
"Pattern 4: Action Bar"
this is the new official advice from the core Android team on that topc
er, topic
now, five activities is a bit more than what they have in that Twitter app
you may have some difficulty making an action bar with four buttons and a logo
Scott
ok, that kind of a tab bar is what I had in mind, just wanted to make sure I wasn't straying from the paradigm
Mark M.
you're straying into a brand new paradigm
:-)
Scott
It seems like a common practice -- do current apps that you've seen handle it in a similar manner?
Mark M.
um, you mean, besides Twitter?
I haven't noticed it anywhere else
but, like I said, it's a new paradigm
that blog post is barely a day old
still has that "new paradigm smell"
Scott
ha - ok, thanks
6:15 PM
Scott
Also, if I am putting an image in the drawable folder that doesn't have different sizes, can I just drop it in the -mdpi folder only and it will be found?
Mark M.
I wouldn't count on that
create /res/drawable/ and put it in there
that's the default folder, for drawables not tied to a density, screen size, language, etc.
Scott
ok, thanks! That is all for now, appreciate the help.
Mark M.
no problem!
6:20 PM
Mike R.
has entered the room
Mike R.
Hi Mark
Mark M.
Howdy, Mike!
Mike R.
Have a few questions. Am I interrupting?
Mark M.
Nope, go right ahead
Mike R.
Let's start with audio. I have an activity that plays an audio file and I'm using the AudioDemo as the basis for it
I've hooked up a start, pause and stop buttons. all works well
What I'd like to do is display a progress bar / scrubber
Not sure how to get callbacks as the audio file is played to show total time, current position, etc
Mark M.
You don't get callbacks
You have to poll
If you read further in the Media chapter, you'll see the vidtry sample for streaming video
that shows a ProgressBar being used as a timeline
Mike R.
i'll try that. thanks.
Mark M.
It uses postDelayed() to get control roughly once/second
then calls getElapsedTime() and stuff to determine what to display
6:25 PM
Mike R.
Next is a list view.
I have several in them in my app.
One, which looks like all the others, is not showing the brief flash of orange to indicate selection
can't figure out why.
Mark M.
are you setting android:listSelector in the layout XML?
Mike R.
is there something I should be looking for to ensure that the item selection will show
Mark M.
a few things
android:listSelector
android:background for the widgets that make up your rows
and whether or not those rows are reported as enabled by your adapter
the defaults for those three all give you the orange flash
monkey with any of them, and you may lose the flash
of course, the monkeying may be intentional, just with unexpected side effects
Mike R.
not using listSelector at all. I'll check the background on the widgets. that may be it
Mark M.
background of layouts (e.g., RelativeLayout) are transparent by default
if you make those solid, you will need to do something about the selector (e.g., android:drawSelectorOnTop="true" and then provide a translucent selector in android:listSelector)
Mike R.
next topic. network connectivity. Is there a simple api call to determine if the device has a connection to the network?
6:30 PM
Scott
has left the room
Mark M.
android.net.ConnectivityManager
getActiveNetworkInfo()
if it returns null, you have no connection
otherwise, you get a NetworkInfo with the details of your connection
Mike R.
ok
Rotation events.
My app pretty much handles all rotations and I've got layouts for them, etc.
However, one activity is causing me problems.
as I understand rotation, the activity stops and recreates itself in response to a rotation event. correct?
Mark M.
by default, yes -- pause->stop->destroy, then create->start->resume for a new instance
Mike R.
is there some way during the onCreate call to tell if this is being done because of a rotation event?
Mark M.
strictly speaking, no
what exactly is your problem?
6:35 PM
Mike R.
During my onCreate method I call another activity that does a lot of network downloads, but I don't want to call that activity if i'm being created solely because the device is being rotated.
Mark M.
well, I'm not a huge fan of Activity A calling startActivity() for Activity B from A's onCreate()
if that's what you have to do, I can think of two possible solutions:
1. In Activity A, implement onRetainNonConfigurationInstance() to return...well, just about anything non-null. Then, in onCreate(), call getLastNonConfigurationInstance(), and if it's not null, you know you are being created as a result of a configuration change. 99% of the time, that's a screen rotation.
2. Block the destroy/create cycle for rotations on Activity A, via the android:configChanges attribute in the manifest, and use onConfigurationChanged() to fix up your UI
both of those are covered in the Rotation chapter of my Android book
Mike R.
yes. i think option 1 will work for my case.
finally, an app design question.
my app has a lot of cases of Activity A calling Activity B which might call Activity C
6:40 PM
Mike R.
in other object oriented frameworks i might create an instance of class A. Class A might create an instance of Class B and set some of the instance variables in Class B. Then i would invoke a method on Class B to display some UI
in Android I'm using an Intent and a startActivity method to display some UI
what i'm missing is the opportunity to create an instance of class b and set some instance variable from within Activity A
is there a way to accomplish this some other way than by using global variables?
Mark M.
the ideal answer is to use Intent extras
if what you want to pass around are not small primitives, then extras aren't a good answer
Mike R.
covered in the book, i assume? :-)
Mark M.
lightly
you'll see it in the Tutorials, when we add the database (Tutorial 11 or so)
Mike R.
not small primitives. more complex objects, arraylists, etc.
Mark M.
then you really should consider more MVC, and move some of that stuff out to a service, or perhaps a custom Application class
activities work best when they're fairly thin
6:45 PM
Mark M.
chunky activities are OK if they are all fairly independent
inter-dependent chunky activities are your problem
Mike R.
exactly. how do i learn MVC in android?
Mark M.
since I'm guessing the dependency will be tough to break, you need to slim them down and move complex data to a central spot
well, Android isn't a great MVC platform, so you wouldn't want to "learn" it on Android
Mike R.
i know how to do MVC, just not on android. any good examples?
Mark M.
you can move in an MVC direction by pulling your data model out to some classes outside any activity, so the activities hold onto just what they need and pass identifiers around
I don't have any great examples at the ready, that is in publicly-available code
that tends to get more complicated than I try to profile in the books, and the places where I've done it are all consulting gigs
Mike R.
I am doing that. I have all my data modeled in separate classes. but I need to pass at least arraylists to the activities
Mark M.
why?
Mike R.
well, for instance, one activity displays a list of articles, which it gets from an arraylist
Mark M.
well, let me rephrase: why are you passing array lists *between* the activities?
you indicated earlier, "not small primitives. more complex objects, arraylists, etc."
Mike R.
the app maintains several arraylists, one for each news channel the user subscribes to .
6:50 PM
Mike R.
one activity displays the list of news channels. the next activity displays the list of articles in the channel that the user selected, etc.
Mark M.
that should not involve "more complex objects, arraylists, etc."
let's pretend this is a feed reader, so I have some terminology to work with
your data model is a collection of Feeds, each of which has Posts
Mike R.
the article itself is a complex article, with several strings, urls, images, and booleans
as is a news channel
Mark M.
that's fine
you still should not need to pass any of that between activities
your articles/news channels/stuff should be held someplace central, outside any activity
such as a Service, or a custom Application class, or in a pinch a global
the news-channel-list activity gets its information from the Service
when the user clicks a channel, you pass a channel ID to the display-articles-list activity
the display-articles-list activity gets the articles from the Service
etc.
and if all of this really is stored in a database, you dispense with the Service
and this all just becomes queries against the database
much like the LunchList tutorial in the Tutorials book
6:55 PM
Mike R.
i can see how that might work. i was trying to avoid having to re-create some lists for performance reasons. but i might be better off just passing id's between activities
Mark M.
then cache the lists in the Service or something
Mike R.
i'll look into that. i don't think it will be too big of a design change.
that's it for me. talk to you next time. Mike
Mark M.
c-ya!
Mike R.
has left the room
Mark M.
turned off guest access

Tuesday, May 11

 

Office Hours

People in this transcript

  • Mark Murphy
  • Mike Renda
  • Scott