Android how to create a nested menulist - java

I want to create a menulike app where each page is a subcategory of the previous selection and the last page shows the nutrition factor of the selected item, I have already created all the arrays in the arrays.xml :
<string-array name="food_values">
<item>Veggies</item>
<item>Fruits</item>
...
<item>
</string-array>
<string-array name="veg_values">
<item>Cucumber</item>
<item>Celery</item>
...
</string-array>
<string-array name="fruit_values">
<item>Apple</item>
<item>Banana</item>
...
</string-array>
I wanted to create a listview and use set onclicklistener to the list to open the next subcategory but I don't know how to implement it without using a lot of if and else statements and also generating the next listview with the same template list_item.xml.
I also tried Maps but it got too complicated with the nested lists.
Thank you for your help

Related

Localization does not work for string array in android application

I have defined a string array in my values folder in this way for default English language
<string-array name="movie">
<item>11001#Action#1</item>
<item>11002#Animation#1</item>
<item>11003#Comedy#1</item>
<item>11004#Documentary#1</item>
<item>11005#Family#1</item>
<item> 11006#Film-Noir#1</item>
<item>11007#Horror#1</item>
<item>11008#Musical#1</item>
<item>11009#Romance#1</item>
</string-array>
My applicaiton is suported for many language like chainese simplified thats why i have defined another string-array in values-zh-rCN/string.xml for chainese simplified langue like this way
<string-array name="movie">
<item>11001#动作片#1</item>
<item>11002#动画片#1</item>
<item>11003#喜剧#1</item>
<item>11004#记录片#1</item>
<item>11005#家庭#1</item>
<item> 11006#黑色电影#1</item>
<item>11007#恐怖片#1</item>
<item>11008#音乐剧#1</item>
<item>11009#爱情片#1</item>
</string-array>
when my app is running and seleted Default english langue shown the array data but when i have seleted phone language in chainese simplified or other langue instead of english the array data does not shown. what are the possible solutionn for these problem ?
Write your texts in string.xml as strings items, then use them into arrays.xml, example:
string.xml (English):
<string name="array_power_unit_item_00">By Watt.</string>
<string name="array_power_unit_item_01">By KiloWatt.</string>
<string name="array_power_unit_item_02">By Ampere and Volt.</string>
<string name="array_power_unit_item_03">By MilliAmpere and Volt.</string>
string.xml (Arabic):
<string name="array_power_unit_item_00">بالواط.</string>
<string name="array_power_unit_item_01">بالكيلو واط.</string>
<string name="array_power_unit_item_02">بالأمبير و الفولت.</string>
<string name="array_power_unit_item_03">بالميلي أمبير و فولت.</string>
arrays.xml:
<string-array name="arraypowerunit" translatable="false">
<item>#string/array_power_unit_item_00</item>
<item>#string/array_power_unit_item_01</item>
<item>#string/array_power_unit_item_02</item>
<item>#string/array_power_unit_item_03</item>
</string-array>
<string name="abcd">喜剧</string>
<string name="efgh">记录片</string>
<array name="array_abcd">
<item>#string/abcd</item>
<item>#string/efgh</item>
</array>
Use this method for get resource and get array from this resource.
this will work 100%
public static Resources getResourcesBasedOnLanguage(Activity activity) {
Configuration confTmp =new Configuration(activity.getResources().getConfiguration());
confTmp.locale = new Locale("EN");
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return new Resources(activity.getAssets(), metrics, confTmp);
}

ListPreference throws NullPointerException

I have a ListPreference:
<ListPreference
android:entries="#array/frequencies"
android:entryValues="#array/frequencies_values"
android:key="pref_key_frequencies"
android:summary="#string/frequency_pref_summary"
android:title="#string/frequency_pref_title" />
#array/frequencies:
<string-array name="frequencies">
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>20 minutes</item>
<item>30 minutes</item>
<item>60 minutes</item>
</string-array>
#array/frequencies_values
<integer-array name="frequencies_values">
<item>300</item>
<item>600</item>
<item>900</item>
<item>1200</item>
<item>1800</item>
<item>3600</item>
</integer-array>
The elements in the dialog are displayed correctly. However, if I try frequencyListPreference.setValueIndex(0); I get a NullPointerException.
Even if I do nothing in my code, if I click on one of the elements of the list, I get:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
If I check the value of one of the elements of the array frequencyListPreference.getEntryValues() is always null.
What am I doing wrong?
To my knowledge, Android will only accept String arrays instead of an Integers.
Change
<integer-array name="frequencies_values">
<item>300</item>
<item>600</item>
<item>900</item>
<item>1200</item>
<item>1800</item>
<item>3600</item>
</integer-array>
To
<string-array name="frequencies_values">
<item>300</item>
<item>600</item>
<item>900</item>
<item>1200</item>
<item>1800</item>
<item>3600</item>
</string-array>
In your code where you read from the Preference, use Integer.parseInt() to convert the value to a usable integer.
See the follow for more detail: ListPreference: use string-array as Entry and integer-array as Entry Values doesn't work

How do I create a navigation drawer with non english items?

This code is stored in res/values/strings.xml
<string-array name="planets_array">
<item>एक काम</item>
<item>दो काम</item>
<item>तीन काम</item>
<item>चार काम</item>
</string-array>
The array will be passed onto ArrayAdapter which will be used in Navigation Drawer.
However, I want these Items to be referenced using an english name.
EDIT
This code was done according to changes suggested by Dave.
<resources>
<string name="Mercury">एक काम</string>
<string name="Venus">दो काम</string>
<string name="Earth">तीन काम</string>
<string name="Mars">चार काम</string>
<string name="app_name">Navigation Drawer Example</string>
<string-array name="planets_array">
<item>#string/Mercury</item>
<item>#string/Venus</item>
<item>#string/Earth</item>
<item>#string/Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
</string-array>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string name="action_websearch">Web search</string>
<string name="app_not_available">Sorry, there\'s no web browser available</string>
</resources>
When I tap on first four items, the respective images of planets dont show up in Navigation drawer but when I tap on last 4 Items (Starting from Jupiter) , It works fine
You can set the name attribute for each item but you will have to parse the strings.xml file and use getValue from the available set of attributes. Check this SO question out :
Get name attribute of item of string array
I haven't had the time to try this though.
It's already answered here.
As the Android reference says:
<item>
...
The value can be a reference to another string resource.
...
Solution:
First, you have to write simple string elements with your english name:
<string name="english_planet_1_name">एक काम</string>
<string name="english_planet_2_name">दो काम</string>
<string name="english_planet_3_name">तीन काम</string>
<string name="english_planet_4_name">चार काम</string>
And then you can reference them everywhere, even from string-array items:
<string-array name="planets_array">
<item>#string/english_planet_1_name</item>
<item>#string/english_planet_2_name</item>
<item>#string/english_planet_3_name</item>
<item>#string/english_planet_4_name</item>
</string-array>
Finally you get both: your planet local names and their english reference name.

Why does reversing the order of declaration in string arrays in strings.xml change things?

My arrays are declared like so in my strings.xml file:
<string-array name="metal_array">
<item >Copper</item>
<item >Aluminum</item>
</string-array>
<string-array name="temperature_array">
<item >60C°, 140F°</item>
<item >75C°, 167F°</item>
<item >90C°, 194F°</item>
</string-array>
and adapters added in the onCreate() method of the activity:
Spinner metalSpinner = (Spinner) findViewById(R.id.metal_spinner);
ArrayAdapter<CharSequence> metalAdapter = ArrayAdapter.createFromResource(this, R.array.metal_array, android.R.layout.simple_spinner_item);
metalAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
metalSpinner.setAdapter(metalAdapter);
Spinner temperatureSpinner = (Spinner) findViewById(R.id.temperature_spinner);
ArrayAdapter<CharSequence> temperatureAdapter = ArrayAdapter.createFromResource(this, R.array.temperature_array, android.R.layout.simple_spinner_item);
temperatureAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
temperatureSpinner.setAdapter(temperatureAdapter);
Without any changes to the activity.xml file, simply switching the order that the two arrays are declared in the strings.xml file reverses which spinner the array is placed into. This makes no sense to me, since everything is referenced by name. Any thoughts?
Arrays XMLs are getting compiled into class files where their names getting turned into integer based IDs. When you changed the order, they get recompiled and elements get new IDs. For you out come is, any class files using old IDs will behave in funny ways.

How to set the Default Value of a ListPreference

i need to set the defult value for a ListPreference when the Activity starts.
I've tried with ListPreference.setDefaultvalue("value"); but it makes the firts Entry of the List as default. I need it because i must check a condition and set as default the value which satisfies that condition, so I think it can't be done from the xml file (with android:defaultValue)
For example, suppose I have this array of values in the arrays.xml:
<string-array name="opts">
<item>red</item>
<item>green</item>
<item>blue</item>
</string-array>
<string-array name="opts_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
In the PreferenceScreen xml:
<ListPreference
android:title="Colour select"
android:summary="Select your favourite"
android:key="colour"
android:entries="#array/opts"
android:entryValues="#array/opts_values" />
In the Activity I'd like to do something like this:
String mycolour;
if (something) {
mycolour="1";
} else {
mycolour="2";
}
ListPreference colour = (ListPreference) findPreference ("colour");
colour.setDefaultValue(mycolour);
But it doesn't work, because it makes the first choice as default. Could you explain me how to make another one as default? Thanks.
You don't need to programmatically handle the default value of ListPreferences. You can do this in xml setting file. Below is an example
<string-array name="opts">
<item>red</item>
<item>green</item>
<item>blue</item>
</string-array>
<string-array name="opts_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
...
<ListPreference
android:title="Colour select"
android:summary="Select your favourite"
android:key="colour"
android:entries="#array/opts"
android:entryValues="#array/opts_values"
android:defaultValue="2" />
here I selected 2 as a default value. Remember defaultvalue will be opts_values element.
Have you tried:
setValueIndex(int index);
Sorry my bad English.
List item
Retrieve the list Check if the value is null. If it is null set to the default value.
Code:
ListPreference dataPref = (ListPreference) findPreference("keyList");
if(dataPref.getValue() == null){
dataPref.setValueIndex(0); //set to index of your deafult value
}
You can set your default value by using the key like this
<string-array name="syncFrequency">
<item name="1">Block All Calls</item>
<item name="2">Block Black List</item>
<item name="3">Block Unknown Calls</item>
<item name="4">Allow White List</item>
<item name="5">Receive All Calls</item>
</string-array>
<string-array name="syncFrequencyValues">
<item name="1">Block_All_Calls</item>
<item name="2">Block_Black_List</item>
<item name="3">Block_Unknown_Calls</item>
<item name="4">Allow_White_List</item>
<item name="5">Receive_All_Calls</item>
</string-array>
<ListPreference
android:key="prefSyncFrequency"
android:entries="#array/syncFrequency"
android:summary="%s"
android:defaultValue="Block_Black_List"
android:entryValues="#array/syncFrequencyValues"
android:title="#string/call_block_options" />
or you can also try colour.setValue(mycolour);
Just for the record if someone else has this problem:
setValueIndex(int X) is setting the value # index X to the default value - so it is probably what you are looking for.
Set this value AFTER you added the Values! (stupid mistake but took me half an hour)
Actually it's because the SharedPreferences will persist after you re-build the app.
Uninstall it and try again.
((ListPreference) findPreference("pref_language")).setValue(Locale
.getDefault().getLanguage());
setValue() is ListPreference's method, and setDefaultvalue is Preference's method
This is an old post, but here's another way to set the default value for ListPreference with the following line of code:
PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
Use the xml attribute android:defaultValue="<VALUE>" in your list tag to set the default value.
Note: the <VALUE> is the actual value and not the index of string
array.
If still its not working, try below steps.
Clear application data.
Uninstall and reinstall the app
Check the list preference, you will see the default value selected
Strange, I know but it worked in my case.
If you are using Android Jetpack Preference, known as androidx.preference:preference-ktx:1.1.1 in Kotlin, you can use:
app:defaultValue="<Value_in_string-array_with_values>".
Additionally: defaultValue is not an index number, is the actual value from the values array.
I also recommend using a string resource for the default value and clearing the data, uninstalling the app, or removing the file:
<package_name_in_app_manifest>_preferences.xml in data/data/shared_prefs/<package_name_in_app_manifest>. Replace <package_name_in_app_manifest> with real name like com.example.yourapp.
I was having the same issue and the defaultValue wasn't updating because it already had a wrong default value of "true". Solved it by using the Android Studio File Explorer and deleting the file.
And here is my solution example:
res/xml/root_preferences.xml
<ListPreference
app:key="mic"
app:title="#string/select_mic_title"
app:useSimpleSummaryProvider="true"
app:entries="#array/mic_entries"
app:entryValues="#array/mic_values"
app:defaultValue="#string/default_mic"
 />
res/values/arrays
<!-- Mic Preference -->
<string-array name="mic_entries">
<item>#string/default_mic</item>
<item>Headband</item>
</string-array>

<string-array name="mic_values">

 <item>#string/default_mic</item>
<item>Headband</item>

</string-array>
res/strings.xml
<string name="default_mic">Integrated</string>
Result:
Setting Fragment with default list value of "Integrated" given by string resource #string/default_mic

Categories