I've searched for information about this but it's hard when I don't really know what to search for.
I'm working on a few android projects which share a common base (that I put in a few libs). The libs works with both classes and xml-files, and some other resources too. The most common is that I have a drawable xml which gets color information from an xml-file which defines which colors to use, called something like "foobar_colors.xml" or so. The "foobar_colors.xml" in the lib itself defines default colors.
When I use the lib in the projects these colors needs to change (to use the client company colors or so), and I'm not sure how the best way is to accomplish this... The libs uses allot of resorces, their own xml-layouts and such, so I really can't always "declare things stylable".
The way I do it now is include the "foobar" lib in my project, copy the "foobar_colors.xml" to my project resources and change their values there. This works since R.java seems to "overload" values like the lib itself sets "foobar_color1" to be black and the project sets it again to be red (and the projects defines has higher priority).
Now I'm just wondering, is this safe? Is there any better way to do it? Possible problems that might come up in the future?
Related
I have a library project and an application project. Beside other things the libary project contains some png and some vector drawables. Now I can easily overwrite a png drawable in the application project by giving it the same name and it will be displayed correctly. This does not work with vector drawables, though: The app always shows the vector drawables defined in the library, both on Android 4 and 5. The app would never show the application project's vector drawables.
Google claims an application's resources always have priority over a library's resources:
Since the tools merge the resources of a library module with those of a dependent application module, a given resource ID might be defined in both modules. In this case, the tools select the resource from the application, or the library with highest priority, and discard the other resource. As you develop your applications, be aware that common resource IDs are likely to be defined in more than one project and will be merged, with the resource from the application or highest-priority library taking precedence.
But as I said, in case of vector drawables, for some reason, it's the other way round. Any idea what I can do to make sure the vector drawables are overridden just like normal drawables and other resources are?
UPDATE: Resolved in support library v23.2! Nothing to do now :)
When the library project is built, the VectorDrawable creates PNG files for each density and places the original VectorDrawable in drawable-anydpi-v21.
If you place your VectorDrawable in drawable-anydpi-v21 in your app, then it will override the drawable from your library project. This seems like a bug and a new issue should be created (if one doesn't already exist).
NOTE: this will not replace the generated PNG files from the library. You will need to add those to your app as well to override them.
Based on the "NOTE" in Jared Rummler's answer and since this won't fit in a comment I'll post a little tutorial here for people who have trouble finding the generated PNG files:
You can find the folders with the required files inside build/intermediates/res/merged/debug or, if you are using product flavors build/intermediates/res/merged/<flavor>/debug. Now the least difficult way of copying the PNG files to the app would be to fully copy their folders, which are:
drawable-ldpi-v4
drawable-mdpi-v4
drawable-hdpi-v4
drawable-xhdpi-v4
drawable-xxhdpi-v4
drawable-xxxhdpi-v4
As a last and tedious step you should remove all files inside you don't need, i.e. those that aren't generated from your vector drawables. This is done easiest if you are using a VCS by adding only the PNGs you need. This places all redundant files under Unversioned Files.
And there you go, together with drawable-anydpi-v21 there are now 7 additional folders just because of this stupid bug :(
UPDATE: Resolved in support library v23.2! As of today, there is finally no need to do any of the above. Just make sure to use app:srcCompat instead of android:src everywhere.
The standard advice for sharing code & resources between Android projects is to use a library. Personally I find this works poorly if (a) the shared code changes a lot, or (b) your computer isn't fast enough.
I also don't want to get into deploying multiple APK's, which seems to be necessary when I use dependent projects (i.e. Java Build Path, Projects Tab).
On the other hand, sharing a folder of source code by using the Eclipse linked source feature works great (Java Build Path, Source tab, Link Source button), but for these two issues:
1) I can't use the same technique to share resources. I can create the link to the resources parent folder but then things get wonky and the shared resources don't get compiled (I'm using ADT 21).
2) So then I settle for copying the shared resources into each project, but this doesn't work because either. The shared code can't import the copy of its resources because it doesn't know the package name of the project that uses it. The solution I've been using is to access the resources dynamically, but that has become cumbersome as the number of resources grows.
So, I need a solution to either (1) or (2), or I'll have to go back to a library project. (Or maybe there is another option I haven't thought of?)
Your real problem is (2). Fixing (1) would eliminate some copying, but you would still run into problems with (2).
Unfortunately, that really isn't possible. There's a fair bit of fancy footwork that goes on to make multiple packages possible with library projects, and there's no good way to get that same result without library projects. Anything in res/ of a project is accessed via that project's R class, including your copied resources.
The solution I've been using is to access the resources dynamically
I translated that into you using getIdentifier(). That certainly works. Another approach is to having the hosting app supply resource IDs as parameters to the library code -- this is the pattern that the Android SDK itself uses. This is faster at runtime than the reflection-based getIdentifier(), and it gives the hosting app somewhat more flexibility, but you do wind up adding a bunch of parameters to your methods and constructors as needed to supply the various project-specific R values.
the res/layout* dir of my projects are getting really messy lately and as there are afaik no subdirs allowed there to change that. So it is hard to get structure in there - how do you guys do that?
I don't know about others but for myself I like to use prefixes to help keep things sorted, essentially taking the place of subdirectories. For example, all my activity layouts start with 'activity_' and all my UI controls start with 'control_', notifications with 'notification_', etc.
I am then left with a flat directory with at least some structure, something like:
activity_graph.xml
activity_main.xml
activity_map.xml
control_graph.xml
control_title_bar.xml
notification_just_label.xml
notification_with_progress_bar.xml
...
It's not perfect, but it works for me.
Sorry subfolder inside the layout folder is not possible other than docs specification.
Just check this and this and this question.
Another possibility is to refactor some elements of your application into libraries.
For example you could extract unrelated fragments (as fragments should per se be unrelated) into libraries, mark that project as an Android library (check "Is library" in project properties) and then use your own libraries in your main project.
The resources you need within the separate libs will not collide anymore, but will be "thrown together" at build time, so access is fine.
Here are the docs for that.
I'm wondering what some good ways of organizing Android projects are. I'm building a little recipe application and have already made dozens of layouts, drawable resources, menus, etc., not to mention Java source code.
Android does not allow sub-folders for resources, so is there a way to organize them? Right now I'm trying to organize them through naming conventions (e.g. new_list_ingredient_edit) but I'm wondering if there is a better way, as the names will probably get pretty long and cumbersome.
Same thing with resources such as string values. As I understand it, I can create multiple resource files (e.g. strings_new_ingredient.xml, drawables_new_instructions.xml, etc.) but all my resources across files have still have to have unique names, which again is cumbersome.
Although android doesn't allow sub-folders for resources, it does for assets, but this is much more cumbersome to use.
A possible option would be to use a sql database with all of your strings, but this approach is probably too much work and more cumbersome anyway.
Your naming convention method is probably your best option. You could think of some of the seperated words as directories if you want, which should keep it organized enough.
user864684,
I normally try to use heirarchy in my naming. If it is a layout for dialog, i will start with dialog_sharing or something like that.
As for graphics, I will start with btn or bg or txt or ic_menu depending on what they are for. Other than that, you just get used to it as you dev more for Android.
Make sure you also have a support folder on your drive for your local resources. I mimic the android layout so i keep my graphics sorted in res/... on my local drive too. I keep the psd and graphic files there and then just copy the pngs to eclipse.
Hope this kinda of helps. There is no real standard but you will pick up a style.
Specifically with respect to organizing drawable resources, I would advise choosing names that describe the drawables structurally, not functionally.
For example, if you have a gray circle shape resource that you are using as a placeholder for an image, I would avoid naming it *image_placeholder*. Instead, I would call it *gray_circle_1*.
My advice comes from having had the experience on multiple occasions of having given things names like *image_placeholder*, forgetting what they actually contained, and then rewriting the same exact thing in a separate resource file without realizing it.
Don't do what I did.
New to Android development and have decided to use NetBeans 6.9.1 as my IDE. So far the process has been somewhat painful, but I'm getting things rolling. However, I am creating an ImageView subclass for my first custom View and I can't figure out how to add my Box.png file to the project. Drag and Drop doesn't work, there are no right-click options to add a file to the Resources folder, no dropdown menus to add images, no way to add the image to a package. Could use some insight, thanks!
Just go to the project folder and copy the images you want into the res/drawable folder. The IDE helps you a lot with code completion, error checking, etc... but that simple task can be done by hand.
Then, you can reference your resources by using something like: R.drawable.image Notice that I'm not using the image extension. If you wonder what R is, let me give you a brief explanation:
Each resource that is saved in the resources directory is referenced in the R class. That's a file that is autogenerated by Android and it's used to reference those resources from your code. In this case, it will be in R.drawable.* since it's a drawable resource. There are other kind of resources, like layouts: R.layout.something or strings R.string.whatever. That's essential for the android development, so you better read some tutorials (or buy books) in order for you to get started.
So, in your case will be something like setImageDrawable(R.layout.wood); However, I highly recommend to read first a couple of tutorials. Google about it, you will find tons of them.