How to use CursorAdapter? - android

I am not sure whether the question title is proper or not, but after searching a lot I am asking this.
In my SQLite table, I have the columns
1: _id 2: position 3: path
position: the position of the gridView where the Image is to set
path: the path of the SDCard having corresponding image
How would I get the image from the path and set into the GridView
GridView grid = (GridView) findViewById(R.id.play_grid_view);
DBAdapter adapter = new DBAdapter(this); //My costum adapter for databse operation
adapter.open();
Cursor cusor = adapter.getAllImages(); //returns cursor with 3 columns mentioned above
startManagingCursor(cusor);
After this what should I do?

If your position column means the position of image in grid, you can just sort your query with this column, then cursorAdapter will fill your grid according to positions set in your DB.
This is not usable, if you will skip some of gridview cells (suppose you have following positions in your database: 1,2,4 - then your this adapter will fill positions 1,2,3 as there is actually no position checking)
public class ImageCursorAdapter extends CursorAdapter {
public ImageCursorAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
String pos = cursor.getString(positionColumnIndex);
String path = cursor.getString(pathColumnIndex);
ImageView image = (ImageView)view;
image.setImageDrawable(Drawable.createFromPath(path));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = new ImageView(context);
bindView(v, context, cursor);
return v;
}
}

You are looking for the SimpleCursorAdapter. You need to customize the bindView() method by overriding to show what you want.
You could also try the CursorAdapter itself. Here is a tutorial..

Related

How to add serial number in recycling list items

I have a custom ListView and used CursorAdapter to expose data from a Cursor. One challenge I got was to add Serial number in each List Items. I know there has to be a column named "_id" and It's a primary field.
What I could do is add Serial number by grabbing up the value of "_id" column, But It was not possible because I showed all data in descending order.
Another way I tried was by declaring a variable and added 1 each time the item is created.
My Adapter class which extends CursorAdapter simply looks like this
public class BalanceInfoAdapter extends CursorAdapter {
Context context;
List<Balance> listOfBalance;
int serialNo = 0; //Declared as field
//Some constructers to initialise fields
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
serialNo+=1; //Added +1 to the variable
return LayoutInflater.from(context).inflate(
R.layout.myLayout, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
mySerialNumberTextView.setText(String.valueOf(serialNo)); //Shown Serial Number in a TextView of List Item
}
Problem
It worked fine till List Items fills the screen at first time. But as I scroll down and up, the way I mentioned above failed, because CursorAdapter recycles it's List Items as it is scrolled and Serial Number of first item became most higher.
Question
Is there any other way to add S/N in recycling List Items ? OR I can prevent this from happening in the same Adapter class.
You can use the public abstract int getPosition () method of Cursor.
For more reference click here
eg: int rowNum = cursor.getPosition();
Note: in public abstract void bindView (View view, Context context, Cursor cursor) method of CursorAdapter, cursor automatically moves to the current row.
So using cursor we can get the current row position in .
Picking up from the documentation http://developer.android.com/reference/android/widget/CursorAdapter.html#newView%28android.content.Context,%20android.database.Cursor,%20android.view.ViewGroup%29
public abstract View newView (Context context, Cursor cursor, ViewGroup parent)
cursor - The cursor from which to get the data. The cursor is already moved to the correct position.
So here cursor is already at its correct position. So you can use cursor.getPosition() method to get the correct serial number.

How change color/picture of specific one ListView row - Android?

I am trying to change only one (maybe more) ListView row based on specific condition. I have read many answers on similar questions and tons of other tutorials but I am not able to make anything.
Exactly what I want to achieve is to have row background (easier version) or row picture (I think harder version) set different than others when row from SQLite is set at specific value.
I have got Activity that extends ListActivity and I am setting the ListView adapter like this:
private void refreshList() {
mySQLiteAdapter = new MyDBAdapter(this);
mySQLiteAdapter.open();
String[] columns = { MyDBAdapter.KEY_TITLE, MyDBAdapter.KEY_GENRE,
MyDBAdapter.KEY_PRICE, MyDBAdapter.KEY_ID };
Cursor contentRead = mySQLiteAdapter.getAllEntries(false, columns,
null, null, null, null, MyDBAdapter.KEY_TITLE, null);
SimpleCursorAdapter adapterCursor = new SimpleCursorAdapter(this,
R.layout.row, contentRead, columns, new int[] {
R.id.text1, R.id.detail });
this.setListAdapter(adapterCursor);
mySQLiteAdapter.close();
}
This function is called in onCreate method and in onResume. I want to set different color/image of row where value from column MyDBAdapter.KEY_PRICE is equal to 5. The R.layout.row is my xml file with row design.
Maybe someone can help me with this? Or at least show tutorial describing it?
Simply extend SimpleCursorAdapter and override bindView():
public class MyAdapter extends SimpleCursorAdapter {
public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
if(cursor.getLong(cursor.getColumnIndex(MyDBAdapter.KEY_PRICE)) == 5)
view.setBackgroundColor(0xff00ff00);
else // this will be the default background color: transparent
view.setBackgroundColor(0x00000000);
}
}
You can try to create your custom adapter that extends on SimpleCursorAdapter and inside that, on the method bindView, you can look if the condition you look for is accomplished and make what you want on that method.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html#bindView(android.view.View, android.content.Context, android.database.Cursor)
Hope to help :)

Displaying an image in ListView from SQLite database

I'm a little stuck at the moment. I know similar questions have been asked, but I haven't been able to find anything that has helped.
I'm trying to get and image to appear in ListView from an internal database inside my android application. I have a database with 141 rows, and each row is labeled 1,2 or 3. I need a different png image (saved in my res/drawable folder) to show depending on the 1,2, or 3. Here is my current Query. Any advice would be welcome. I realize there may be a better way to display the info I need.
public void whosnext(View view) {
// || is the concatenation operation in SQLite
cursor = db.rawQuery("SELECT * FROM eventsv1 WHERE start_time > (DATETIME('now')) AND title LIKE ? ORDER BY date ASC, time DESC",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new SimpleCursorAdapter(
this,
R.layout.artist_list_item,
cursor,
new String[] {"title", "time", "date", "title3", "style"},
new int[] {R.id.title, R.id.time, R.id.date, R.id.title3, R.id.style});
setListAdapter(adapter);
}
I would write a custome CursorAdapter
public class WhosNextAdapter extends CursorAdapter
{
public WhosNextAdapter(Context context, Cursor cursor, boolean autoRequery) {
super(context, cursor, autoRequery);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
//This is were you would check your cursor for style (I think that is 1,2,3 your column)
int style = cursor.getInt(cursor.getColumnIndex("style"));
ImageView img = (ImageView) view.findViewById(R.id.yourImageViewId);
switch (style) {
case 1:
img.setImageResource(R.drawable.yourImageForStyle1);
break;
case 2:
img.setImageResource(R.drawable.yourImageForStyle2);
break;
//etc.
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//Inflate layout R.layout.artist_list_item
//Call bindView passing inflated layout, context, and cursor
//return layout
}
}
You definitely need to extend SimpleCursorAdapter and if your item layout is simple enough, the only thing you need to do is to override setViewImage() method where you simply convert provided value from the database and call setImageResource() method on the ImageView object. Then you won't have to alternate much your attached code.
public class MySimpleCursorAdpater extends SimpleCursorAdapter {
public MySimpleCursorAdpater(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
}
#Override
public void setViewImage(ImageView v, String value) {
/*your code to convert value from database to drawable resource id*/
v.setImageResource(resourceId);
}
}

Implementing a CursorAdapter to get DB rowID's of ListItems in a ListView

I'm trying to implement a CursorAdapter in my Android App. I read different tutorials and tried out different things but it won't work!
I found one question here very similar to mine but I didn't get the idea out of it.
Here's the thing:
I got a Database with multiple tables and foreign keys and so on. I wrote a (tested and working) Database including an
extension of the SQLiteHelper class to work properly. The DB-Class containts a lot of methods to get various operations
on that DB like: insert, update, delete, alter and some special needs....
My Problem is the following:
I have written a method which returns all Data containing (all rows) in the Database which i want to present
in a ListView. The returning object is a wrapped ArrayList> . I got the thing working all fine
with an ListViewAdapter but then i came to my problem which now almost drives me crazy:
The User shall click a random item in that specific list (which contains all rows from the DB) and then i want to
update that specific row in the DB with some new data the user put into a EditText box. Pretty simple task actually but I think I just don't understand the usage of the CursorAdapter.
My questions now:
What does my DB-Method have to return (or look alike) that the CursorAdapter can handle it....
How do I have to implement the Adapter that it just fulfill this one task (retrieving the correct rowID of the DB entry in the list)
Here is my method retrieving the data from the DB
public ArrayList<ArrayList<Object>> getAll()
{
ArrayList<ArrayList<Object>> allRows = new ArrayList<ArrayList<Object>>();
//Cursorobjekt haelt die Daten einer Zeile und dient dazu in diesen zu iterieren
Cursor myCursor1,myCursor2,myCursor3;
myCursor1 = db.query
( "Faecher",
new String[] { "id" , FACH_NAME, FACH_ART },
null, null, null, null, null
);
// Den Pointer an die erste Stelle ruecken
myCursor1.moveToFirst();
myCursor2 = db.query
(
"Ort",
new String[]{"id" , ORT_RAUM , ORT_GEBAEUDE},
null,null,null,null,null,null
);
myCursor2.moveToFirst();
myCursor3 = db.query
(
"Profs",
new String[]{"id", PROFS_NAME, PROFS_SNAME, FKEY_GENDER_ID},
null,null,null,null,null,null
);
myCursor3.moveToFirst();
for(int i=0; i < myCursor1.getCount(); i++)
{
ArrayList<Object> row1 = new ArrayList<Object>();
row1.add(myCursor1.getLong(0));
row1.add(myCursor1.getString(1));
row1.add(myCursor1.getString(2));
row1.add(myCursor2.getLong(0));
row1.add(myCursor2.getString(1));
row1.add(myCursor2.getString(2));
row1.add(myCursor3.getLong(0));
row1.add(myCursor3.getString(1));
row1.add(myCursor3.getString(2));
row1.add(myCursor3.getLong(3));
allRows.add(row1);
myCursor1.moveToNext();
myCursor2.moveToNext();
myCursor3.moveToNext();
}
myCursor1.close();
myCursor2.close();
myCursor3.close();
return allRows;
}
The Adapter is empty right now because my code was real crap and now looks like this hull:
public class SubjectListAdapter extends CursorAdapter
{
private LayoutInflater myInflater;
public SubjectListAdapter(Context context, Cursor c)
{
super(context, c);
}
#Override
public View newView(Context context, Cursor myCursor, ViewGroup parent)
{
return null;
}
#Override
public void bindView(View parent, Context context, Cursor myCursor)
{
}
}
I hope someone can help me out with my problem or give me a hint where I have to go to get this working.
If I understand your question correctly, it seems like your primary issue is determining which element has been clicked on within the adapter. You may need to switch from bindview and newview to just using getview. If you do, you can just add an onClicklistener to the view before getView returns it. This way, each row in the list has its own listener and can update the correct row in the db. Any particular information that the onClickListener needs to run the correct database update method (ie the rowId) can also be passed into the listener with a Tag on the view. Hope that helps.
You have to create one big query from DB and get one Cursor. You can use even ordinary sql selection like
String selectQuery = "SELECT id, " FACH_NAME", "+ FACH_NAME ", " + FACH_ART .... +" FROM Faecher INNER JOIN ....";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
to get requared cursor. Than create custom CursorAdapter with getted cursor
public class ExampleCursorAdapter extends CursorAdapter {
public ExampleCursorAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView something1 = (TextView)view.findViewById(R.id.something1);
something1.setText(cusror.getString(0));
TextView something2 = (TextView)view.findViewById(R.id.something2);
something1.setText(cusror.getString(1));
.......
viev.addOnClickListener(new OnClickListener{
public void onClick(...){
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.item, parent, false);
return v;
}
}
Method bindView(....) will be called for each raw of Cursor but it will be setted to the different position, you souldnt change it inside this method. Than just bind this adapter to your ListView by setAdapter(....) method.

How to bold specific elements from a Database using a SimpleCursorAdapter

I have a main activity that takes elements from a database and displays them in a clickable listview. I use this method to accomplish the task:
private void fillData() {
// Get all of the notes from the database and create the item list
Cursor c = RequestManager.getRequests(getApplicationContext());
startManagingCursor(c);
String[] from = new String[] { DataBase.KEY_TITLE, DataBase.KEY_BODY };
int[] to = new int[] { R.id.text1, R.id.text2 };
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
setListAdapter(notes);
}
I am wondering, is it possible to access a boolean field inside the database, and bold the specific element is the field is marked as unread? The elements are each in a textview, and are then placed in a listview.
Thanks
Edit: Used the suggestion to extend the CursorAdapter Class, but when any element in the list is bolded, the first element is also bolded. Once all the elements are marked as read, the first element goes back to unbolded. Any ideas?
public void bindView(View view, Context context, Cursor cursor) {
TextView textRequestNo = (TextView) view.findViewById(R.id.text1);
TextView textMessage = (TextView) view.findViewById(R.id.text2);
StringBuilder requestNo = new StringBuilder(cursor.getString(cursor
.getColumnIndex("requestNo")));
StringBuilder message = new StringBuilder(cursor.getString(cursor
.getColumnIndex("Message")));
textRequestNo.setText(requestNo);
textMessage.setText(message);
if (cursor.getString(cursor.getColumnIndex("Read")).equals("false"))
{
textRequestNo.setTypeface(null, Typeface.BOLD);
textMessage.setTypeface(null, Typeface.BOLD);
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final View view = mInflater.inflate(R.layout.notes_row, parent, false);
bindView(view, context, cursor);
return view;
}
Unfortunately I think you're going to have to implement your own CursorAdapter in order to achieve this functionality. It's not so bad though; you can make subclass of ResourceCursorAdapter, and then all you need to do is write your own implementation of bindView(). Inside of this implementation, you can read the Cursor to determine if you should bold the row or not.

Categories

Resources