Displaying an image in ListView from SQLite database - android

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);
}
}

Related

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 :)

Prevent AutoCompleteTextView from showing the result in its own box

I am using an AutoCompleteTextView to show a list of items the user can select. When the users selects an item, this selected item fills a ListView just below the AutoCompleteTextView. So far so good.
The issue: after the selection of the item out of the AutoCompleteTextView, the AutoCompleteTextView body itself (this "text-box") gets filled up with some text, which is the SimpleCursorAdapter resource (the actual text showing up is: android.widget.SimpleCursorAdapter#4107d010).
What I wish to have: I want the AutoCompleteTextView to refresh and show no text in its own body so the user can immediately type in more text and select further items out of the drop-down list.
Could you please give me a hint how I could achieve that?
Added information:
Thank you Kyle. What I did was to extend SimpleCursorAdapter to SimpleCursorAdapterNoText. I then overridden convertToString() just like you said. I didn't change BindView because I read the documentation twice but I still don't understand what I should change in BindView. Any way - This didn't save the problem - I still get the same string in the AutoComplete. Here is my code:
#SuppressWarnings("deprecation")
private void populateListView()
{
// Get all of the notes from the database and create the item list
Cursor tournamentXCursor = mDbHelper.retrieveTrounamentX(mRowId);
startManagingCursor(tournamentXCursor);
// Create an array to specify the fields we want to display in the list (only name)
String[] from = new String[] {StournamentConstants.TblX.TBL_COLUMN_X_NAME};
// and an array of the fields we want to bind those fields to (in this case just name)
int[] to = new int[]{R.id.competitor_row};
// Now create an array adapter and set it to display using our row
SimpleCursorAdapterNoText tournamentX = new SimpleCursorAdapterNoText(this, R.layout.competitor_row, tournamentXCursor, from, to);
tournamentX.convertToString(tournamentXCursor);
setListAdapter(tournamentX);
}
Anyone has a clue what I am doing wrong?
EDITED:
This is my inherited SimpleCursorAdapter class
public class SimpleCursorAdapterNoText extends SimpleCursorAdapter
{
public SimpleCursorAdapterNoText(Context context, int layout, Cursor c,
String[] from, int[] to)
{
super(context, layout, c, from, to);
// TODO Auto-generated constructor stub
}
#Override
public CharSequence convertToString(Cursor cursor)
{
//Empty string so AutoComplete shows no text
return "";
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
super.bindView(view, context, cursor);
}
}
I changed my calling code and eliminated
tournamentX.convertToString(tournamentXCursor);
I was convinced it is essential that I not only override it in my subclass but that I also use it in my calling code so the text inside the AutoComplete will be eliminated.
I am sag to say the this still didn't help - I keep on getting android.database.sqlite.SQLiteCursor#41377578 in the AutoCompleteBox just after I select one item off the AutoComplete selection list.
Thanks D.
If you simply want to clear the text when a user clicks on an item in the dropdown list, define the AutoComplete as a member variable and override it's setOnItemClickListener. Like this:
mAutoComplete.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mAutoComplete.setText("");
}
});
if you are using a simplecursoradapter to fill the textView, you will need to subclass it and override the following method. You will probably also have to override bindview.
#Override
public CharSequence convertToString (Cursor cursor){
return "";
}
You need to put the above inside your SimpleCursorAdapterNoText class, not call it from the top level code.
class extends SimpeCursorAdpaterNotText{
// ... whatever other code you have here
#Override
public CharSequence convertToString (Cursor cursor){
return "";
}
}

How to use CursorAdapter?

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..

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