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()
Related
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)
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 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);
}
}
hi am using cursor adapter for my listview, my problems is when i put my application in background ,on retuning my screen is empty, in onresume i have open the database and creating cursor still i have the problem, how can i solve my problem ,pls help me .
searchCursor= dbReaderContact.rawQuery(query, null);
startManagingCursor(searchCursor);
String[] from=new String[] {ALDbAdapter.TITLE,DbAdapter.CATID,DbAdapter.LTID,DbAdapter.RK,DbAdapter.SUBTITLE};
int [] to=new int[] {R.layout.ctllist_item};
catSearchAdapter=new CategorySearchAdapter(context, R.layout.ctllist_item, searchCursor, from, to);
//////////////Adapter calss
public class CategorySearchAdapter extends SimpleCursorAdapter implements Filterable{
private Context context;
private int layout;
private ALDbAdapter dbadapter;
/**
* #param context
* #param layout
* #param c
* #param from
* #param to
*/
public CategorySearchAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout=layout;
this.context=context;
dbadapter=new ALDbAdapter(context);
try {
dbadapter.openAngiesListDb();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append("name");
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
Cursor c=null;
// c=dbadapter.getPartialNamesSearch(constraint.toString());
return c;
}
#Override
public void bindView(View v, Context context, Cursor c) {
TextView subTitle=(TextView)v.findViewById(R.id.ctlName);
TextView title=(TextView)v.findViewById(R.id.cltAssocationName);
ImageView imgIcon=(ImageView)v.findViewById(R.id.ctlLogo);
int subTitInd=c.getColumnIndex(ALDbAdapter.SUBTITLE);
int titInd=c.getColumnIndex(ALDbAdapter.TITLE);
int ltId=c.getColumnIndex(ALDbAdapter.LTID);
int ltype=c.getInt(ltId);
if(!c.getString(subTitInd).equalsIgnoreCase("")){
subTitle.setText(c.getString(subTitInd));
title.setText(c.getString(titInd));
}else{
subTitle.setText(c.getString(titInd));
}
if(ltype==1){
imgIcon.setImageResource(R.drawable.logo1);
}else if(ltype==2){
imgIcon.setImageResource(R.drawable.logo2);
}else{
imgIcon.setImageResource(R.drawable.logo3);
}
}
}
//On post i closed the cursor
///On Resume
searchCursor= dbReaderContact.rawQuery(query, null);
startManagingCursor(searchCursor);
You are talking about ListView and using SimpleCursorAdapter. Don't you think creating your own ArrayAdaptor isn't more efficient : you create a class of your own to hold the data you want from your DB request (iterate over your Cursor), then you populate an ArrayList of that class.
Then you give this ArrayList to a class which extens ArrayAdaptor. You should store the ArrayList in the ArrayAdaptor and override contructor and the public View getView(int position, View convertView, ViewGroup parent) method to create each view of your ListView.
You can google custom ListView (first result : http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/ ).
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