Office Hours — Today, May 7

Yesterday, May 6

May 7
8:50 AM
Mark M.
has entered the room
8:55 AM
Mark M.
turned on guest access
9:10 AM
Leora
has entered the room
Mark M.
hello, Leora!
how can I help you today?
Leora
Heya Mark!
How are you?
Mark M.
OK, and you?
Leora
Not bad not bad hhhhhh
So I got permission to rewrite an old project I had worked on
And the simplest thing has stumped me ----- the layout!
It is a gameboard - calculator style you might say
9:15 AM
Leora
and was written as a gridview with a BaseAdapter
Mark M.
ooooo... retro! :-)
Leora
And me, being so wise and experienced and all tried to turn it into recycler view, which i realized quickly is wrong in this case since it doesn't scroll and doesn't recycle
or grid layout which is completely inflexible....
since in the settings the user can change the item number to 4, 6, 9, or the default 12
Mark M.
that controls the numbers of rows? columns? both?
Leora
So....should i leave it as gridview (gasp)??
yes both
each column or row can be 2 or 3 span
Mark
has entered the room
Mark M.
for a fixed number of alternatives like that, I would consider creating individual ConstraintLayout-based layouts for each, and using the right one based on user selection
Leora
or 4 hhhh
Mark M.
(BTW, hello Mark -- I will be with you shortly!)
Mark
hello
Leora
hmmmm i didn't think you would say that :)
Mark M.
Leora: GridView is also set up for scrolling and recycling, so IMHO RecyclerView is also a viable option, though the ConstraintLayout approach would give you per-gameboard design flexibility
I would not use GridView or GridLayout -- I would expect them to be deprecated one of these years
Leora
with the constraint layouts option i would be copy/pasting 12 views! (gasp)
9:20 AM
Mark M.
it's possible you could do it with fewer layouts and using View.GONE visibility for some of the cells
Leora
deprecated eh
the items will also need to be shuffled when the user shakes the device
and smooshed a bit when a banner ad is presented
Mark M.
one advantage of RecyclerView is that if you use ListAdapter, you get automatic animations on a shuffle, to move the items around your board
(here by "ListAdapter" I mean the RecyclerView one, not the old AdapterView subclass)
Leora
oh i didn't know that
yes but it's really hacky to get recyclerview not to scroll
i think you even commented on that in SO once
i think it has to be in a nested layout
Mark M.
¯\_(ツ)_/¯
at a high level, if you want to use pre-existing UI things, I'd lean towards RecyclerView and/or ConstraintLayout, but in the end, it is up to you
let me take a question from Mark, and I'll be back with you shortly
Mark: your turn! do you have a question?
Leora
i was tempted to leave it as is, already has shuffle functionality written and all that, but if you think those layouts' days are numbered then....
ok
9:25 AM
Mark M.
(Leora: you could leave them alone if you prefer -- your next rewrite may need to consider changes, though)
Leora
then i rather consider them now :)
Mark M.
Mark: your turn! do you have a question?
Mark
I created a productFlavor called "liveScores". In the Android Studio Project View, I see app/src/liveScores/kotlin/com.sports.mobile/info. I see the same directory structure in the debug build type: app/src/debug/kotlin/com.sports.mobile/info. When I CMD+SHIFT+O for a file in the info directory I see app/src/liveScores/kotlin/com.sports.mobile/info and app/src/debug/kotlin/com/sports/mobile/info
Mark M.
Android Studio shows packages using dot notation, to/limit/the/number/of/nested/directories/
Mark
but why would it appear differently between debug and liveScores
Mark M.
oh, wait
Mark
com.sports.mobile is one directory in the project window. if I search for a file the paths are different
Mark M.
to be clear: CMD+SHIFT+O brings up a file explorer for that directory? (I use Linux and forget my macOS UI...)
9:30 AM
Mark
global search for files
so it lists a path from app. debug shows the package split up while livescores shows it as one package
Mark M.
OK, if you use Finder or something, and look at the app/src/liveScores/kotlin/ directory, do you see a com/ directory or a com.sports.mobile/ directory?
Mark
but project view shows both as com.sports.mobile
finder shows it as com.sports.mobile
Mark M.
OK, that's wrong
Mark
finder shows it as separate directories for the debug
Mark M.
I'm not certain how you got into that state, but you need that as com/sports/mobile/, not com.sports.mobile/
you may have difficulty fixing this directly from within Android Studio -- I would close the project in Studio, fix the filesystem using Finder or something, then reopen the project
9:35 AM
Mark M.
Android Studio's behavior of showing packages as dot.delimited.strings normally is fine, but in this case masked a real problem in the directory structure
let me take another question from Leora, and I will return to you in a bit
Leora: do you have another question?
Leora
errr same question
Mark
View paste
I have this in app gradle:

sourceSets {
  liveScores {
    java.srcDrs += 'src/liveScores/kotlin'
  }
}
Mark M.
ummm... same answer? :-)
Mark
OK
Mark M.
(Mark: that should be OK)
Leora
i thought you would be vehemently opposed to me using recyclerview since it doesn't recycle
but if i have your blessing...
Mark M.
you do not gain as much value from RecyclerView if you do not need recycling
but they have added enough stuff to RecyclerView and its related classes that it is not unreasonable to use it even in places where you do not expect to recycle stuff
Leora
i see
9:40 AM
Leora
so that or different layouts yeah?
Mark M.
those would seem to be the two main options, for using modern existing UI constructs
you could always roll your own custom ViewGroup, if you wanted, but I find those to be kinda complex
Leora
nah :)
Mark M.
or, since this is a game, you could change approaches entirely and switch to a game UI framework
Leora
as in, no thanks
game UI?
it's a toddler game. they click a card and it opens up
Mark M.
most Android games are not written using the View hierarchy -- they use various game toolkits
Leora
not too complicated
Mark M.
the best known is Unity 3D, though that's probably overkill here
Leora
it would be nice to know but yeah overkill
ok great thanks for your input Mark!
Mark M.
happy to help!
Leora
as always
Mark M.
let me take another question from Mark, and I'll return to you in a bit
Leora
peace
Mark M.
Mark: back to you! do you have another question?
Mark
for my liveScores product flavor I have my own version of files originally in src/main/com/sports/mobile/info that I moved into src/liveScores/com/sports/mobile/info. I want the app to use different files of the same name depending on the product flavor or build type. The file has a build error on the class name complaining Redeclaration
9:45 AM
Mark M.
View paste
you can have different class implementations either for:
- product flavors
- build types
- build variants
but you cannot have different class implementations for the same class for both build types and product flavors, other than by organizing them via build variants
Mark
I just want my product flavor to use its own version of the activity
Mark M.
you have more than one flavor, as you cannot just have a single flavor (other than to have no flavors at all)
(unless they added single-flavor support when they started forcing flavorDimension... actually haven't tried that recently...)
Mark
I created my own flavor
should i move the activity out of debug and into main
Mark M.
if you only wanted resources/assets/manifest entries to vary, then having just one flavor might work
but if you want classes to vary, you need two flavors (liveScores and, um, deadScores), with your class implementations in each
you cannot have the same class in main/ or in debug/
Mark
no this is an Activity. Originally it was in main. I want my own version in liveScores
ok let me try deleting it from the debug build type
Mark M.
then you need liveScores/ and deadScores/, each with their own version of the activity
and you need to remove the activity class from other places (main/, debug/, etc.)
Mark
what is deadScores
Mark M.
another flavor in the same dimension as the dimension that you have set up for liveScores
Mark
ok i can try that
thanks
Mark M.
(though I suppose undeadScores/ would allow you to have Walking Dead and Game of Thrones tie-ins... :-)
9:50 AM
Mark
haha
Leora
hhhh no spoilers! didn't see ep 4 yet
Mark M.
OK, we're running out of chat time -- if either of you have additional questions, ask away!
Leora
bye mark and mark, may the undead be with you
Leora
has left the room
Mark
before we go, how would I go about obscuring a module from deadScores, which I assume has the same source files as main?
Mark M.
what do you mean by "obscuring a module"?
deadScores/ has no source files by default, just as liveScores/ has no source files by default
Mark
I have an app module and an api module. liveScores depends on new code in api module. I would like to hide that code from deadScores
Mark M.
use liveScoresApi
so, liveScoresApi "your.artifact.group:your.artifact.id:1.3.3.7"
(or liveScoresImplementation)
that says "use this dependency only for builds for the liveScores flavor"
Mark
I unfortunately it is not in artifcatory, it is a separate module in the app
Mark M.
so, liveScoresImplementation project(":whatever")
Mark
yes
Mark M.
(or liveScoresApi)
9:55 AM
Mark
im not sure I follow, they both need the module but liveScores only should have the liveScores api functionality built in the final apk
Mark M.
what is "the liveScores api"?
if you mean "code in liveScores/", then by definition only liveScores builds will have that code
an undeadScores build will not have the liveScores/ code in it
they both will have main/ code, plus code for the build type (e.g., debug/ or release/)
Mark
I have 2 modules in the same project, app and api. Before liveScores app still uses api. WIth liveScores I have new app code inside liveScores AND new code inside api module
Mark M.
you will need another module then, AFAIK
the api module would be split into the common stuff that both flavors use and a liveScores-specific api module
and you would only add the liveScores-specific api module to liveScores builds, via liveScoresImplementatino
er, liveScoresImplementation
Mark
do modules have flavors? couldnt I create a flavor in api and reference it somehow specifically in liveScores product flavor from the app
what is liveScoresImplemenation?
Mark M.
"do modules have flavors?" -- um, possibly, I forget the details there
10:00 AM
Mark M.
implementation project(":whatever") says "add this module to all builds"
liveScoresImplementation project(":whatever") says "add this module only to liveScores builds"
you might wish to reconsider whether having a separate api module is worthwhile
Mark
OK I can create a submodule within api called liveScoresApi. Then in app's build.gradle say liveScoresImplementation project(":liveScoresApi")?
Mark M.
yes
Mark
yeah
great!
Mark M.
and that's a wrap for today's chat
Mark
have a wonderful day!
Mark M.
the transcript will be posted to https://commonsware.com/office-hours/ shortly
Mark
see ya
Mark M.
have a pleasant day!
Mark
has left the room
Mark M.
turned off guest access

Yesterday, May 6

 

Office Hours

People in this transcript

  • Leora
  • Mark
  • Mark Murphy
  • Mark Murphy