I am trying to make place dropdowns for user locations in my app. I'm using Exposed Drop-Down Menu not spinners. I've set it up so that depending on which country you have your self set to, it changes the next dropdown to reflect that.
this is how I do it:
val country= resources.getStringArray(R.array.nations)
val arrayadapters = ArrayAdapter(requireContext(), R.layout.country_dropdown, country)
view.autoCompleteTextView.setAdapter(arrayadapters)
view.autoCompleteTextView2.setOnClickListener {
val abc = autoCompleteTextView.text.toString()
if(abc == "canada"){
var country2= resources.getStringArray(R.array.canada)
val arrayadapters2 = ArrayAdapter(requireContext(), R.layout.locality_dropdown, country2 )
view.autoCompleteTextView2.setAdapter(arrayadapters2)
}
if (abc == "us"){
var country2 = resources.getStringArray(R.array.american_states)
val arrayadapters2 = ArrayAdapter(requireContext(), R.layout.locality_dropdown, country2)
view.autoCompleteTextView2.setAdapter(arrayadapters2)
}
}
anyways this takes what country you have selected and depending on that gives you a drop-down of all the regions within that country
the problem that I'm having is that of code scalability, I don't think It would be wise or reasonable to copy, paste and modify for each and every locality.
so my question is this. how do you set the name of the string array to a variable so I can have 1 line of code and just switch out the name of the location and have it read the string array that way.
if you're wondering the string array is XML stored int the res\values\strings.xml as something like this
<string-array name="canada">
<item>Alberta</item>
<item>British Columbia</item>
<item>Manitoba</item>
<item>New Brunswick</item>
<item>Newfoundland and Labrador</item>
<item>Nova Scotia</item>
<item>Nunavut</item>
<item>Ontario</item>
<item>Prince Edward Island</item>
<item>Northwest Territories</item>
<item>Quebec</item>
<item>Saskatchewan</item>
<item>Yukon</item>
</string-array>
thank you for reading my question, if you have any questions please ask.
Edited: this was a Java solution, since question was originally tagged as asking about Java. Don't spray language tags at random.
This is what maps are for. A sketch of an approach, rather than full code, follows.
The setup:
class CountryStuff {
Country country;
ArrayAdapter adapter;
...etc...
CountryStuff(Country c, ArrayAdapter a, ...etc...) {
country = c;
adapter = a;
...etc...
}
}
Map<String,CountryStuff> map = new HashMap<>();
map.put("canada", new CountryStuff(...whatever...);
map.put("us", new CountryStuff(...whatever...);
The use:
String abc = "something"; // country name as determined before
CountryStuff stuff = map.get(abc);
if (stuff == null) {
... no such country ...
}
else {
country2 = stuff.country;
adapter2 = stuff.adapter;
... etc ...
}
Related
I have a long string array list of "Animals" that I need to associate a code number with.
Once the "Animal" is selected via my spinner the value is stored in a variable. I also want to have the associated code number stored in its own variable.
How do I go about creating this "pairing" without writting a ton of if/then code. Can I do anything within my strings.xml file that contains my string-array?
<string-array name="Animals">
<item>Dog</item>
<item>Cat</item>
<item>Mouse</item>
...
"Dog" paired with code: "111"
"Cat" paired with code: '222"
"Mouse" paired with code:"333"
You can create the corresponding integer-array and zip them together. There is one BIG WARNING with this though, you have to make sure that if you change one of the arrays, you must update the other too!
Kotlin playground example:
fun main() {
val stringArray: Array<String> = arrayOf("Dog", "Cat")
val intArray: Array<String> = arrayOf("1", "0")
print(sArray.zip(iArray))
}
If the corresponding code is going to be only their index in the array it's simple as:
arrayOf("Dog", "Cat").mapIndexed { index, animal -> index to animal }
So with your example it would be something like this:
<string-array name="Animals">
<item>Dog</item>
<item>Cat</item>
<item>Mouse</item>
...
</string-array>
<integer-array name="AnimalsNumberCodes">
<item>111</item>
<item>222</item>
<item>333</item>
...
</integer-array>
val listOfPairs = resources.getStringArray(R.array.Animals)
.zip(
resources.getIntArray(R.array.AnimalsNumberCodes).toTypedArray()
)
To address the change in the question. All you have to do to get that lookup is to change to a map.
spinnerMap = resources.getStringArray(R.array.Animals)
.zip(
resources.getIntArray(R.array.AnimalsNumberCodes).toTypedArray()
).toMap()
spinnerMap["Dog"] // "111" or whatever you zip it with
I am using Autocomplete Text Input control of xamain. Autocomplete reference
Here is my code
var autoCompleteOptions = GetAllContacts();
ArrayAdapter autoCompleteAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleDropDownItem1Line, autoCompleteOptions);
speedSearch = FindViewById<AutoCompleteTextView>(Resource.Id.AutoCompleteInput);
speedSearch.Adapter = autoCompleteAdapter;
Problem is when i try to search in my contacts, i only get the suggested values that matches the first letter only. for example if [paul#email.com, tom#email.com,bill#xamarin.com] is the list of contacts, if i make search with "xamarin" Autocomplete does not returns anything, but if i search with "bill" it will return.
How can i change an autocompelte's behavior so that any part of string in an array item is searched, it should be returned.
You need create a custom adapter and implement IFilterable.
Here is the source code of ArrayAdapter( java codes), you can find these codes in ArrayFilter.performFiltering():
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] words = valueText.split(" ");
for (String word : words) {
if (word.startsWith(prefixString)) {
newValues.add(value);
break;
}
}
}
Note startsWith, that is why you can't get "bill#xamarin.com" while you input "xa". You need change it to Contains.
Here is a fast way to achieve your goal.
Here is a class--AutoAdapter (C# codes) which has already implemented ArrayAdapter and IFilterable.
You just need copy and paste it, and then replace:
var matches = from i in a.AllItems
where i.IndexOf(searchFor) >= 0
select i;
with:
var matches = from i in a.AllItems
where i.Contains(searchFor)
select i;
And at last, use AutoAdapter in your MainActivity:
AutoCompleteTextView textView = FindViewById<AutoCompleteTextView>(Resource.Id.autocomplete_country);
var adapter = new AutoAdapter(this, Resource.Layout.list_item, COUNTRIES);
textView.Threshold=1;
textView.Adapter = adapter;
Note:
You also need to look at performFiltering and publishResults methods in Filter class
You need to apply a filter to search amongst it and find what you want :
_adapter.Filter.InvokeFilter("your_Search");
speedSearch.Adapter = _adapter;
Put this in your text change event
In my application I want use ChipView, from this Library : https://github.com/adroitandroid/ChipCloud
In this library for set lists , I should use string[].
In my application I get lists of Tag with this code :
response.body().getData().getTags()
And Tags model is :
#SerializedName("tags")
#Expose
private List<NewsDetailTag> tags = null;
...
public List<NewsDetailTag> getTags() {
return tags;
}
In above library I should add list with this codes :
chipCloud.addChips(someStringArray);
How can I convert List to string[] in android?
Please help me guys.
There is no need for a "conversion" at all! No need to waste memory :)
Take a look at the code of the library and see, what ChipCloud.addChips() does:
public void addChips(String[] labels) {
for (String label : labels) {
addChip(label);
}
}
Its just going through the elements of the array and adding each string individually with the addChip() method.
In your code, you can do this the same way with a list:
List<NewsDetailTag> tags;
String tagString;
ChipCloud chipCloud;
// Get the tags, initialize the chipCloud, etc ...
for (NewsDetailTag tag : tags) {
tagString = tag.getTheStringFromNewsDetailTag();
chipCloud.addChip(tagString);
}
You could even write your own class that extends ChipCloud and add a method that accepts a List parameter.
The only thing thats left to do is to get a String from your NewsDetailTags. But it looks like they are serializable anyways.
try this:
String[] newList = yourList.toArray(new String[]);
hope this works
List<NewsLineTag> tags = response.body().getData().getTags();
List<String> tagStrings = new ArrayList<String>();
//add some stuff
for (NewsLineTag tag : tags) {
tagStrings.add(tag.getSomeTextValueINeed());
}
chipCloud.addChips(tagStrings.toArray(new String[0]));
getSomeTextValueINeed() should be replaced with some method which will provide you with the String you want to show.
Duplicate of Converting 'ArrayList<String> to 'String[]' in Java
Java's List has a pretty convenient toArray() method you can use to convert a List to an Array of the same type.
However, since you have a List<NewsDetailTag> you will have to build the new array yourself.
It will look something like this:
String[] strings = new String[](list.size())
for(int i = 0; i < list.size(); i++) {
array[i] = list.get(i).getStringField();
}
Where getStringField() is whatever property on NewsDetailTag contains the String you want.
Basically I have a textbox and an edittext box that looks like this:
Username [ ]
Then at the bottom there is a button called "Submit".
Simply enough, I have to type in a username, compare it to a string array that I have in my strings.xml file, and if it does not equal any of the strings in the array, then I am good to go.
The string array looks like this:
<string-array name="usernames">
<item>Bryan
<item>John</item>
<item>Matt
<item>Mike</item>
</string-array>
I am confused as to how I can do a simple if statement that in pseudo-code looks like:
if (username_entered_in_editText == usernameArray[contents])
{ submit_check = true; }
Any advice would be greatly appreciated!
Try something like this. Get an instance of your String[], get the text from your EditText with getText().toString(), and compare is to every name in the list. This isn't optimized, of course. If your String array is sorted, you could implement a binary search to make it faster, but the general theory here will work.
String[] usernames = getStringArray(R.array.usernames);
EditText editText = (EditText)findViewById(R.id.edittext);
String candidate = editText.getText().toString();
boolean submit_check = usernameTaken(candidate, usernames);
public boolean usernameTaken(String candidate, String[] usernames) {
for(String username : usernames) {
if(candidate.equals(username)) {
return true;
}
}
return false;
}
Here's the setup. I have a spinner, and each item in the spinner is associated with their own StringArray. I want to streamline the process of loading the StringArray when an item is selected in the spinner without using a bunch of if statements for each item.
The StringArray has the same name as the spinner item's text
Drawn out it would look like this:
String cat = parent.getItemAtPosition(pos).toString(); //Selected Spinner item (Category)
...
String catStringArray = "R.array." + cat;
listdata = getResources().getStringArray(catArray); //Get the StringArray
is there a way to do this correctly?
--Edit--
#EboMike
Your answer sent me on a hunt and ran into this which I'm now using:
Class res = R.array.class;
Field field = res.getField(selectedCategory);
int saId = field.getInt(null);
String[] myList = getResources().getStringArray(saId);
That's not a great approach. It's slow. It'd be better to have an internal integer array with all the R.string IDs or something similar.
If you really insist on using a string-based approach, use Resources.getIdentifier(). It's technically not a big deal if you only do it once.