Android - store/set imageResource path in database? - android

Cursor c = dbHelper.getMostRecent();
String[] from = new String[] { "name", "data", "thumb" };
int[] to = new int[] { R.id.activityName, R.id.activityData, R.id.activityThumb };
startManagingCursor(c);
SimpleCursorAdapter activities;
activities = new SimpleCursorAdapter(this, R.layout.activitywidget, c, from, to);
setListAdapter(activities);
On the second line, I'm grabbing the name, data, and thumb from the database.
On the third line, I'm setting those values for activityName (TextView), activityData (TextView), and activityThumb (ImageView).
It works fine for "name" and "data", but I have no idea what to put for "thumb".
I have some images in /res/drawable/, but I'm not sure how to store them in the database (file path as a string? R.drawable.IMAGE_NAME as a string? Do I need to save it as raw data somehow?)
Best case scenario: I'd like to just tell each instance of activityThumb in the list what image path it should be using as its resource.
EDIT: I figured it out by creating an implementation of SimpleCursorAdaptor and overriding bindView.

R.drawable.IMAGE_NAME is an integer. You can store it into the database, but it might change on the next build and break all existing databases.
You can do an enum with 2 fields: One "external representation" string that you can store in the database and one int that represents the resource identifier. You would also need a way to restore the enum from the string representation, e.g. using a map.

I figured it out by creating an implementation of SimpleCursorAdaptor and overriding bindView.
public void bindView(View view, Context context, Cursor cursor) {
ImageView imageView = (ImageView) view.findViewById(R.id.image);
//do stuff with image here
super.bindView(view, context, cursor);
}

Related

Setting the resource of an ImageView using a CursorLoader

Sorry for such an open-ended question, but I'm new to Android and I genuinely looked all over for an answer and couldn't find anything. I'm wanting to store some sort of information that references an image in a SQLite table, and then use a SimpleCursorAdapter to move that data to an ImageView. I thought that, if I store an integer (the resource ID) and then have the adapter set to the correct view, the resource of the view would be updated to that ID, but that didn't work. Is there any other way to do what I'm wanting to do?
Thanks in advance :)
Edit 1:
This is what I'm doing right now. I'm storing the drawable's ID in the table and then setting the SimpleCursorAdapter to a View whose resource I want to be the drawable. Here's the code I use to store the info:
ContentValues values = new ContentValues();
values.put(SubwayContract.ROUTE_IMG, R.drawable.red_circle);
values.put(SubwayContract.ROUTE, "R");
values.put(SubwayContract.FINAL_STATION, "Howard-Bound");
values.put(SubwayContract.ARRIVAL_TIME, "5:24:00");
final Uri uri = mContentResolver.insert(SubwayContract.CONTENT_URI, values);
The second line stores the image ID. Here's the code I have that sets the adapter:
private final int URL_LOADER = 0;
private String[] mProjections = {SubwayContract._ID, SubwayContract.ROUTE_IMG, SubwayContract.ROUTE, SubwayContract.FINAL_STATION, SubwayContract.ARRIVAL_TIME};
private int[] mTo = {R.id._id, R.id.arrival_icon, R.id.arrival_letter, R.id.arrival_dest, R.id.arrival_time};
private SimpleCursorAdapter mAdaptor = null;
...
getLoaderManager().initLoader(URL_LOADER, null, ArrivalsFragment.this);
ListView mListView = (ListView) rootView.findViewById(R.id.arrivals_list_view);
mAdaptor = new SimpleCursorAdapter(
rootView.getContext(),
R.layout.arrivals_list_item,
null,
mProjections,
mTo,
0
);
mListView.setAdapter(mAdaptor);
The View's ID is R.id.arrival_icon, which is a View. I know that there's no error in the cursor or the loader, as everything works fine if I take out the View and ID. How can I fix this?
You can save resource Id of the image (which is in drawable folder) into database.
You can try as below:
int resID = mContext.getResources().getIdentifier(image_name, "drawable", mContext.getPackageName());

Linking listview to sqlite database

Here is what I am trying to do and would like some advice on the best methods to do it:
have a database that contains a word, and the name of an image file associated with that word.
the words from the database will be displayed in a listview
when the word is selected, a new activity will start displaying the word and the image in an image view.
Would it be best to store the terms in an array and have the list view populate from this array and then pull from the database onitemclick? Or can the list view be populated with the terms from the database?
Will android be able to display the image if the name of the file is stored in the db?
The best way to achieve what you're looking for is to store the term and image path in the DB, then use the path to fetch the image from whatever location you have put it in.
Images can be stored in the DB, but the general consensus is that it is better to store the image outside the DB and a path to said image in the DB.
Your DB can then be as simple as three columns... "_id", "term" and "term_image".
You can do a simple query to fetch all the info at once (thus only querying the DB once).
Then use the cursor returned by that query to populate your list of terms, and onListItemClick to start a new activity to display the associated image using the path from the list that is in the same record as the term from the list.
Query to fetch data:
public Cursor fetchAllTerms() {
return mDb.query(TERMS_TABLE, new String[] { "_id", "term", "term_img" }, null, null, null, null, null);
}
Using it in your list:
mTermCursor = mDbHelper.fetchAllTerms();
getActivity().startManagingCursor(mTermCursor);
String[] from = new String[] { YourDBClass.term };
int[] to = new int[] { android.R.id.Text1 };
SimpleCursorAdapter ranks = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, mRankCursor, from, to);
setListAdapter(ranks);
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
String imagePath = mTermCursor.getString(mTermCursor.getColumnIndexOrThrow("term");
// code to start your new activity and put the image path into the bundle to be passed
}

listview display images from internet and data from sqlite

My cursor gets 3 columns of data from sqlite, 1st column is recipe name, 2nd column in recipe author and 3rd column is the url for the recipe's image. here's a portion of my code
private static final String fields[] = { "recipeID", "recipeName", "thumbnail"};
Cursor mCursor = dbAdapter.getAllTitles(); //get all titles returns the recipe name, author and thumbs
startManagingCursor(mCursor);
dataSource = new SimpleCursorAdapter(this, R.layout.recipelist, mCursor, fields,
new int[] { R.id.recipeAuthor, R.id.recipeName, R.id.recipeThumb });
setListAdapter(dataSource);
Obviously instead of displaying the recipe image, the code above just displays the url for the recipe image at R.id.recipeThumb. How can I make it display pictures from the internet instead?
The post right below the answer in this discussion might be of use to you:
Lazy load of images in ListView
You need a CustomAdapter and override the getView() method.
In the getView() method based on the Url you create a ImageView.
getView(...) {
//First Create a Drawable from the InputStream of the Url
//store this drawable locally so that you don't have to fetch it again
Drawable imgDrawable = Drawable.createFromStream(inputStream,"");
//set this in the imageView
imgView.setImageDrawable(imgDrawable);
//set this imgView in the contentview and return
}

Populating a spinner with a db query

I recently started programming for android and java development in general. Currently I train by writing a timetable app.
I want to get a list with all subjects from the db (the table also contains teacher and rooms) and put them into a spinner.
Thats the code I wrote
Cursor c = dba.fetchAllSubjects();
if (c.getCount() != 0) {
Spinner subjectSpinner = (Spinner) findViewById(R.id.newlesson_subject);
startManagingCursor(c);
String[] from = new String[]{DbAdapter.KEY_SUBJECT};
int[] to = new int[] {android.R.layout.simple_spinner_item};
SimpleCursorAdapter subjectAdapter =
new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, c, from, to);
subjectSpinner.setAdapter(subjectAdapter);
}
The problem is that when clicking on the spinner it shows a list with as much items as the db has entries, but the list doesn't show the names (you can say it's empty). So I probably messed something up with the simple cursor adapter, but I don't know what.
Thanks for your help
You're error lies in specifying the wrong Resource ID in your to integer array.
int[] to = new int[] {android.R.layout.simple_spinner_item};
You need to specify the ID of a TextView (or similarly typed view) and not the layout itself. Replace the line above with:
int[] to = new int[] { android.R.id.text1 };

Fetch all notes returns zero rows from Android notepad example

Well this is probably a stupid question with a simple answer but when using simple cursor adapter from the notepad example, I get a list of names from my database.
When I try to do it "manually" by moving the cursor over the rows and extracting the names the cursor says there is zero rows returned...
This works as per the example:
Cursor notesCursor = mDbHelper.fetchAllNotes();
startManagingCursor(notesCursor);
// Create an array to specify the fields we want to display in the list (only NAME)
String[] from = new String[]{WeightsDatabase.KEY_NAME};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.weightrows};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this, R.layout.weights_row, notesCursor, from, to);
setListAdapter(notes);
Now i'm trying to do this but it's not quite working. Is the simple cursor adapter doing something special i'm not?
//check # of rows, returns 0
int mOne = notesCursor.getCount();
//initial random string array
String[] temp = new String[100];
int i = 0;
notesCursor.moveToFirst();
do{
temp[i]=notesCursor.getString(notesCursor.getColumnIndex(WeightsDatabase.KEY_ROWID)); //crashes here
//index out of bounds
i++;
}while(notesCursor.moveToNext());
I have gotten this to work, but with returning a specific query like return all row with the name "_". What is different about returning all notes?
moveToFirst() actually returns a boolean, so you can prevent the exception from being thrown by checking the value before you attempt to read from the Cursor:
if (notesCursor.moveToFirst()) {
// do loop
}
As for why there are 0 rows, are you attempting to re-use the same cursor that you passed into the SimpleCursorAdapter, or is the code that is failing stand-alone? If you are attempting to re-use it, I would try it using a new Cursor after performing a fresh fetchAllNotes().

Categories

Resources