Android: dynamic resource values from layout xml - android

I have an application, in which I need to use diffrent text strings in each view.
I have already a function which returns the correct string according to internal state:
getText(String id)
so getText("menuTitle") might return "Title1" at one time, and "Title2" at another
and getText("buttonX") might return "Press" at one time, and "Click" at another
I have no problem to do this progmatically in each activity
however, as I have a lot of activities, it would be great if I can somehow override the resource mechanism, so instead of writing code in each Activity for each text
View v=findViewbyId(...);
v.setText(setText(stringID));
I could set in the XML
....
<TextView text="myDir/menuTitle" />
and recieve a callback with the resource name so I could return
getText("menuTitle")
instead of reading the resource from the file

You can make one common Baseactivity which contains your common view and just extend this baseactivity in each of your activity class and just set the text over their.

I think, you need a binding mechanism. Take a look at this young project. Or have some fun googling 'android binding' term.

Related

Using same Android binding class from 2 different layouts

I am trying to display data from the same class in two different layouts using Android's data binding. The layouts are used to inflate the views in a ListView. I already have it functioning for one, and I was hoping to use the same adapter class since it's easy enough to specify which layout resource to use.
The problem arises in the automatically generated databinding classes; since there are two layout files, it generates two of them, say, LayoutOneBinding and LayoutTwoBinding, and when I use
DataBindingUtil.bind(inflatedView)
I get one of the two, and they have no common superclass that I can assign the result to and still be able to use the contained data. So, is there any way to reuse the data binding class across two different layouts?
Each layout file has a separate <variable>, but it is named the same and contains the same type of data.
There is a way to reuse binding in case you have same variable names in both bindings. Every data binding extends ViewDataBinding. So, you have a super class which you can accept.
Here, you cannot directly set the variable like dataBinding.variable1 = someValue. But, there is an alternate way i.e. use of #setVariable function.
So in your adapter, your code would be something like as follow:
dataBinding.setVariable(BR.variable1, someValue)
Ref: https://www.vogella.com/tutorials/AndroidDatabinding/article.html#implement-the-recyclerview-with-data-binding

Is it possible to get an attribute value of a widget as declarated in the android layout.xml file?

Is there a way in an android application to retrieve the attribute value of a widget declared in a layout.xml?
for example in my layout.xml file i have :
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/clean_filesWithoutVideo"
android:checked="#{uiprefs.switchButtonEditable}"
android:id="#+id/checkbox_updateable" />
I would like to retrieve the literal value for android:checked, eg I want to retrieve "#{uiprefs.switchButtonEditable}" at runtime.
I searched in android.content.res.Resources class using getResources() from an Activity without success :
I cant get the xml file as stream.
Parsing attributes throught the Resources.getLayout() doesn't restitute the attribute value.
Maybe this value is hidden somewhere in the CheckBox instance but I can't find it using inspection at debug time...
Note : The value I want to retrive are especially databinding literals. Maybe I could retrieve this through the databinding API ?
Every UI component has it’s own getters and setters through which you can retrieve attributes that are currently set or set what you want to. If the attributes are common among the views, for example height/width, the getter will be available in View class.
In your case, you can get checked attribute through:
CheckBox checkbox = (CheckBox) view.findViewById(R.id.checkbox_updateable);
boolean initialState = checkbox.isChecked();
In Android Studio, you can get the methods available for a particular view. Enter var name (say checkbox) then enter dot (.) and it will show you all available methods. Start typing that you think you are looking for, it will show you all relevant methods.
UPDATE
I think AttributeSet is what you are looking for. You can do this :
XmlPullParser parser = resources.getXml(myResource);
AttributeSet attributes = Xml.asAttributeSet(parser);
From doc:
The implementation returned here, unlike using the implementation on
top of a generic XmlPullParser, is highly optimized by retrieving
pre-computed information that was generated by aapt when compiling
your resources. For example, the getAttributeFloatValue(int, float)
method returns a floating point number previous stored in the compiled
resource instead of parsing at runtime the string originally in the
XML file.
This interface also provides additional information
contained in the compiled XML resource that is not available in a
normal XML file, such as getAttributeNameResource(int) which returns
the resource identifier associated with a particular XML attribute
name.

What are "tag" and "id" on Layouts?

I know how the switch statement works but I don't know what this means (R.id.webbutton). Can anyone please explain what it is and also what is TAG?
Is there any guide for the beginners? I mean absolute beginners.
IDs and Tags
IDs
Views may have an integer id associated with them. These ids are
typically assigned in the layout XML files, and are used to find
specific views within the view tree. A common pattern is to:
Define a Button in the layout file and assign it a unique ID.
<Button
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_button_text"/>
From the onCreate method of an Activity, find the Button
Button myButton = (Button) findViewById(R.id.my_button);
View IDs need not be unique throughout the tree, but it is good
practice to ensure that they are at least unique within the part of
the tree you are searching.
Tags
Unlike IDs, tags are not used to identify views. Tags are essentially
an extra piece of information that can be associated with a view. They
are most often used as a convenience to store data related to views in
the views themselves rather than by putting them in a separate
structure.
Tags may be specified with character sequence values in layout XML as either a single tag using the android:tag attribute or multiple tags using the child element:
<View ...
android:tag="#string/mytag_value" />
<View ...>
<tag android:id="#+id/mytag"
android:value="#string/mytag_value" />
</View>
Tags may also be specified with arbitrary objects from code using setTag(Object) or setTag(int, Object).
Id is id of your xml's components [may be views like textview,edittext... or viewgroup like linearlayout ,relativelayout... or anything else] in xml simply you can get reference to them in java code by saying
(R.id."id of your view in xml")
but firstly you should use setContentView(R.layout."name of xml file in layout/res in your project")
this xml file which you want to use it's components .
TAG i use it when i want to show message in logcat [tool in eclipse you can watch your app messages when it is running] by saying String TAG= yourclassname.class.getsimpleName();
and use it in Log.d(TAG,"any string here"+some variable in my class i want to know it's value in a particular time when app running );
i hope that i made it clear to you .
Start with the tutorials. (If you are so absolutely a beginner that you don't have a development environment set up yet, then start with Installing the SDK.)
When you use the console log facility in Android, the first argument to the logging methods is a tag, which can be used to filter logcat output. A typical programming style is:
public class Something {
private static final String TAG = "Something";
public void aMethod() {
Log.i(TAG, "Entered aMethod");
}
. . .
}
That's what TAG is.
Resource IDs are explained in the tutorial. When you define a resource in XML, Android generates a class called R with nested classes for different kinds of resources (R.id, R.string, R.layout, etc.). Each of those nested classes has a constant for each resource of that type. R.id.webbutton might be generated from a layout file that has a button with attribute android:id="#+id/webbutton". This is all explained in the tutorials.

Finding the value of the reference name to R

I am doing some debugging in my application, mainly loading custom styles from styles.xml when my custom view is given a style="#styles/CustomStyle", and attributes such as custom:attribute="custom value"
I looked into the TextView source to see how Android loads styles/attributes and I am mimicking that. However I am not being passed any of my R.styleables through some of the calls to my constructors and so I am trying to peek in there to see which resources are coming in.
I am using obtainStyledAttributes() to load these key/value pairs into a TypedArray, however I am wondering if there is an easy way to convert the R.styleable.CustomWidget_customAttribute from the int that R reads, to its referenced name.
In essence, I want LogCat to say, "We've been given R.styleable.xxx" and not "We've been given 1487214712442"
Look at this method: http://developer.android.com/reference/android/content/res/Resources.html#getResourceName(int)
Return the full name for a given resource identifier. This name is a single string of the form "package:type/entry".
You most likely are not able to do this explicitly, as all resources are stored in a generated java class with no accessible reference to the original strings.
However, your best bet is override the toString() method for the R class.
See if something like that works.
Hope this helped!

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