I'm using this sample code to populate the Spinner. Data is read from database. The selection displays correctly - in this case, it shows "Green" and "Red".
Spinner spinnerColor = (Spinner) findViewById(R.id.spinnertProfile);
mProfileDbHelper = new ProfileDbAdapter(this);
mProfileDbHelper.open();
Cursor profilesCursor = mProfileDbHelper.fetchAllProfiles();
startManagingCursor(profilesCursor);
// Create an array to specify the fields we want to display in the list
String[] from = new String[] { ProfileDbAdapter.COL_PROFILE_TITLE };
// and an array of the fields we want to bind those fields to
int[] to = new int[] { R.id.textviewColors };
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter profilesAdapter = new SimpleCursorAdapter(this,
R.layout.profile_color, profilesCursor, from,
to);
spinnerColor.setAdapter(profilesAdapter);
}
However, when I changed to use a different layout android.R.layout.simple_spinner_dropdown_item. The Spinner Text disappeared.
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter profilesAdapter = new SimpleCursorAdapter(this,
R.layout.profile_color, profilesCursor, from,
to);
profilesAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerColor.setAdapter(profilesAdapter);
See snapshots of without and with simple_spinner_dropdown_item below:
Anything I may miss?
Ok, what's happening is that when you're calling setDropDownViewResource you're replacing the layout you previously specified in the constructor. In your case R.layout.profile_color. SimpleCursorAdapter extends ResourceCursorAdapter and in the constructor sets the two layouts equal to each other.
public ResourceCursorAdapter(Context context, int layout,
Cursor c, boolean autoRequery) {
super(context, c, autoRequery);
mLayout = mDropDownLayout = layout;
mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
The issue arises when you call setDropDownViewResource and change the drop down layout. The SimpleCursorAdapter will continue to use the same resource id bindings that you specified in the constructor.
What you should do is only specify the layout in the SimpleCursorAdapter's constructor. I suggest changing your code to as follows:
String[] from = new String[] { ProfileDbAdapter.COL_PROFILE_TITLE };
int[] to = new int[] { android.R.id.text1 }; // from simple_spinner_dropdown_item
SimpleCursorAdapter profilesAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_dropdown_item, profilesCursor, from, to);
spinnerColor.setAdapter(profilesAdapter);
To get the results you want.
Basically don't use the setDropDownViewResource method. Or, if you do, and you change the resource id bindings, you'll have to call SimpleCursorAdapter#changeCursorAndColumns; however, that is probably overkill for the simple result you're trying to achieve.
VERY IMPORTANT! I almost tore my hair out trying to figure out why my code wouldn't work. For those of you who may be reading this and your code still isn't working, make sure that int[] to = new int[] {android.R.id.text1} if you're using the other android layouts (such as android.R.layout.simple_spinner_dropdown_item). The code won't work if the integer array textview is not contained in the specified layout that you're using. While debugging my code I changed a lot of things around and forgot to make sure that these matched. SO, if you define your own layout, make sure that you use a textview from that layout.
Qberticus,
Yes, you're right about the resource ID binding!!
However, if I started with android.R.layout.simple_spinner_dropdown_item, obviously the dropdown layout will show, but it is not pretty :-)
String[] from = new String[] { ProfileDbAdapter.COL_PROFILE_TITLE };
int[] to = new int[] { android.R.id.text1 }; // from simple_spinner_dropdown_item
SimpleCursorAdapter profilesAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_dropdown_item, profilesCursor, from, to);
spinnerColor.setAdapter(profilesAdapter);
But now If I started with simple_spinner_item first, then setDropDownViewResource to simple_spinner_dropdown item, it now displays exactly what I'm looking for.
String[] from = new String[] { ProfileDbAdapter.COL_PROFILE_TITLE };
int[] to = new int[] { android.R.id.text1 }; // from simple_spinner_dropdown_item
SimpleCursorAdapter profilesAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, profilesCursor, from, to);
profilesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerColor.setAdapter(profilesAdapter);
Thank you so much for your help.
Related
I am new to android and not a killer in programming. I am trying to implement a dynamic listview in which items must be added to the top, rather than getting added to the bottom by default. Is there a way to achieve this? Below is the code I used to create a dynamic listview. Please help!
private void populateListView() {
Cursor cursor = myDb.getAllRows();
startManagingCursor(cursor);
String[] fromFieldNames = new String[]
{DBadapter.KEY_FIELD1,DBadapter.KEY_FIELD2};
int[] toViewIDs = new int[]
{R.id.field1,R.id.field2};
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this,
R.layout.inner_list_view,
cursor,
fromFieldNames,
toViewIDs
);
ListView myList = (ListView) findViewById(R.id.sampleList);
myList.setAdapter(myCursorAdapter);
myCursorAdapter.notifyDataSetChanged();
}
ListViews support stacking the items from the bottom. You can either set it in the XML with android:stackFromBottom or you can set it programmatically by invoking setStackFromBottom(boolean).
I don't understand the 2nd part of your question.
you can use the "insert" method. It allows you to define position to add new items
myCursorAdapter.insert(newItem, 0);
Use a loop if you have multiple elements
I subclassed SimpleCursorAdapter for displaying a list. In my row layout file, I have 3 textView, but I just want to map the data to 2 of them. I explicitly left out txt2, but it keeps being displayed with the data on it. I can fix this by manually removing txt2 from the layout file, then all good. But just out of curiosity, what was wrong with the adapter in the fist place?
Tks.
String []from = new String[] {
DbField.FIELD1,
//DbField.FIELD2,
DbField.FIELD3
};
// Fields on the UI to which we map
int[] to = new int[] { R.id.txt1, /*R.id.txt2,*/ R.id.txt3 };
adapter = new CustomCursorAdapter(this.getActivity()
, R.layout.row_entry, null, from,
to, 0);
setListAdapter(adapter);
I have an application that has a Database of vehicles with multiple fields.
I then have a ListView in which I want to display some of the fields.
Currently I have this:
SimpleCursorAdapter vehicleAdapter = new SimpleCursorAdapter(this, R.layout.vehiclerow, vehicleCursor, new String[] {"registration"}, new int[] { R.id.vehicleRow});
And I want to put multiple values on the vehicleRow TextView for instance:
Toyota - Corolla
in which Toyota and Corolla come from separate fields of the database.
I've tried this:
SimpleCursorAdapter vehicleAdapter = new SimpleCursorAdapter(this, R.layout.vehiclerow, vehicleCursor, new String[] {"make", "model"}, new int[] { R.id.vehicleRow});
but it doesn't work.
What could be the problem?
Regards
You can only map one data field to one view with the standard adapters.
You either need to create a custom adapter to let you put two data fields.into one widget (not always trivial) or create a new rowlayout with the necessary textviews and use that with a standard adapter.
I'd go for the second option.
Create another TextView and entered its Id in the cursorAdapter.
try in this way :
String[] from = new String[]{DbManager.Title, DbManager.Date};
int[] to = new int[] { R.id.list_name_main,R.id.list_date_main};{
Adapter = new SimpleCursorAdapter(this, R.layout.row_item_by_list, c1, from, to);
//Adapter.setViewBinder(new ScoreHistoryBinder());
list_item.setAdapter(Adapter);
list_item.setOnItemClickListener(listOnItemClickListener);}
I have a listview that I want to change the font size of.
Of course, doing this works with some hardcoded data:
setListAdapter(new ArrayAdapter<SimpleCursorAdapter>(this, R.layout.list_view));
But I would like it to take my cursor, so I have
mContactList.setAdapter(adapter);
But in that case, I can't change my layout to be my list_view. Is there any way to go about this oro do I have to take my cursor data and put it into an array first.
This is where I have my adapter:
private void populateContactList() {
Cursor cursor = getContacts();
fields = new String[] { ContactsContract.Data.DISPLAY_NAME };
adapter = new SimpleCursorAdapter(this,
R.layout.entry, cursor, fields,
new int[] { R.id.contactEntryText });
mContactList.setAdapter(adapter);
}
EDIT: Got it. Turns out, I just needed to edit the contactEntryText TextView.
Maybe this will help you:
ListAdapter adapter = new SimpleCursorAdapter(
this,
android.R.layout.two_line_list_item,
mCursor,
new String[] {"String1", "String2"},
new int[] {android.R.id.text1, android.R.id.text2});
lv.setAdapter(adapter);
You could use a CursorAdapter.
for custom listviews you need to extend baseadapter link here
and make your own adapter where you can specify the layout xml to be used for each or all elements.
I'd like to populate a listview from 2 tables. Anyone know how I can achieve this? Currently what I have looks like but it only works with one adapter:
private void populate() {
todoCursor = dbNotes.getTodoKey();
startManagingCursor(todoCursor);
todo =
new SimpleCursorAdapter(
this,
R.layout.todo_list,
todoCursor,
new String[] {databaseHelper.DB_COLUMN_TODO_KEYS},
new int[] {R.id.textTodo});
setListAdapter(todo);
}
private void fillData(int i) {
Cursor notesCursor = dbNotes.retrieveAll(i, "=0");
startManagingCursor(notesCursor);
notes =
new SimpleCursorAdapter(
this,
R.layout.list_item,
notesCursor,
new String[] {databaseHelper.DB_COLUMN_SUBJECT, databaseHelper.DB_COLUMN_TIME, databaseHelper.DB_COLUMN_MESSAGE, databaseHelper.DB_COLUMN_DOW, databaseHelper.DB_COLUMN_MD},
new int[] {R.id.text1, R.id.text2, R.id.text3, R.id.textDay, R.id.textDayOfWeek});
setListAdapter(notes);
}
I'd like to populate a listview from 2 tables. Anyone know how I can achieve this?
You haven't exactly explained what you mean by "populate a listview from 2 tables".
So, depending on your definition, you could:
Use a join to create a single result set from both tables
Use my MergeCursor to concatenate adapters on your two result sets into a single adapter
Assemble a single MatrixCursor from your disparate parts that you then put into the list
There are probably other solutions as well.