I want to set image in my ListView, my intention is to take a string contain the address of the image (ex. "#drawable/image") from database and to set the images for the element of the LisView. I have already create a custom SimpleCursorAdapter to change the font.This is my custom SimpleCursorAdapter code:
public class CustomFontExampleAdapter extends SimpleCursorAdapter
{
private Typeface mCustomFont;
#SuppressWarnings("deprecation")
public CustomFontExampleAdapter(final Context context, final int layout, final Cursor c, final String[] from,
final int[] to) {
super(context, layout, c, from, to);
mCustomFont = Typeface.createFromAsset(context.getAssets(), "font/Pompiere-Regular.ttf");
}
#Override
public void bindView(final View view, final Context context, final Cursor cursor) {
super.bindView(view, context, cursor);
final TextView _TextViewTitle = (TextView) view.findViewById(R.id.record_nome);
_TextViewTitle.setTypeface(mCustomFont);
}
}
This is my code when i set the adapter:
d= new Database(getActivity());
final Cursor c = d.scelta();
CursorLoader(c);
String from[] = {Codice.DATI_ID,
Codice.DATI_NOME_DIETA};
int to[] = {R.id.record_id,
R.id.record_nome};
#SuppressWarnings("deprecation")
CustomFontExampleAdapter sca = new CustomFontExampleAdapter(rootView.getContext(),
R.layout.singolo_elemento,
c, from, to);
sceltadieta = (ListView) rootView.findViewById(R.id.scelta_dieta);
sceltadieta.setAdapter(sca);
after this line :
_TextViewTitle.setTypeface(mCustomFont);
Yous should go :
ImageView _ImageView = (ImageView) view.findViewById(R.id.your_image_id)
//Suppose you've already get your string(because it's not part of a question)
Drawable drawable = getResources().getDrawable(getResources()
.getIdentifier(yourStringName, "drawable", context.getPackageName()));
_ImageView.setImageDrawable(drawable)
Oh, and as far as i see you have no context in your adapter, putting context to adapter is common thing, you should past it throw constructor(as you did), and storing reference for it(create field and initialize it by context from constructor)
Related
I have a ListView that will be able to show two TextViews and an ImageView per ListViewItem. I also have a SQLite Database that has the following fields, _id, name, description, image.
An example record would be as follows:
1,R.string.name1,R.string.description1,R.drawable.image1
The strings for name and description are in the strings.xml file, and the images needed are in the res/drawable folders, which would usually be referenced by R.drawable.image_name
I am using the SQLiteAssetHelper Library to manage the database.
I am able to get a cursor containing all the information needed, and I am able to populate the listview with the text, but when I run the app, the textviews show as R.string.name1, R.string.description1, etc. I have not yet been able to get the image to work at all.
How would I get the text to show properly (so I can have different languages in the future) and how would I get the images to show?
Here is my code so far:
Database Helper
public class Database extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "database.sqlite";
private static final int DATABASE_VERSION = 1;
public Database(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
setForcedUpgrade();
}
public Cursor getList() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String [] sqlSelect = {"_id","name","description","image"};
String sqlTables = "tbl_list";
qb.setTables(sqlTables);
Cursor c = qb.query(db, sqlSelect, null, null,
null, null, null);
c.moveToFirst();
return c;
}
}
Main Activity
public class SQLite_List extends ActionBarActivity {
private ListView listView1;
private Cursor list;
private Database db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview);
getSupportActionBar().setTitle("List");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
db = new Database(this);
list = db.getList(); //Move this to its own thread later on
ListAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
mods,
new String[] {"name","description"}, //table values
new int[] {android.R.id.text1,android.R.id.text2});
listView1 = (ListView) findViewById(R.id.listview);
listView1.setAdapter(adapter);
}
...
}
Thanks
EDIT: I have written a new adapter, but the images are still not working:
public class SQLite_Adapter extends ResourceCursorAdapter {
public SQLite_Mods_Adapter(Context context, int layout, Cursor c, int flags) {
super(context, layout, c, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.txtTitle);
name.setText(cursor.getString(cursor.getColumnIndex("name")));
TextView description = (TextView) view.findViewById(R.id.txtDescription);
description.setText(cursor.getString(cursor.getColumnIndex("description")));
ImageView image = (ImageView) view.findViewById(R.id.imgIcon);
image.setImageResource(context.getResources().getIdentifier("image","drawable","com.package"));
}
}
EDIT 2: I found a solution. The answer is posted below.
Ok, I got this to work, Instead of using the SimpleCursorAdapter, use a custom adapter. Code can be found below.
Then you use the getIdentifier method to turn the name of the image or string, into an integer that can be used to setText on a TextView or setImageResource on an ImageView:
public class SQLite_ListView_Adapter extends ResourceCursorAdapter {
public SQLite_ListView_Adapter(Context context, int layout, Cursor c, int flags) {
super(context, layout, c, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.txtTitle);
String name_string=cursor.getString(cursor.getColumnIndex("name"));
int resIdName = context.getResources().getIdentifier(name_string, "string", context.getPackageName());
name.setText(resIdName);
TextView description = (TextView) view.findViewById(R.id.txtDescription);
String description_string = cursor.getString(cursor.getColumnIndex("description"));
int resIdDescription = context.getResources().getIdentifier(description_string, "string", context.getPackageName());
description.setText(resIdDescription);
ImageView image = (ImageView) view.findViewById(R.id.imgIcon);
String image_string = cursor.getString(cursor.getColumnIndex("image"));
int resId=context.getResources().getIdentifier(image_string, "drawable", context.getPackageName());
image.setImageResource(resId);
}
}
So if you had the string, R.string.name1 and you wanted that to show in the TextView, then in the name field of a record in your database, you only need name1
Similar idea with drawables and whatever else you might need
I have displaying value in list using simplecursoradapter. Nothing problem it. but how to split from [] value in simplecursoradapter in android
Means. I have in colummn this value -> John-44-2013
This value display in list. but i want to display John only.
String[] from = new String[] { column[0], column[1] };
int[] to = new int[] { R.id.colID, R.id.colDate };
TestCursorAdapter sca = new TestCursorAdapter (this,R.layout.gridrowsaveddetail, c,from, to);
public class TestCursorAdapter extends SimpleCursorAdapter {
String [] from;
int [] to;
public TestCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.from=from;
this.to=to;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title_of_list= (TextView) view.findViewById(R.id.colDate);
String temp=cursor.getString(cursor.getColumnIndex(from[1]));
String[] parse = temp.split("-");
title_of_list.setText(parse[0].trim());
super.bindView(view, context, cursor);
}
}
But not getting this. Why something wrong with this code. thank you advance.
Remove the call to super.BindView
This call will try to set the text itself, and is thereby overruling your actions.
Or, place the call at the start of the method.
I have a database where i store the names of some photos.
At onCreate() method i make a new PointofInterestAdapter:
String[] from=new String[] {"name", "address", "favorite", "type", "distance"};
int[] to = new int[] {R.id.name, R.id.address, R.id.favoriteImage, R.id.icon, R.id.distance};
//SCAdapter = new SimpleCursorAdapter(this, R.layout.row, null, from ,to, 0);
SCAdapter = new PointOfInterestAdapter(this, R.layout.row_subcategory, null, from ,to, 0);
list.setAdapter(SCAdapter);
Here is the code for making the SCAdapter:
class PointOfInterestAdapter extends SimpleCursorAdapter {
PointOfInterestAdapter(Context ctxt, int layout, Cursor c, String[] from, int[] to, int flags) {
super(ctxt,layout,c,from,to,flags);
}
#Override
public View newView(Context ctxt, Cursor c, ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row_subcategory, parent, false);
PointOfInterestHolder holder=new PointOfInterestHolder(row);
row.setTag(holder);
return row;
}
#Override
public void bindView(View row, Context ctxt, Cursor c) {
PointOfInterestHolder holder=(PointOfInterestHolder)row.getTag();
holder.populateFrom(c, databaseConnector);
}
}
static class PointOfInterestHolder {
private TextView name=null;
private TextView address=null;
private ImageView icon=null;
private ImageView favoriteImage=null;
private TextView distance=null;
PointOfInterestHolder(View row) {
name=(TextView)row.findViewById(R.id.name);
address=(TextView)row.findViewById(R.id.address);
favoriteImage=(ImageView)row.findViewById(R.id.favoriteImage);
icon=(ImageView)row.findViewById(R.id.icon);
distance=(TextView)row.findViewById(R.id.distance);
}
void populateFrom(Cursor c, DatabaseConnector databaseConnector) {
name.setText(databaseConnector.getName(c));
address.setText(databaseConnector.getAddress(c));
distance.setText(databaseConnector.getDistance(c)+" m");
//---set the image ---
String photo_name=c.getString(c.getColumnIndex("photo_name"));
int resID = getApplicationContext().getResources().getIdentifier(photo_name, "drawable", getApplicationContext().getPackageName());
//Resources res = getResources();
//Drawable drawable=res.getDrawable(R.drawable.myimage);
icon.setImageDrawable(getApplicationContext().getResources().getDrawable(resID));
//--> set favorite image
if(databaseConnector.getFavorite(c).equals("yes")) {
favoriteImage.setImageResource(R.drawable.favorite_yes);
}
else if (databaseConnector.getFavorite(c).equals("no")) {
favoriteImage.setImageResource(R.drawable.favorite_no);
}
}
}
at
populateForm(Cursor c, DatabaseConnector databaseConnector)
i try to set the image
The problem is that i get that error message:
"Cannot make a static reference to the non-static method getApplicationContext() from the type ContextWrapper"
at lines:
int resID = getApplicationContext().getResources().getIdentifier(photo_name, "drawable", getApplicationContext().getPackageName());
and here:
icon.setImageDrawable(getApplicationContext().getResources().getDrawable(resID));
How can i solve that problem ?
Thank you in advance.
As # Luksprog you will need the activity context which is passed to the constructor of your adapter class.
You have this
private Context mContext;
PointOfInterestAdapter(Context ctxt, int layout, Cursor c, String[] from, int[] to, int flags) {
super(ctxt,layout,c,from,to,flags);
mContext = ctxt;
}
Then use the context
int resID = mContext.getResources().getIdentifier(photo_name, "drawable", mContext.getPackageName());
Note
Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
More info #
http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html
This is the constructor you defined. I see you are passing context in it as a param. Use it itself
PointOfInterestAdapter(Context ctxt, int layout, Cursor c, String[] from, int[] to, int flags) {
super(ctxt,layout,c,from,to,flags);
}
you have ctxt/Context already in the constructor, Declare a local variable and store this ctxt in that. like below
class PointOfInterestAdapter extends SimpleCursorAdapter {
Static Context mCtx; // local context instance
PointOfInterestAdapter(Context ctxt, int layout, Cursor c, String[] from, int[] to, int flags) {
super(ctxt,layout,c,from,to,flags);
mCtx = ctxt; // assigning context instance in local variable
}
......................
now use mCtx where ever you using getApplicationContext()
I have a listview which populates its content from SQLite Database.
Here's my code:
ListView listView = (ListView) findViewById(R.id.lstText);
listView.setOnItemClickListener(this);
listView.setAdapter(new MySimpleCursorAdapter(this, R.layout.listitems,
managedQuery(Uri.withAppendedPath(Provider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, null, null, null),
new String[] { Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, new int[] {
R.id.txt_title, R.id.image, R.id.txt_list_desc, R.id.txt_org}));
I want to put an extra String to some TextViews above when its displayed on the list. For example, I want to add a String with the word "from" on R.id.txt_org, before the populated String from the database which is Database.Project.C_ORGANIZATIONTITLE
Let's say the populated String is: New Organisation,
with an extra String "from" what will be displayed is: from New Organisation
Can anybody help me with that? Thank you very much.
EDITED:
FYI, this is my SimpleCursorAdapter method:
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
loader = new ImageLoader(context);
this.context = context;
}
Context context=null;
ImageLoader loader = null;
public void setViewImage(ImageView v, String value) {
v.setTag(value);
loader.DisplayImage(value, context, v);
}
}
Since you're already using a custom adapter, override the adapter's bindView() and newView() methods, rather than getView(). That way you will not have to manually deal with recycling the row's view.
Within these method you can get the data from the resulting Cursor and manipulate it before binding it to your row's view.
GetView Vs. BindView in a custom CursorAdapter?
How to override CursorAdapter bindView
//Edit: some more code below. Note that this is just a rough outline and by no means complete or tested.
class MySimpleCursorAdapter extends SimpleCursorAdapter {
private ImageLoader mLoader = null;
private LayoutInflater mInflater = null;
private int mBusinessNameIndex = -1;
private int mSmallImageIndex = -1;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mLoader = new ImageLoader(context);
mInflater = getLayoutInflater();
mBusinessNameIndex = c.getColumnIndexOrThrow(Database.Project.NAME);
mSmallImageIndex = c.getColumnIndexOrThrow(Database.Project.C_SMALLIMAGE);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.row, null);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Get your views from 'view'
TextView someTextView = (TextView) view.findViewById(R.id.xxx);
ImageView someImageView = (ImageView) view.findViewById(R.id.yyy);
// Set the data
someTextView.setText("from " + cursor.getString(mBusinessNameIndex));
mLoader.DisplayImage(cursor.getString(mSmallImageIndex ), context, someImageView);
}
}
I'm trying to populate listview from my SQLite database... this is how I get my data from database:
Cursor c = database.rawQuery("SELECT * FROM " + TableName, null);
int Column1 = c.getColumnIndex("uri");
int Column2 = c.getColumnIndex("file");
int Column3 = c.getColumnIndex("id");
c.moveToFirst();
if (c != null) {
do {
String uri = c.getString(Column1);
String file = c.getString(Column2);
int id = c.getInt(Column3);
} while (c.moveToNext());
}
I would normally add an array to listview like that:
ListView my_listview2 = (ListView) findViewById(R.id.listView1);
String my_array[] = {"Android", "iPhone"};
my_listview2.setAdapter(new ArrayAdapter<String>(this, R.layout.row, R.id.my_custom_row, my_array));
How can I make an array to setadapter from my sql query?
The best way to do this is to use a CursorAdapter or a SimpleCursorAdapter. This will give you the best performance and once you figure it out you'll find it's the simplest approach when using a SQLite db.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html
Below is a simple CustomCursorAdapter that I use frequently. Just add the CustomCursorAdapter class as an inner class.
protected class CustomCursorAdapter extends SimpleCursorAdapter {
private int layout;
private LayoutInflater inflater;
private Context context;
public CustomCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.i("NewView", newViewCount.toString());
View v = inflater.inflate(R.layout.list_cell, parent, false);
return v;
}
#Override
public void bindView(View v, Context context, Cursor c) {
//1 is the column where you're getting your data from
String name = c.getString(1);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.textView);
if (name_text != null) {
name_text.setText(name);
}
}
Create an instance of the CustomCursorAdapter like so...
You'll need to create your cursor just like you're already doing.
protected String[] from;
protected int[] to;
//From is the column name in your cursor where you're getting the data
//to is the id of the view it will map to
from = new String[]{"name"};
to = new int[]{R.id.textView};
CustomCursorAdapter adapter = new CustomCursorAdapter(this, R.layout.list, cursor, from, to);
listView.setAdapter(adapter);
I found working with the notepad tutorial very useful for learning about this.
It shows you how to implement the listview using the sqlite database in very easy steps.
http://developer.android.com/resources/tutorials/notepad/index.html