create "ArrayList" in xml resource file in android - java

I know how to create a simple Array in xml like this
<resources>
<string-array name="countries_array">
<item>Afghanistan</item>
<item>Albania</item>
<item>Algeria</item>
<item>American Samoa</item>
<item>Andorra</item>
<item>Angola</item>
<item>Anguilla</item>
<item>Antarctica</item>
</string-array>
</resources>
And then I initialize it like this in code
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, countries_array);
textView.setAdapter(adapter);
But I want to store more items than just a string, so I need a way to store an arraylist rather than a simple array.
Like below
<resources>
<Share>
<name>Apple</name>
<currentRate>5.69</currentRate>
<changeToday>-0.11</changeToday>
<changeTodayPercent>-0.02</changeTodayPercent>
<timeUpdated>2012,12,06,18,00,00</timeUpdated>
<Share>
<Share>
<name>Microsoft</name>
<currentRate>5.88</currentRate>
<changeToday>0.19</changeToday>
<changeTodayPercent>+0.09</changeTodayPercent>
<timeUpdated>2012,12,06,18,00,00</timeUpdated>
<share>
...
</resources>
I already have a class called Share.java with following variables that need to be set via setMethods
public class ShareHolding {
private String name;
private double currentRate;
private double changeToday;
private double changeTodayPercent;
private GregorianCalendar timeUpdated;
}
and add them to an arraylist
ArrayList<Share> allShares = new ArrayList<Share>();
allShares.getShare(0).setName("I want to access my xml file here and add the first shares name here");

As far as I know, you won't be able to mismatch data types using the resource file. The resource only supports one-way datatypes. e.g Array of string, array of integers, etc.
The best solution that would work is to make the Share xml into it's own file and parse is into your shared object. The android developer has some example of the built in xml parser

Related

How to retrieve data from Firebase and assign to a string in strings.xml in Android Studio

I have a data in Firebase like:
-Moon1
sm_1 : "Titan"
-Moon2
sm_2 : "Europa"
-Moon3
sm_3 : "Triton"
-Moon4
sm_4 : "Io"
My strings.xml file is like below
<string name="sm_1">/*Data from firebase*/</string>
<string name="sm_2">/*Data from firebase*/</string>
<string name="sm_3">/*Data from firebase*/</string>
<string name="sm_4">/*Data from firebase*/</string>
I want the string sm_1 to have the data Titan, sm_2 = Europa and likewise. I am able to retrieve the data from Firebase and assign to a Listview.
But how to assign to a string in strings.xml?
I am fairly sure you cannot create string resources on runtime as they are compiled into your apk when you are bundling your project. What you are thinking is persisting your data from Firebase, which can be done in many ways.
You could save your instance state, create a Room database, a SQL database, use shared preferences even. However since you already seem to have a Firebase database set up maybe use that always.
It is actually possible by following codes but however, this ain't a good practice at run time. Instead, try saving strings in a variable then setting your data to adapter or etc.
In your Strings.xml:
<string name="sm_1">%1$s</string>
In Java-Kotlin side:
val yourString = "Titan" // Or you can set this from FireBase output
val formatted = getString(R.string.my_xml_string, yourString)

Edittext list editing

In my app there's a large EditText field that contains barcodes separated by "\n". Barcodes can be added to this EditText field either programmatically(in onActivityResult returning from a scanning Activity) or manually.
Random example:
010566510415
40541651654556
561516551588
0043211652
003789453
I need each of these barcodes to be saved locally with their barcode type.
Random example:
012315612323 - Code128 (scanned)
561516551588 - Custom (manually inputted)
0123156124xx - Code128_Custom (scanned, then edited by user!!)
The scanning library I use identifies the barcode types on scan, so I have an ArrayList of objects that saves the scanned barcodes with their respective barcode type.
public class BarcodeObject
{
private int _position = -1;
private String _barcode = "";
private String _barcodeType = "";
}
The problem I'm having is keeping the ArrayList<BarcodeObject> in sync with the editText, when the user manually edits a barcode.
Do you have any ideas as how I should accomplish this?
Edit 1 : Thank you for your answers. One issue is that I don't know what barcode the user is modifying. I managed to solve it by using numbersList.getSelectionStart(); to find out where the cursor is and then look for the nearest "\n" so as to identify the correct barcode(bcs all barcodes are between "\n"). But what happens if the user click selects more than one barcodes and changes them. I just don't know how to keep them in sync.
you can update the array list based of index, example :
private ArrayList<BarcodeObject> barcodes = new ArrayList<Object>();
barcodes.set(#indexposition#, #BarcodeObject#);
and add getter and setter in your BarcodeObject class, for update the object;
Assuming you have an EditText only and you want to save the data after the user stop typing...
You have to extend the class with TextWatcher and override afterTextChanged(),beforeTextChanged(), onTextChanged().
You have to write your desired logic in afterTextChanged() method to achieve functionality needed by you.
That means, in your afterTextChanged(), you can write the following code and it will work well..
bcodes.set(#position#, #Barcode-Object#);
Assuming you have already initilized bcodes...
private ArrayList<BarcodeObject> bcodes = new ArrayList<Object>();
Hope it helps. Cheers!

android reshape all resource file string

I'm working an Android app and want to translate it to Persian language.
All String values in the project are saved into an resource XML file.
Some String values are used in layout files and some in classes (R.String). When using Persian text in Android, it has to be reshaped to be displayed correctly.
I want to reshape all resource String values without calling reshape method for every String value.
Can anyone explain me how to do this?
Some idea:
override String class
override getResource class
Android provides already functionality (well documented) to have a multilanguage app. Instead of replacing your text and having severall versions of your app for each language, its better to use the frameworks function. In that case the app chooses a suitable language from the available languages you provided depending on the device locale settings.
So basically you would start by creating the required directory structure (link above):
MyProject/
res/
values/
strings.xml
values-fa/
strings.xml
and then you fill in String values into the files, e.g.:
English (default locale), /values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
Persian, /values-fa/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">...</string>
<string name="hello_world">...</string>
</resources>
(quoted and adapted from the link above)
Solution for reshape farsi language
The reshape function has to be used for every Farsi String value, so setting string in the XML layout isn't possible (AFAIK), so the following proposals assume, that all String values are set programatically.
Using a global static wrapper function #1
public static final String getLocalizedString(int resId) {
if(Locale.getDefault().toString().equals("fa_IR")) {
return PersianReshape.reshape(getResources().getString(resId));
}else{
return getResources().getString(resId);
}
You can now use this function to load the String (you have to change each occurence) or you override e.g. the getRessource method. I personally would prefer using a static function instead of overriding because of possible other problems regarding loading resources of other type than String, side effects etc.
Creating a custom class with overriding setText() for each used ui widgets #2
Another possibility is to create custom ui widgets that do a call to PersianReshape.reshape() when display. E.g. for EditText:
class CustomTextField extends EditText {
#Override
public void setText(String text) {
super.setText(PersianReshape.reshape(text));
}
}
[...]
CustomTextField myTextBox = new CustomTextField();
myTextBox.setText("....");

Identify classes at run-time

I'm working in a project for Android using libGDX framework in which I show some examples of the use of three graphic libraries. Once started, the app must show a menu with a link for each sample, its title and a little description. For the time being, I'm creating all manually, declaring a new link for each sample, but as I will have a lot of samples and I'll add new ones in each app version, I would like to identify them and generate a new entry automatically.
The samples part is composed of an abstract class called Sample and a class for each sample that extends from Sample. How could I accomplish this? The requisites will be to have the possibility to identify all samples at run-time and get information about them (name, description, etc.) without the need of create an instance previously.
My actual options are use Annotations (don't know if it is possible or if I need an external library to search for this annotations at run-time) or use something like a JSON file. What do you think is the best way (I'm open to other solutions of course) to solve this problem?
I would recomend using XML and take the class you want to create as Tag so something like this:
<root>
<sampleimplement1 name ="sampleimplement1" descript="sample1 description" ..... more attributes here... />
<sampleimplement2 name ="sampleimplement2" descript="sample2 description" ..... more attributes here... />
<sampleimplement3 name ="sampleimplement3" descript="sample3 description" ..... more attributes here... />
</root>
This can now be parsed with the XmlReader of libgdx to a Element. So the element is not the root.
Last but not least you can iterate over the childs of the root and check what the name of the Tag is. Depending on the name you create a different implementation of your Sample.
XmlReader r = new XmlReader();
Element e = r.parse(xml);//<--- the XML as string also possible as file
for (int i = 0; i < e.getChildCount(); i++)
{
Element child = e.getChild(i);
switch(child.getName()){
case "sampleimplement1":
//create sample1
break;
....
....
}

Get an integer array from an xml resource in Android program

Just a quickie,
i have an xml resource in res/values/integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer-array name="UserBases">
<item>2</item>
<item>8</item>
<item>10</item>
<item>16</item>
</integer-array>
</resources>
and ive tried several things to access it:
int[] bases = R.array.UserBases;
this just returns and int reference to UserBases not the array itself
int[] bases = Resources.getSystem().getIntArray(R.array.UserBases);
and this throws an exception back at me telling me the int reference R.array.UserBases points to nothing
what is the best way to access this array, push it into a nice base-type int[] and then possibly push any modifications back into the xml resource.
I've checked the android documentation but I haven't found anything terribly fruitful.
You need to use Resources to get the int array; however you're using the system resources, which only includes the standard Android resources (e.g., those accessible via android.R.array.*). To get your own resources, you need to access the Resources via one of your Contexts.
For example, all Activities are Contexts, so in an Activity you can do this:
Resources r = getResources();
int[] bases = r.getIntArray(R.array.UserBases);
This is why it's often useful to pass around Context; you'll need it to get a hold of your application's Resources.
get an array from xml resources of android project can be accessed.
from array.xml
<string-array name="weather_values">
<item>sunny</item>
<item>cloudy</item>
<item>rainy</item>
</string-array>
in Activity
String[] stringsArray = getApplicationContext().getResources().getStringArray(R.array.weather_values);
in Fragment
String[] stringsArray = getContext().getResources().getStringArray(R.array.weather_values);
for output in log
System.out.println("Array Values " + Arrays.toString(stringsArray));
output is
I/System.out: Array Values [sunny, cloudy, rainy]

Categories