SimpleCursorAdapter / ListAdapter with Multiple Sources - android

Is it possible to build a ListAdapter having elements come from different sources (not just one cursor).
// Build up a list of names
// Query table1.name
// Query table2.name
// Create a ListAdapter passing in the list of names.
Here's the example for creating a cursor from a single table:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[] { NAME }, new int[] {
android.R.id.text1 });
setListAdapter(adapter);
adapter.setFilterQueryProvider(m_filterQueryProvider);
if (rememberLastConstraint && m_filterQueryProvider.getConstraint() != null) {
adapter.getFilter().filter(m_filterQueryProvider.getConstraint());
}

One method would be to compile all the data for the ListView in a data structure outside the ListView adapter and then pass it to the ListView and called notify data set changed. This way you can get data from different type of sources into the ListView.

Yes. To merge cursors use MergeCursor

Related

How could I change this hardcoded data to data from my database?

I would like to change it by getting the data from the database .
public void initList(){
product = new String[]{"apple","apricot","banana","orange","nuts","pears","pineapple","watermelon"};
listProducts = new ArrayList<>(Arrays.asList(product));
adapter = new ArrayAdapter<String>(this, R.layout.list_item,R.id.txtitem, listProducts);
listView.setAdapter(adapter);
}
For lists that come from the database, you should use a CursorAdapter
public void initList() {
String[] from = new String[] { productColName };
int[] to = new int[] { R.id.txtitem };
Cursor cursor = db.query(.....);
CursorAdapter adapter = new SimpleCursorAdapter(context, R.layout.list_item, cursor, from, to, 0);
listView.setAdapter(adapter);
}
This is an easy way to handle database data for a list item with all TextViews. If you have more complex data, such as for images etc. you should create a CursorAdapter subclass and override newView() and bindView().
You can use SQLite db, which is commonly used in android apps. You can insert and retrieve the data using SQLite queries.
For your example: you can create a table consisting the names of the fruits.
You can query your database to get all the fruits and populate the list (by adding the retrieved results in to the list) and use it as you are using it now to inflate the listView.
You can use the following tutorial to know about how to create a table, insert/update an entry and retrieve data from the table.
SQLite setup and sample queries

Android SimpleCursorAdapter for generating ListView

I am using ListView in android
My data is coming from database
I Have learned SimpleCursorAdapter and this is the code from official docs
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);
All the thing i have understand successfully created the list view also but there is one doubt
what the use of last argument 0 in the constructor they have not explained. Please tell me what this last argument is doing here.
The SimpleCursorAdapter documentation explains that these are flags used to determine the behavior of the adapter:
Flags used to determine the behavior of the adapter, as per
CursorAdapter(Context, Cursor, int).
See the CursorAdapter docs for more information.
Listview from Cursor (without Loaders)
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this, // The Activity context
R.layout.list_item, // Points to the XML for a list item
cursor, // Cursor that contains the data to display
dataColumns, // Bind the data in column "text_column"...
viewIDs // ...to the TextView with id "R.id.text_view"
);
Listview from Cursor (Using Loaders)
To Asynchronously load data to the Containers(Listview or Fragments) Loaders are best approach.
// Initialize the adapter. Note that we pass a "null" Cursor as the
// third argument. We will pass the adapter a Cursor only when the
// data has finished loading for the first time (i.e. when the
// LoaderManager delivers the data to onLoadFinished). Also note
// that we have passed the "0" flag as the last argument. This
// prevents the adapter from registering a ContentObserver for the
// Cursor (the CursorLoader will do this for us!).
mAdapter = new SimpleCursorAdapter(this, R.layout.list_item,
null, dataColumns, viewIDs, 0);
The following URL describes above.
http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

How can I merge two SimpleCursorAdapters in Android?

I am using two SimpleCursorAdapters to display text and images in a row in my Listview. The problem is that when calling these Adapters two times they conflict with each other. In the end my Listview only shows the data of the SimpleCursorAdapter that I called last.
What I need to do is merge those two SimpleCursorAdapters although they use different sql databases.
Any ideas to solve this??
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reminder_list);
mDbHelper = new RemindersDbAdapter(this);
mImageHelper = new ImageAdapter(this);
mDbHelper.open();
mImageHelper.open();
fillData();
fillImages();
registerForContextMenu(getListView());
}
//
// Fills the ListView with the data from the SQLite Database.
//
private void fillData() {
Cursor remindersCursor = mDbHelper.fetchAllReminders();
startManagingCursor(remindersCursor);
// Creates an array with the task title.
String[] from = new String[] {RemindersDbAdapter.KEY_TITLE, RemindersDbAdapter.KEY_BODY};
// Creates an array for the text.
int[] to = new int[] {R.id.text1, R.id.text2};
// SimpleCursorAdapter which is displayed.
SimpleCursorAdapter reminders = new SimpleCursorAdapter(this, R.layout.reminder_row, remindersCursor, from, to);
setListAdapter(reminders);
}
//
// Fills the ListView with the images from the SQLite Database.
//
private void fillImages() {
Cursor imageCursor = mImageHelper.fetchAllImages();
startManagingCursor(imageCursor);
// Creates an array with the image path.
String[] fromImage = new String[] {ImageAdapter.KEY_IMAGE};
// Creates an array for the text.
int[] toImage = new int[] {R.id.icon};
// SimpleCursorAdapter which is displayed.
SimpleCursorAdapter images = new SimpleCursorAdapter(this, R.layout.reminder_row, imageCursor, fromImage, toImage);
setListAdapter(images);
}
You can use the MergeCursor class to expose a number of individual cursors as a single cursor. As your adapters bind different columns->widgets, you may have to write your own subclass of SimpleCursorAdapter (or just CursorAdapter) so that you can do the correct type of binding depending on the row.
how about creating your own adapter (extend BaseAdapter) , which will point to the correct data each time it needs to ?
this way you can have full control over when and where to show each item.
you can even use the 2 adapters and use them for the new adapter.
What I need to do is merge those two SimpleCursorAdapters although they use different sql databases.
If the two adapters are truly different (e.g., different row layouts), use my MergeAdapter to combine your two existing adapters into one, then use the MergeAdapter with your ListView.
However, in your case, it would appear that you simply have two Cursors with different contents, in which case superfell's answer of using MergeCursor is probably a better approach.

Android ListView update with SimpleCursorAdapter

Hey i use a listview for demonstrate entries which are stored in a database. I also have a EditText element and a button which adds the content of the EditText into the Database. To bind the view to the database content i use the SimpleCursorAdapter and following populate function:
private void populate() {
cursor = dbAdapter.getAllItems();
startManagingCursor(cursor);
String[] from = new String[] { DBAdapter.KEY_TASK };
int[] to = new int[] { android.R.id.text1 };
// Now create an array adapter and set it to display using our row
cursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, from, to);
list.setAdapter(cursorAdapter);
}
If i added a new entry, by clicking on the button i want to refresh the listview but this only works with the populate function and not with the common adapter function notifyDataSetChanged();. Do i have a bug or is this the right way to refresh a listview?
Have you seen this, tried the swap cursor method, or tried just simply calling setAdapter() again?
I had a similar issue where I could not get my list to update, and what I did was just create a refreshListView() method. Now you can call this initially from your onCreate(), AND anytime a user adds something to the DB. All it does is re-bind the listview to a cursor. With all the deprecating methods (requery()), and issues with notifyDataSetChanged(), I decided this was the easiest way.
Please refer this link...it works like charm
Update SimpleCursorAdapter while maintaining scroll position in ListView
for dynamic listview on scroll i added new item from database ..
I did mistake here ..
i was assigning new adapter for each time for same simplecursoradapter .
Instead of creating new adapter.
just use
adapter.changecursor(newcursorValue);
adapter.notifydatasetChanged();
lsMedicine1.setSelectionFromTop(lsMedicine1.getLastVisiblePosition()-20, 0);
You need to call swapcursor() before notifyDataSetChanged() on the adapter.

Listview from multiple tables?

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.

Categories

Resources