I kind of have a 2 part question here.
1) How can I populate my ListView so that strings are what is displayed, but when items are selected, a non-visible id value (contact id from phone contacts) is the value that is actually used?
2) I have a ListView that's using multipleChoice mode for item selections. It's popluated with names from my contacts list. When I select an item in the ListView, I want that selected item to trigger a call to my SqLite routine to store the value into a database record. How do I make this event fire when an item is checked in the listview?
This is my layout XML;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/lvContacts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:choiceMode="multipleChoice"
/>
</LinearLayout>
And here is the code I am using to populate my ListView;
private void fillData() {
final ArrayList<String> contacts = new ArrayList<String>();
// Let's set our local variable to a reference to our listview control
// in the view.
lvContacts = (ListView) findViewById(R.id.lvContacts);
String[] proj_2 = new String[] {Data._ID, Phone.DISPLAY_NAME, CommonDataKinds.Phone.TYPE};
cursor = managedQuery(Phone.CONTENT_URI, proj_2, null, null, null);
while(cursor.moveToNext()) {
// Only add contacts that have mobile number entries
if ( cursor.getInt(2) == Phone.TYPE_MOBILE ) {
String name = cursor.getString(1);
contacts.add(name);
}
}
// Make the array adapter for the listview.
final ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice,
contacts);
// Let's sort our resulting data alphabetically.
aa.sort(new Comparator<String>() {
public int compare(String object1, String object2) {
return object1.compareTo(object2);
};
});
// Give the list of contacts over to the list view now.
lvContacts.setAdapter(aa);
}
I had hoped to be able to use something like the onClick event for each checked item, but have made not one bit of progress.
Any help would be so very appreciated. Thanks.
I think solution for you problem is using custom list adapter witch each item include contact name and contact ID, here is detail:
1) Try to create custom contact item bean include 2 properties: contactID, contactName
public class contactItem{
private long contactID;
private String contactName;
//...
}
Create CustomContactAdapter:
public class CustomContactAdapter extends ArrayAdapter<contactItem>{
ArrayList<contactItem> itemList = null;
//Constructor
public CustomContactAdapter (Context context, int MessagewResourceId,
ArrayList<contactItem> objects, Handler handler) {
//Save objects and get LayoutInflater
itemList = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
final ReceiveMailStruct contact= items.get(position);
if (contact!= null) {
view = inflater.inflate(R.layout.layout_display_contact_item, null);
//Set view for contact here
}
}
}
Search custom adapter for more information
2)To handler click event at ListView you must register an handler for listitem:
Step1: Register handler to List item:
lvContacts.setOnItemClickListener(new HandlerListClickEvent());
Step2: Implement proccess when item click (check/uncheck)
class HandlerListClickEvent implements OnItemClickListener {
public void onItemClick( AdapterView<?> adapter, View view, int position, long id ) {
//Get contact ID here base on item position
}
Hope it help,
Regards,
Related
I want to Convert the Languages. So i am using two Spinners one is "From Language" and Another one is for "To Language". If One Language is Selected in "From Language" Spinner, it shouldn't display (or it should be disabled) in 2nd spinner. how can i achieve it?
Ex. if i Select English in 1st Spinner, 2nd Spinner Shouldn't display English in its dropdown.
This is may not be the best way try this.
ArrayList<String> languages = new ArrayList<>();
languages.add("English");
languages.add("Hindi");
languages.add("Telugu");
languages.add("Tamil");
languages.add("Kannada");
languages.add("Malayalam");
// make a array list of languages
String option1 = null;
Spinner spinnerOption1 = (Spinner) findViewById(R.id.spinner1);
final ArrayAdapter<String> adapterOpton1 = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, languages);
spinnerOption1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerOption1.setAdapter(adapterOpton1);
spinnerOption1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
option1 = adapterOpton1.getItem(position);
}
});
int selectedIndex;
for (String item : languages) {
if (item.equals(option1)) {
selectedIndex == languages.indexOf(item);
}
}
ArrayList<String> languages2 = languages;
languages2.remove(selectedIndex);
Spinner spinnerOption2 = (Spinner) findViewById(R.id.spinner2);
final ArrayAdapter<String> adapterOption2 = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, languages2);
spinnerOption2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerOption2.setAdapter(adapterOption2);
Explanation:
lets create a arraylist with languages
bind it to the adapter on the spinner, on selection to the spinner one keep a track of that selection, then find the index of the selection in the arraylist.
create second arraylist with the same languages and find and remove the user selected item, create an adapter and bind the data.
Hope it helps.
Use Hashmaps it will be easier. Create an Adapter that uses Key Values for populating adapter.
This is a snippet I found from another link on how to do that, in case you are not familiar
public class HashMapAdapter extends BaseAdapter {
private HashMap<String, String> mData = new HashMap<String, String>();
private String[] mKeys;
public HashMapAdapter(HashMap<String, String> data){
mData = data;
mKeys = mData.keySet().toArray(new String[data.size()]);
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(mKeys[position]);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
String key = mKeys[pos];
String Value = getItem(pos).toString();
//do your view stuff here
return convertView;
}
}
Credit What adapter shall I use to use HashMap in a ListView
Now for your management of the adapters.
LanguageOneMap.put (all your keys 0-whatever) value (english-whatever)
LanguageTwoMap.put (same as above)
LanguageAllMap.put (same as above)
Adapter 1 selects Language Callback(languageSelectedFromOneKey){
LanguageTwoMap.clearAll
LanguageTwoMap.put (all again)
LanguageTwoMap.remove(languageSelectedFromOneKey)
LanguageTwoAdapter.notifyDataSetChanged()
}
The above is just pseudo code meant to give the idea, not exact copy and paste. Hope that is enough to get you going. There are many ways to skin this cat, you could even use the same list for both adapters. Then when one is selected from one or the other, set a property of "selectedOtherLanguage" in the opposite adapter, then in the GetView method if data.get(pos) == selectedFromOtherListItem return, don't draw.
Many ways to do this, just a matter of how you want to do it. Goodluck.
Quite new to Android development, can manage the more simple tasks but never dealt with databases before. I have managed to get so far, however, when trying to output all results from the databases, which has been created, i am only receiving references to the record not the actual values. Debugging shows that the values are being assigned correctly, however, are showing the object reference and not the values them selves. What i see is a list similar to:
com.example.testdb.myapplication.Films#42ff37f0
Please see below for my code:
// Getting All Films
public List<Films> getAllFilms() {
List<Films> filmList = new ArrayList<Films>();
// Select All Query
String selectQuery = "SELECT * FROM film_table";
SQLiteDatabase db = new MyDBHandler(this).getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
ArrayAdapter<Films> adapter = new ArrayAdapter<Films>(MainActivity.this, android.R.layout.simple_list_item_1,filmList);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Films film = new Films();
film.setID(Integer.parseInt(cursor.getString(0)));
film.setfilmName(cursor.getString(1));
film.setFilmActors(cursor.getString(2));
film.setFilmDirectors(cursor.getString(3));
film.setfilmDescription(cursor.getString(4));
film.setfilmFave(cursor.getString(5));
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(adapter);
filmList.add(film);
} while (cursor.moveToNext());
}
// return Film list
return filmList;
}
I would very much appreciate any input which may guide me in the right direction. I have tried many methods to no avail.
Thank you in advance.
Okay, I have to guess a little bit here because you don't have more code posted.
You say you have a list that is showing the output of the default toString() method for your Films object.
I am guessing your list adapter is using the default getView() method, since the default behavior is to print the toString() output for the item.
If you want to see the database values of your Films object formatted into a list, you have to extend a list adapter class like BaseAdapter or create a class that implements ListAdapter, then override the getView() method to create a View that contains your values.
Have a look at ListAdapter.getView() and see if that will solve your issue. If not, you'll have to post more code and be more specific about what's happening.
You are setting the adapter before you are retrieving the values from database, hence there would be no data in the adapter. Moved setting the adapter after retrieving values from DB and after setting them in Films object.
public List<Films> getAllFilms() {
List<Films> filmList = new ArrayList<Films>();
// Select All Query
String selectQuery = "SELECT * FROM film_table";
SQLiteDatabase db = new MyDBHandler(this).getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Films film = new Films();
film.setID(Integer.parseInt(cursor.getString(0)));
film.setfilmName(cursor.getString(1));
film.setFilmActors(cursor.getString(2));
film.setFilmDirectors(cursor.getString(3));
film.setfilmDescription(cursor.getString(4));
film.setfilmFave(cursor.getString(5));
filmList.add(film);
} while (cursor.moveToNext());
}
ArrayAdapter<Films> adapter = new ArrayAdapter<Films>(MainActivity.this, android.R.layout.simple_list_item_1,filmList);
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(adapter);
return filmList;
}
Also add a custom adapter to display the value from the class Film:
public class MyClassAdapter extends ArrayAdapter<Films> {
private static class ViewHolder {
private TextView filmname;
private TextView actors;
................
}
public MyClassAdapter(Context context, int textViewResourceId, ArrayList<Films> items) {
super(context, textViewResourceId, items);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(this.getContext())
.inflate(R.layout.film_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
Films item = getItem(position);
if (item!= null) {
// My layout has only one TextView
// do whatever you want with your string and long
viewHolder.itemView.setText(String.format("%s", item.getfilname));
}
return view;
}
}
Layout for the listrow(film_layout.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/filname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
.................... //Form how each row should be displayed
</RelativeLayout>
Tutorial how to create a custom listview here
Sorry i didn't post sooner. In the end i fixed the issue using the following code, which outputs into the list similar to you answer, however, without the floater element...
String[] columnName = new String[]
{MyDBHandler.COLUMN_NAME, MyDBHandler.COLUMN_ACTORS, MyDBHandler.COLUMN_DIRECTORS,MyDBHandler.COLUMN_DESCRIPTION, MyDBHandler.COLUMN_FAVE};
int[] displayName = new int[]
{R.id.filmNameEdit, R.id.filmActors, R.id.filmDirectors, R.id.filmDescription, R.id.filmFave};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.activity_listview,cursor, columnName, displayName);
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(adapter);
Thanks for all the suggestions. This turned out to be the most simple answer for me.
I have a spinner which is populated with Category objects that are retrieved from the db. The Categories table has _id and category_name columns. I want to show the category name in the spinner, but when the user selects an item, I need it to retrieve the selected item's ID. I tried the following:
Declaring variables (in class level):
int currCategoryId;
ArrayAdapter<String> adapter;
NotesManager manager = new NotesManager(this);
ArrayList<Category> arrListCategories;
ArrayList<String> arrListCategoriesString = new ArrayList<String>();
Spinner spCategories;
Instantiating them in onCreate method:
manager.getAllCategories();
arrListCategories = manager.getAllCategories();
for (int i = 0; i < arrListCategories.size(); i++)
{
Category currCategory = arrListCategories.get(i);
arrListCategoriesString.add(currCategory.getCategory_name().toString());
}
adapter=new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, arrListCategoriesString);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spCategories.setAdapter(adapter);
spCategories.setOnItemSelectedListener(spinnerListener);
And this is the spinnerListener I tried:
OnItemSelectedListener spinnerListener = new OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected.
//currCategory = (String) parent.getItemAtPosition(pos).toString();
//selectedCategory =
Category selectedCategory = (Category)spCategories.getItemAtPosition(pos);
currCategoryId = selectedCategory.getId();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
};
But in this case the app crashes and I'm getting a "
String cannot be cast to Category" at this line: Category
selectedCategory = (Category)spCategories.getItemAtPosition(pos);
I also tried this:
currCategoryId = view.getId();
But then instead of 1 or 2 (depending on what category I selected, currently I have 2 of them), I'm getting a very long number...
How can I fix it? How can I retrieve the ID of the selected object?
I would use a SimpleCursorAdapter because it stores multiple columns, instead of an ArrayAdapter that only stores one.
First change NotesManager.getAllCategories() to return a Cursor that uses:
"SELECT _id, category_name FROM Table;"
You could alphabetize the results if you want:
"SELECT _id, category_name FROM Table ORDER BY category_name;"
Next bind this Cursor straight to your Spinner:
Cursor cursor = manager.getAllCategories();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, cursor, new String[] {"category_name"}, new int[] {android.R.id.text1});
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spCategories.setAdapter(adapter);
Finally in your OnItemSelectedListener everything is ready and waiting:
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// The parameter id already refers to your Category table's id column,
}
No extra get() calls or converting Cursors into Lists necessary!
You can't use the ArrayAdapter anyway because it's for Strings only (not Categories). Hence why you're getting a casting exception. Since you have your Category ArrayList and your String ArrayList (which is used for the ArrayAdapter) in the same order, just use
Category selectedCategory = arrListCategories.get(pos);
in your onItemSelected() method
I have an array of Strings I'm populating a Spinner object with. However, I'd like to attach an ID to each element of the Spinner, so when the user selects an item, I have its ID to use to save to some other piece of data. How can I do this?
Create a class StringWithTag and use in place of the string name in the list like so :-
public class StringWithTag {
public String string;
public Object tag;
public StringWithTag(String stringPart, Object tagPart) {
string = stringPart;
tag = tagPart;
}
#Override
public String toString() {
return string;
}
}
in the add items to spinner part :-
List<StringWithTag> list = new ArrayList<StringWithTag>();
list.add(new StringWithTag("Oldman", "12345"));
list.add(new StringWithTag("Umpire", "987654"));
list.add(new StringWithTag("Squad", "ABCDEE"));
ArrayAdapter<StringWithTag> adap = new ArrayAdapter<StringWithTag> (this, android.R.layout.simple_spinner_item, list);
....
....
in the listener :-
public void onItemSelected(AdapterView<?> parant, View v, int pos, long id) {
StringWithTag s = (StringWithTag) parant.getItemAtPosition(pos);
Object tag = s.tag;
}
voila!
}
What do you mean by id. You can use ArrayAdapter to populate the Spinner. When item is selected just get the element from the adapter and save the data you want.
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<MyObject> adapter = ... // initialize the adapter
adapter.setDropDownViewResource(android.R.layout.some_view);
spinner.setAdapter(adapter);
and when item is selected
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
MyObject selected = parent.getItemAtPosition(pos);
// save any data relevant with selected item
}
If you are storing your data in db you can use CursorAdapter and in onItemSelected to fetch the selected item id from the cursor.
I don't think you can attach an arbitrary ID to elements of a text array resource, if that's what you're using.
I think the simplest way to attach such an ID would be to either hard-code (if you're using a static text resource) or dynamically build (if you get the strings at runtime) a mapping from (String position in array)->(primary key).
EDIT: On the other hand, Mojo Risin has a point - you should check to see if the CursorAdapter API already does what you need for you.
Andrew Hi, it's been a long time but it's worth to write.
You can set a tag for each row when you'r inflating spinnerLayout in SpinnerAdapter:
spinnerView = inflater.inflate(spinnerLayout, parent, false);
spinnerView.setTag("Your Tag");
And then you can get the tag with:
yourSpinner.getSelectedView().getTag();
I think The best solution is to add one more spinner and fill it with the ids but make the visibility of it to gone
I've been reading stuff about this for hours and still haven't figured out how to do it.
I managed to populate a spinner from a cursor reading the database and now I'm trying to get the selected item on the spinner to help fill a listview.
Here's my code:
Cursor cursorpf = DatabaseHelper.getPFunc();
startManagingCursor(cursorpf);
Spinner spinnerpf = (Spinner) findViewById(R.id.spinner1);
String[] frompf = new String[] { "Designacao" };
int[] topf = new int[] { android.R.id.text1 };
SimpleCursorAdapter scaPFunc = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, cursorpf, frompf, topf);
scaPFunc
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerpf.setAdapter(scaPFunc);
spinnerpf.setOnItemSelectedListener(new MyOnItemSelectedListener());
final String stringpf = MyOnItemSelectedListener.getSelected();
long id = spinnerpf.getSelectedItemId();
String stringpf = String.valueOf(id);
DatabaseHelper.setPF(stringpf);
MyOnItemSelectedListener class:
public class MyOnItemSelectedListener implements OnItemSelectedListener {
private static String selected = "";
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
selected = String.valueOf(id);
Toast.makeText(parent.getContext(), "Escolha: " + selected, Toast.LENGTH_LONG).show();
}
#SuppressWarnings("unchecked")
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
The toast on this class returns the cursor position. Now, I know I must compare it against the database to get the value I want, but I just can't do it. Would you please help me out?
Thanks in advance.
Edit:
Guys, would you help me out?
I managed to get the selected item by implementing the code above, but it happens that the listview is only filled when the app starts. When I select something on the spinner, nothing happens. :|
If you want to retrieve selected item from database, just pass the fourth argument of onItemSelected (id) to you SQL query. It's the row id of the record, aka _ID.