Customizable input fields in an android app - android

I'm working on a project for my university about customizing an Android application on runtime.
Is it possible to include layout XML files that are actually not in the \res\layout\ folder of my android project but on an external webserver?
The idea behind this is to give me an opportunity to customize the xml-file on my webserver, e.g. adding new fields, without having to re-install/update the app.
I'll try to explain my idea with the following example:
Let's say I got an application to save and display addresses. All addresses are stored in a database. I got the fields 'name' and 'surname' in my database and displayed in the app when saving or displaying the addresses.
Now I would like to add a third field 'email' where I can enter email addresses.
My idea is to create this field in my database and add it to my layout-xml-file which is on my webserver. So I can 'link' the xml file within the app and the new field appears after refreshing the app.
Hope you guys can give me some information about how to customize my input forms on runtime, my research on the internet didnt help me out at all..
Greetz

You can't use external XML files to dynamically adjust the layout.
The documentation of LayoutInflater#inflate(XmlPullParser, ViewGroup) explains why:
Important For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
But you can create your layout dynamically in code, see e.g. Android Runtime Layout Tutorial
So you could put a file on the server that holds layout information, fetch it in your app, parse it and create the layout dynamically. It is going to be a lot of work since you would basically replicate Android's LayoutInflater. You can obviously simplify the format to just the basics that you need but it's still a lot of work that is IMHO not required.
Let's assume your layout info is just a plain text file that has name of fields
name
surname
email
You can then read it line by line and create a simple EditText for each in a way like
private View getDynamicLayout(ArrayList<String> lines) {
LinearLayout ll = new LinearLayout(this);
for (String line : lines) {
EditText et = new EditText(this);
// fill it with some text
et.setText(line);
ll.addView(ll);
}
return ll;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> layoutConfig = readConfigFromFile();
View layout = getDynamicLayout(layoutConfig);
setContentView(layout);
}
But unless you really need that, I would suggest that you update the app the regular way. It is also faster to use preprocessed layouts instead of building that info on your own.
Also take care not do heavy disk / any network access in the UI thread like in above example (reading the file). That should be done in a background task.

Thanks a lot for your help. I'll try to get through this.
The reason I can't just update the app is that the app I'm talking about is actually a CRM system used by many different companies. They all have to download the same app from the google play store.
The goal of my work is that every company can customize their input forms on their own, so there could be many different input forms (each for every company) but all using the same app.
I thought about a server that stores a file with the layout information which can be accessed by the app on runtime.
btw, since I'm not a software engineer, I don't have to write any code, I only have to describe the concept in an abstract way.. :)

Related

Is there a way to add XML code to an XML file from a Kotlin code?

The question might seem incomprehensible just from the title alone so let me elaborate on what I mean. From what little I've dabbled in HTML and JavaScript, you could add HTML lines to the HTML file from using a Javascript function in the script.js file and it would add those HTML lines you've written into the function to the HTML file on execution and it would work as if you've written it in the HTML file to begin with. That was my understanding of how it worked, at least, if I'm wrong on my assessment feel free to correct me on that matter.
Anyway, I'm wondering if we could do a similar thing in Android Studio where we can use a Kotlin function to add an XML line/attribute/command like 'app:srcCompat="#drawable/whatever"' to an XML file.
Of course the question doesn't come from a mere sense of wonder. I currently have an application with a fragment that's supposed to get some football teams from the Room database and display them in CardViews using RecyclerView. In those cards, the team's name and their logo should be displayed. I don't have logos as image files in the Room database itself, however there is a column that stores the names of the drawable files in which the team logos are stored. (For example: Team A's logo is stored in the drawable's as 'teama.png' and it has 'teama' stored in a column.)
In the Adapter class of the RecyclerView, I want to use the bind() function to put the name and the logo on the cards. What I'm expecting to do (related to my question overall) is using a function that can take a string parameter ("app:srcCompat="#drawable/teama"") and puts it to the XML file of my team item. Is this possible? I'm open to other solutions as well and can post code if requested.
Thank you for your answer beforehand.
Is there a way to add XML code to an XML file from a Kotlin code?
Yes, but not in the context of what you are asking.
What I'm expecting to do (related to my question overall) is using a function that can take a string parameter ("app:srcCompat="#drawable/teama"") and puts it to the XML file of my team item. Is this possible?
No. You cannot modify the content of a resource XML file at runtime.
From what little I've dabbled in HTML and JavaScript, you could add HTML lines to the HTML file from using a Javascript function in the script.js file and it would add those HTML lines you've written into the function to the HTML file on execution and it would work as if you've written it in the HTML file to begin with.
JavaScript, run in the browser, does not modify the HTML file on the server. It modifies the DOM: the parsed representation of the HTML that is used by the browser to render a UI on the screen.
Similarly, in Android, you will need to update the View objects — created from parsing that resource XML file — to reflect your desired name and logo. This approach is covered in books and courses on Android app development. FWIW, here is a free book of mine on the subject.
Till now this technology is not available and if it is available it's not that famous and in use

Is there a way to override getString() for resources the android framework inflates?

Is there any way to intercept the Android framework's inflation of xml resources (menus and layouts) to change the strings it uses (e.g. for attributes like android:text="#string/button_trade_commit".)
I know it's possible to override getString() as it's called from an Activity. But framework code doesn't seem to use getString(). For example, in MenuInflator.java, strings come from mContext.obtainStyledAttributes(), and obtainStyledAttributes() is final: I can't override it.
Anybody know of another way to accomplish this?
Background: I want to allow non-English-speaking users to localize my app themselves. I imagine an interface that displays the English strings and lets them enter a translation which is then used in place of the English string from then on. I can imagine also providing a "Share translations" button that uploads the translations, and then,
on the server side, incorporating them into a downloadable module that other users of the same language would get. Being able to substitute strings at runtime is the blocking piece that I can't figure out.
I don't believe you can override the systems getString() methods the way you are looking at it.
It might be worth trying to use a custom attribute and handle the work there: http://developer.android.com/training/custom-views/create-view.html#customattr
I don't think you will be able to modify the process Android uses when inflating resources the way you wanted to.
What you can do is to simply not provide any strings (android:text, etc.) in XML files. You can always obtain a reference to any element in your XML file in the code. Once you have a reference, you can provide texts in the code, taking properly localized strings from your custom framework.
I am not sure about this, but i think you can examine the source of Calligraphy library for Android. It is overriding system LayoutInflater to change the FontType, so i imagine you can do the same to change the strings.

Advice on what I should be in making an application that reads multiple .txt files

This is not a coding problem question, I just need general advice.
I am making an application that populates a listfragment with multiple text files. What I want is for the user to select the intended article they wish to read and said article will be provided for them. I have already made a master/detail esk application but it is only reading in a static array for the articles (which will later be changed to an expanding list and more dynamic method for reading in the files)
My question is this: do I make a database for the ~30-40 text files and create an onlistclick--database adapter function or should I use Assetmanager (or something else).
I am new to android programming and this is my first proper application so any suggestions that would be suitable for a novice would be much obliged.
If those text files are going to be modified very often then yes, it is a good idea to create a local database to keep them into.
On the other hand if you only need those 30-40 fixed text files and you are planning to add more just through app updates then you can simplify your life by using the assets folder. Cycle through all the files in there and use them to create the list.
Code snippet for Assets usage:
AssetManager assets = context.getAssets(); //use 'this' if you are inside an activity or 'getActivity()' if you are inside a fragment
String files[] = assets.list("folder_inside_assets"); //use assets.listFiles("folder"); if you want an array of File objects

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.

Trying to pull API into LinearLayout Android APP

I am a beginner of Android apps and am using Eclipse. I have found some larger samples of pulling APIs but I cannot find a simple one to get started with. I simply want to pull from an XML file on the web (by using an API KEY) and throw it in a LinearLayout (Vertical). I can then go from there, anyone know of any? Below is a sample of my XML:
<xmldata>
<Products>
<ProductCode>ITI-GR12</ProductCode>
<ProductName>Granada 9-3/4" Narrow Rim Platter</ProductName>
<ProductPrice>64.4000</ProductPrice>
</Products>
</xmldata>
I am assuming you are looking for mechanisms which help you to parse XML and extract data from it...Voila here is a link to get you started with different ways of doing it...
http://www.ibm.com/developerworks/opensource/library/x-android/
Good luck!
your question is not easy as you will have quite a lot of programming to achieve what you want.
Here are the steps :
read your data using sax
fill a data structure of your own (build a
class, data members will be filled by
previous parsing)
build an activity, use a layout you define to
show all UI fields you think you need
to display your data
fill the content of each view using the data
structure you filled on step 2.
If you are a beginner, I suggest you first understand steps 3 and 4, having fun with UIs, then try to understand how you could download your file, parse it and fill some data class to provide content for the views.
Regards,
Stéphane

Categories

Resources