I am trying to take an AutoCompleteTextView and, through an OnListItemClickListener, return an ID from a database. To be more specific, I want a user to be able to type something in, click on one of the options that pops up, and then, rather than completing the typed word, the click returns an ID associated with that word to the user.
I know that, through a custom adapter, I can return an id through a Spinner, but I want a user to be able to type in what they're looking for. Is there some way to do this through AutoCompleteTextView, or does another class exist where I can do this?
Thank you!
AFIK there is no such class with both the functionalities.
You can try the following code which does that...
final AutoCompleteTextView mAutoCompleteTextView;
final ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.items));
mAutoCompleteTextView = (AutoCompleteTextView) view.findViewById(R.id.name_txt);
mAutoCompleteTextView.setAdapter(mAdapter);
mAutoCompleteTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View arg0) {
mAutoCompleteTextView.showDropDown();
}
});
Related
I have an AlertDialog with a ListView set to multiple selection on it. It also has a Button on it.
The Button open another AlertDialog that if ok'ed will remove the selected items from the data set of the ListView, and then tell the adapter of the list view that the dataset has changed with the notifyDataSetChanged() method.
This all works fine except for one thing. The ListView does not update it's content until I interact with something. Then it updates to the correct data.
This is not a big problem, but I really would like the ListView to appear correct at once, and not just after the focus has changed.
Code:
Button remove = (Button) view.findViewById(R.id.btn_remove_questions_edit_rack);
final Context con = this;
remove.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Builder warnBuild = new Builder(con);
warnBuild.setMessage(R.string.question_deletion_warning);
warnBuild.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
SparseBooleanArray checked = list.getCheckedItemPositions();
for (String s : keys)
{
int i = keys.indexOf(s);
if (checked.get(i))
{
toRemove.add(map.get(s));
map.remove(s);
}
}
keys.clear();
keys.addAll(map.keySet());
((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
list.clearChoices(); //This makes sure the selection is cleared, if it isn't, some of the other items (those that now has the index of the selected items) will be selected when the View refreshes.
dialog.dismiss();
}
});
//Negative button here, not relevant.
}
});
Where map and keys are:
final HashMap<String, QualityQuestion> map = new HashMap<>();
//I add items to the map
final ArrayList<String> keys = new ArrayList<>(map.keySet());
And toRemove is where I store the items to be removed from the actual object they are on when the ok button on the original AlertDialog is pressed.
This is how I populate my ListView in the first place:
final ListView list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
list.setAdapter(
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
keys));
I have tried things like list.invalidateViews(), list.invalidate and other things I found in questions similar to mine here on SO. But none of that made any difference. I suspect my problem to be different from theirs since my items clearly are updated, it just takes a change of focus on the original AlertDialog for the change to be visible.
How can I make the ListView show the changes in it's data source imidiatly insted of after a focus change?
By calling
((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
you get a fresh adapter which is almost certainly not identical to the anonymous adapter you used to populate your list in the first instance.
See also the documentation for ListView.getAdapter()
Returns the adapter currently in use in this ListView.
The returned adapter might not be the same adapter passed to setAdapter(ListAdapter) but might be a WrapperListAdapter.
From the point of view of this fresh adapter, the data set hasn't changed because the changes happened way before it was instantiated.
To solve your problem, make your list and your list adapter members of your activity class (or the scope where you want to keep them alive):
private ArrayList<String> keys;
private ArrayAdapter myAdapter;
private ListView list;
Then in your "onCreate()"
keys = ...; // initialization of ArrayList with the needed data
myAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
keys);
list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
list.setAdapter(myAdapter);
This way, in your "OnClickListener" you can notify "myAdapter":
keys.addAll(map.keySet());
myAdapter.notifyDataSetChanged();
Hope this helps :)
You can tweak it, by granting focus to another view, and then requesting it back:
view.requestFocus();
You can also use:
view.requestFocusFromTouch();
I created an Android app where users can save data to Google Spreedsheet using Google Form. I followed this POST which I found is very useful for me, but I'm having some trouble. I'm not able to save data of RadioButton , CheckBox, Date....To upload data we need Key-Value pair.. for TextView its easy to find as ID field is using Inspect Element, But for RadioButton , CheckBox there are multiple IDs.. How to set data for that..
Can anyone please tell me, how to make it possible??
I wanted to work with Radion Buttons, but as there are number of Id's for different radio buttons. So i just opted for "Choose from a List" in google form. There in list you will have one Id for spinner and multiple options. Take the Entry_Id from form and attached with your spinner id. Here is the code
s = (Spinner) findViewById(R.id.spinner);
list.add("Male");
list.add("Female");
ArrayAdapter<String> ad = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, list);
ad.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(ad);
s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
result = list.get(position);
Toast.makeText(getApplicationContext(), "you selected:" + result, Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
And in Your Post() method add this lines
gender = String.valueOf(s.getSelectedItem()); String data ="entry_1008323309=" + URLEncoder.encode(gender);
Hope this Will help you out.
This is the code I'm using:
MultiAutoCompleteTextView selectedCities = (MultiAutoCompleteTextView)findViewById(R.id.citiesSelected);
String[] cities = getResources().getStringArray(R.array.cities);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,cities);
selectedCities.setAdapter(adapter);
selectedCities.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
but when i want to add items it is possible to add any string not from my list...
I dont want to use Alert Dialog with MultiChoiceItems since I have more than 200 items on my list.
Thanks!!
I know this is an old question but if you still have this problem, you can do this in at least two ways:
You can add an onFocusChangeListener and then perform your
validation inside of that.
You can have your activity implement TextWatcher and
then override:
#Override
public void afterTextChanged(Editable s) {
// validation code goes here
}
About the last one, take a look at this question: Android: How can I validate EditText input?.
I have the following code that starts a listview with 100 options. Also it activates the software keyboard, for easy-searching of the options. If i choose an option, the position of the selected option stores in the string array items[]. The problem is that when i search an option by keyword, select it and then go back, it points at the current position not at the current value.
How to prevent this?
public class MyListActivity extends ListActivity {
String[] items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
ListView lView = getListView();
lView.setChoiceMode(2);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
lView.setTextFilterEnabled(true);
items = getResources().getStringArray(R.array.items1);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_checked, items));
}
public void onListItemClick(ListView lv, View v, int position, long id) {
lv.setItemChecked(position, lv.isItemChecked(position));
String selectedValue = (String) getListAdapter().getItem(position);
Toast.makeText(this, selectedValue, Toast.LENGTH_SHORT).show();
}
}
I think that you should create your own custom Adapter , and then in that adapter just simply override the getItem(int position) function to return the value that you need. If u haven't done it before then check out for instance this tutorial
As it turns out, having a filterable adapter doesn't play well with any choice mode (single or multiple). The only solution to this is to manually maintain the state of the selected items (a set or a list of strings in your case), and then simply loop through it every time you change the filter, in order to select the items you need. This has already been described in great detail here: Multiple Choice Searchable ListView
You obviously can't use the setTextFilterEnabled() method for this, you simply need to add an EditText in your layout and then set a TextWatcher on that in order to get all the necessary callbacks.
I want to get a random list item from a list on click of button in android. Can someone guide me to a tutorial or example where I can find how this can be done, or if someone has already done something like this can i see a sample code. I'm clueless as how to get by it. Need help.
public class RandomActivity extends Activity {
String arr[]={"A","B","C","D","E"};
ListView list;
p v onCreate(Bundle saved) {
list = (ListView)findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,arr);
list.setAdapter(adapter);
}
public void onRandom(View v){
list.getAdapter().getItem(new Random().nextInt(list.getCount()));
}
}
Still not getting the size() method so i substitutedit with getCount().But not generating a random value;
Use the Random class (http://developer.android.com/reference/java/util/Random.html)
list.get(new Random().nextInt(list.size()))
Since Kotlin 1.3:
list.random()
If the list is empty, it will throw NoSuchElementException. Docs
If you can't use Kotlin, then #tom's answer is your way to go.