Switch a whole application to alternative "styles.xml" files at run time? - android

my app has a styles.xml file with various visual constants defined.
I'd like my users to be able to switch the entire app to an alternative visual theme. I'd like to provide an alternative styles2.xml file and switch at runtime (via the Settings).
Is this possible, and how? I suspect the style names' appearance in the generated R class does not bode well.
If it's not possible, what's my next best option?

Not sure if anyone is still interested but I have found a possible solution. A bit hackish but gets the desired result.
Basically I set up my 2 style files in separate country code directories:
res/values-mcc199/style.xml
res/values-mcc198/style.xml
Then in my activity I use the following to change which is referenced:
Configuration config = new Configuration();
config.mcc = 199;
getBaseContext().getResources().updateConfiguration(config,null);
I've only done some basic testing so far but it appears to work. Obviously if you are already using country code to decide your layouts then this will interfere. I think there may be problems as well if the phone gets an event about a country change.

Actually, after some reading of the doc, it seems that this can be done. Look here.
As it is mentionned :
To create a set of styles, save an XML
file in the res/values/ directory of
your project. The name of the XML file
is arbitrary, but it must use the .xml
extension and be saved in the
res/values/ folder.
Now, if this is logical and I didn't read the doc wrongly, you can create as many styles as you want, reference them in themes.xml with #style/... (if you want to apply it to a whole activity or application) and then, just call
setTheme(R.id.yourtheme)
I think this should work. Have a go at it and tell us?

It's not an exact answer; in my blog post here:
http://blog.blundell-apps.com/switching-android-configurations-using-constants-and-ant/
I switch out a java class at build time using Ant, there is nothing to stop you switching out an XML file, as it compiles after the switch. To amend the tutorial you'd just have to change the path's of the file your templating.
Also mirrored on GitHub: https://github.com/blundell/BuildChoiceTut

Related

Is it possible to use strings.xml from one localization values folder for another similar language?

I've been looking on Internet for this but didn't find any article/blog (probably I have been looking poorly) so I'd decided to ask question here: is it possible to use same strings.xml (translations) from one language folder for another language, which is very similar? To be more specific, I'd like to use translations from values-sk also for values-cz language.
I was thinking about writing a Gradle script which would make a copy of strings.xml file in values-sk folder and copy it into values-cz folder on build, but I'd like to know if there's an easier/out of the box solution.
Well, I solved it using Gradle script before build. In case someone's interested, I added new task in app.gradle (at the end of the file, but that shouldn't matter):
gradle.projectsEvaluated {
preBuild.dependsOn(copySkStringsFileToCsFolder)
}
task copySkStringsFileToCsFolder(type: Copy) {
description = 'Copies strings.xml from values-sk to values-cs'
from 'src/main/res/values-sk/strings.xml'
into 'src/main/res/values-cs'
}
From what I overview, it copies the file on every Sync/Build operation - works pretty neatly for me, but I am still interested in other possibilities (if there are any).
Also I would like to apologize to Czech people that I misinterpreted the code for values folder (using -cz instead of -cs) - sorry 'bout that, I didn't know I was supposed to use the other one. :)
Create both values-sk & values-cz folder in your /res directory of your project and then copy-paste the strings.xml to each. As you can see, those will be different directories but with the same strings.xml so, it probably should work.
After that, Android will detect that you have two different directory-strings for two different localization then, you can change, modify each one of them (If needed).

what R.java file actually does and how

I have been working on a simple android tutorial and while browsing through the project folders I found this R.java file in gen folder...
When I opened it seemed to me as a mess...
first R itself is a class.
it had multiple Inner classes defined within eg drawable,id,layout,etc.
and that inner classes had lots of variables declared as below which were assigned with hex values
public static final int addr=0x7f080003;
...
...
and much more
R is auto generated and acts as some pointer for other files
Questions for R.java
what it is basically for
how it works
why
values are in hex
what role did it performs while the actual application is running
"Acts as some pointer to other files" is actually absolutely correct, now the question is which files it points to how it is done.
What does it contain?
R file contains IDs for all the resources in the res folder of your project and also some additional IDs that you define on your own (in the layouts, for example). The IDs are needed for the Android resource management system to retrieve the files from the APK. Each ID is basically a number which corresponds to some resource in the resource management system.
The file itself is needed so you can access or reference the resource from code by giving the ID of the resource to the resource manager. Say, if you want to set the view in the activity, you call
setContentView(R.layout.main);
main in the R file contains the number which is understood by the Android resource management system as the layout file which is called main.
Why is it better than just plain file names?
It's harder to make a mistake with the generated fields. If you write the field name incorrectly, your program won't compile and you will know that there's an error immediately. If you write an incorrect string, however, the application won't fail until it is launched.
If you want to read more on this topic, you should check the Android documentation, especially the Accessing Resources part.
This holds your resource ids. So when you do something like
TextView tv = (TextView) findViewById(R.id.mytextview);
it looks up your id here for that View, layout, etc... This way the app has an easy way to look up your ids while you can use easy to remember names. Anytime you create a resource it automatically creates an id for it and stores it here. That's why you never want to try and edit this file yourself.
One way to think about how valuable R.java is, imagine a world without it. Its amazing how android brings the xml and java world together to help avoid coding the UI manually completely. With legacy java building UI using the java language was a pain. Invaluable.
With Android you can not only build your UI using only xml, but also see it while you build it. Invaluable.
Every element in the xml can be referenced in the java code WITHOUT writing a single line of code to parse the xml :). Just R.id.nameOfElement. Invaluable.
Rapid development is beautifully done in android. Imagine if iPhone would have 5000 screens to fit that one piece of code, they would crumble on their XCode. Google has done a wonderful job with just R.java. Invaluable.

How can one bend Android's layout XML l10n-wise?

As you probably know, Mozilla aims to do the mobile UI on fennec as native Java/Android UI.
That includes using the layout XML files, which by default use stuff like
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/text_a"
/>
with #string/text_a being resolved to text_a in a strings.xml file, doing l10n.
We'd like to use something else, and I wonder if/how we can hook that up in the XML files.
So, I'd love to get pointers to android source code that actually does the string lookup, for one.
And I have three ideas on how to hook up something custom, which are not fact-checked, basically because I haven't managed to find the code that does stuff yet:
#moz-l10n/text_a, with a java-implemented service giving back values for that resource type
moz:l10n="text_a" custom attribute that would get hooked up to post process the generated widgets
subclass the widgets we want to localize with our scheme, adding (2)
I hope that there are folks out here that have a good idea to point me to good paths or shoot some down.
PS: I'd appreciate a lack of bike-shed about whether android l10n scheme is good or not.
So, I'd love to get pointers to android source code that actually does the string lookup, for one.
android.content.res.Resources delegates to android.content.res.AssetManager and the getResourceText() method. That in turn dives into a native loadResourceValue() method. And you're on your own from there... :-)
1) #moz-l10n/text_a, with a java-implemented service giving back values for that resource type
Unless you are going to pre-process your faux resource files with your own build tools, generating valid Android resource files into the res/ directory, you cannot invent new resource types (e.g., #moz-10n). That would require modifications to the build tools and the firmware.
2) moz:l10n="text_a" custom attribute that would get hooked up to post process the generated widgets
3) subclass the widgets we want to localize with our scheme, adding 2)
Your option #3 is definitely possible and is fairly typical when creating custom widgets. It's conceivable that the techniques for it (usually involving a res/values/attrs.xml file with a declare-styleable resource) could somehow be applied to a standard widget class, but I've never seen that done. Of course, you could always do the pre-processing as in how you'd accomplish option #1.

Where can I find the android.R.* files?

I am looking for the preset android files that come with the Android os. Can someone direct me to the source?
(Android install path)\android-sdk-windows\platforms\android-version\data\res
Hope this is what you mean.
Call the following as an example:
android.R.*
You can access built-in animations, layouts, text fields, whatever you need.
So if you wanted to find the default android black color, call the following:
View.setBackGroundColor(android.R.color.black);
This returns the INTEGER containing the pointer to the appropriate resource files.
All R files are generated as integer pointers, so this is the proper way to access these resources.
Hope this helped!
Try codesearch from google:
http://google.com/codesearch (choose android on the left side) or directly:
http://google.com/codesearch#cZwlSNS7aEw/frameworks/base/core/res/&exact_package=android
go to gen-> android.support.v7.appcompat ->R.java
Android generated a special called the
‘R’ file. This is a file of constants that allow you to
get Java references to the TextView you defined
in main.xml In fact, you can get references to all
kinds of in app resources you define! But remember
the String resources you defined in XML? You can
get references to those too.
You mean R.java? It will be in %project root%/res/android/%your project name%/

Layout files naming conventions?

What are some layout file naming conventions people have come up with.
I haven't found anything online, but thought about using the following convention.
What does everyone think?
- activity_*
- dialog_*
- list_item_*
That's all I have worked with so far.
Also, what about the naming of the activity against its layout? For example:
-> res
-> layout
-> activity_about_us.xml
-> src
-> activity
-> AboutUs.java
Strangely enough, trying to google this question brings only this page as meaningful result...
For the past half year I am using naming convention similar to yours but with shorter prefixes. For example:
For activity that shows "About us" screen:
Class name: ActAboutUs. Prefixing class is kind of overkill but it clearly distinguishes activity classes from the others. Initially I used separate directory for all the activities (similar to your approach) but after some time I realized that for bigger apps may be it is better to group in directories by feature than by superclass (i.e. Activity). It is easier for me to work in single directory for example /src/settings/ when I work on Settings. That way all java files that I need are in a single dir so i don't have to wander around:
/src/settings/ActSettingsGlobal.java
/src/settings/ActSettingsNet.java
/src/settings/Settings.java
/src/settings/SettingsDBAdapter.java
/src/settings/etc...
This approach also helps to split the work among different developers, i.e. each one is working in his own dir on separate feature so no stepping on each other's feet :-).
Some people preffer suffixes but I found them less useful. Prefixes help to group things alphabetically like in the example above: Act* prefix is sorted first so all activities are conveniently at the top.
I am even considering of using Act_ as a prefix which is more readable although it is in conflict with java naming conventions...
Layout filename: act_about_us.xml. In res/layout/ we don't have the "luxury" of subdirs which is quite unfortunate so the only way to group things is using appropriate prefix like act_, dlg_, etc...
String IDs: <string name="act_about_us_dlg_help1_title" ...
string.xml is the place where we have most problems with duplicate names. It is very easy to create duplicates if naming convention like activity_element_item is not used. It adds a lot of additional typing but it saves you from a lot of confusion later on.
For global (application wide) strings we use prefix "global_", for example global_btn_ok, global_msg_no_inet_conn. Usually we make one person responsible for all global_ strings so if someone needs new string or change he needs to sync with him in order to avoid creating a mess.
(now I am realizing that activity__element__item (two underscores) is more clear and readable than activity_element_item)
All in all I still can't get rid of the feeling that there is something wrong with my approach because I can't believe that google devs created such an inconvenient framework when it comes to working with files, IDs, names, etc...
i think following naming convention should be follow
for activity
if our activity name is
DisplayListActivity
then our layoutname should be
display_list_activity.xml
for list items we can include category in list item layout name
country_list_item.xml
and for dialogboxes their action can be included
delete_country_dialog.xml
When looking for a group of layouts, which is how I tend to work on them, I find it effective to always prepend the class name and follow up with any sub-layouts. For Instance:
Class Name: AboutActivity.java
Layout Name: about_activity.xml
Sub-layout Name: about_activity_menu.xml
Sub Sub-layout Name: about_activity_menu_item.xml
Your activity will always be at the top of each grouping and hunting for non-activities becomes less of a chore. Anyone know why sub-folders aren't a thing yet? I expect for efficiency and simplicity on the back-end, but I imagine it wouldn't hurt too much.
This is a good read https://jeroenmols.com/blog/2016/03/07/resourcenaming/
Basically, you follow WHAT WHERE DESCRIPTION SIZE
For example, layout file
activity_main: content view of the MainActivity
fragment_articledetail: view for the ArticleDetailFragment
strings
articledetail_title: title of ArticleDetailFragment
feedback_explanation: feedback explanation in FeedbackFragment
drawable
- all_infoicon_large: large version of generic info icon
- all_infoicon_24dp: 24dp version of generic info icon
The first part of a layout file name should always be the type of the corresponding class.
For example if we have a class MainActivity (type is Activity in this case), the corresponding layout file should be called activity_main.xml
That means that lets say we have a dialog called WarningDialog, the corresponding layout file should be called dialog_warning.xml, same goes for fragments etc.
This might seem familiar because thats also how the activity/layout files are named when creating a new project in Android Studio (MainActivity -> activity_main.xml).
For me, naming should fix two important requirements:
it should give you a hint about files' content and type (for example activity_login/login_activity or movie_list_item/list_item_movie)
it should visually group related items together to minimize jumping back and forth
For the second requirement, most people define "related" as type related which gives you something like this:
activity_login
activity_movie_list
activity_user_list
activity_settings
fragment_movie_list
fragment_user_list
item_movie
item_user
etc.
I prefer to do grouping by feature since you'll almost never work on all activities or all fragments, but instead, you'll work on movies feature or setting feature.
so, my prefered way is this:
login_activity
movie_list_activity
movie_list_fragment
movie_list_item
user_list_activity
user_list_fragment
user_list_item
settings_activity
Source files are following xml naming but in CamelCase, so there will be
LoginActivity
MovieListActivity
MovieFragment
etc.

Categories

Resources