Retrieve image names from sqlite - android

I have a database and I have two columns
Name of the first column: Img
Name of the second column: Name
I want to show them in Listview
There is no problem displaying names
But there is a problem with displaying pictures What is the solution?
ِAdbter Listview
public class adbter_listview extends ArrayAdapter<String> {
Activity activity;
ArrayList<Integer> icons;
ArrayList<String> name;
public adbter_listview(Activity activity, ArrayList<Integer> icons, ArrayList<String> name) {
super(activity, R.layout.custom_listview, name);
this.activity = activity;
this.icons = icons;
this.name = name;
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
View v = inflater.inflate(R.layout.custom_listview, parent, false);
ImageView iv = (ImageView) v.findViewById(R.id.imageView);
TextView tv = (TextView) v.findViewById(R.id.textView);
iv.setImageResource(icons.get(position));
tv.setText(name.get(position));
return v;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
ListView con;
ArrayList<String> icons_name = new ArrayList<>();
ArrayList<Integer> icons = new ArrayList<>();
ArrayList<String> name = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = (ListView) findViewById(R.id.con);
db connect = new db(MainActivity.this);
SQLiteDatabase read = connect.getReadableDatabase();
Cursor save = read.rawQuery("select image from game",null);
save.moveToFirst();
while(save.isAfterLast()==false)
{
icons_name.add(save.getString(0));
icons.add(R.drawable.user);
save.moveToNext();
}
adbter_listview adb = new adbter_listview(MainActivity.this,icons,name);
con.setAdapter(adb);
}
}
please help me

Get int id of drawable using this line,
int drawableResourceId = this.getResources().getIdentifier("nameOfDrawable", "drawable", this.getPackageName());
In your case
nameOfDrawable = save.getString(0); I guess
then add into icons arrayList,
icons.add(drawableResourceId);
Hope this will work.

Instead of this
icons.add(R.drawable.user);
Use
icons.add(Integer.parseInt(save.getString(1)));
in adapter it should work only if the images are from drawables folder and use it like
R.drawable.icons.get(position)
But first remove the database call from the oncreate mainThread call to a different thread. Either create a new Thread or use asynctask or use loaders. Don't make a sqlitedatabase call in mainthread.

Related

Android notifyDatasetChange with SQLite cursor how to?

So I have 2 activities.
The first (ActivityOne) displays a listview with data from SQLite cursor, and a button.
On click of that button, I want to add an item to the listview, so I display the second activity (ActivityTwo), that contains a number of editTexts and a save Button, that does the saving in the Database.
But what I want is:
after saving the new item to the DB, the ActivityTwo should close and the ActivityOne should be displayed with the refreshed content from the DB
.
This seems a reasonable workflow. How do I achieve it?
Code for ActivityOne:
public class ActivityOne extends Activity {
private ArrayList<String> idclient = new ArrayList<String>();
private ArrayList<String> numeclient = new ArrayList<String>();
private ArrayList<String> tipclient = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView mylist = (ListView) findViewById(R.id.lv_clienti);
LoadList();
Button btnex = (Button) findViewById(R.id.btnNewCli);
btnex.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View aView)
{
Toast.makeText(getApplicationContext(), "Add new client... " , Toast.LENGTH_SHORT).show();
Intent toAnotherActivity = new Intent(aView.getContext(), NewClientActivity.class);
startActivity(toAnotherActivity);
}
}
);
}
public void LoadList(){
SQLiteDatabase db = new myDbHelper(getApplicationContext()).getWritableDatabase();
Cursor mCursor = db.rawQuery("select idclient,nameclient,typeclient from clienti order by numeclient" , null);
idclient.clear();
numeclient.clear();
tipclient.clear();
if (mCursor.moveToFirst()) {
do {
idclient.add(Integer.toString(mCursor.getInt(0)));
nameclient.add(mCursor.getString(1));
typeclient.add(mCursor.getString(2));
} while (mCursor.moveToNext());
}
DisplayClientiAdapter disadpt = new DisplayClientiAdapter(ClientiActivity.this,idclient,nameclient, typeclient);
ListView lv = (ListView) findViewById(R.id.lv_clienti);
lv.setAdapter(disadpt);
mCursor.close();
db.close();
}
}
And in the ActivityTwo, I have in a button click:
db.execSQL("insert into clients (idclient, nameclient,typeclient,...");
DisplayClientiAdapter da = new DisplayClientiAdapter(getApplicationContext());
da.notifyDataSetChanged();
finish();
Also the displayAdapter is something like:
public class DisplayClientiAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> idclient;
private ArrayList<String> numeclient;
private ArrayList<String> tipclient;
public DisplayClientiAdapter(Context c){
this.mContext = c;
}
public DisplayClientiAdapter(Context c, ArrayList<String> idclient, ArrayList<String> numeclient, ArrayList<String> tipclient) {
this.mContext = c;
this.idclient = idclient;
this.numeclient = numeclient;
this.tipclient = tipclient;
}
public int getCount() {
return idclient.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.clienti_item, null);
mHolder = new Holder();
mHolder.txt_idclient = (TextView) child.findViewById(R.id.tv_cl_id);
mHolder.txt_numeclient = (TextView) child.findViewById(R.id.tv_cl_nume);
mHolder.txt_tipclient = (TextView) child.findViewById(R.id.tv_cl_tip);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.txt_idclient.setText(idclient.get(pos));
mHolder.txt_numeclient.setText(numeclient.get(pos));
mHolder.txt_tipclient.setText(tipclient.get(pos));
return child;
}
public class Holder {
TextView txt_idclient;
TextView txt_numeclient;
TextView txt_tipclient;
}
Of course it does not work like this. The list is not refreshed... I assume it has to do with the displayAdapter !?!?!
I cannot call the LoadList method since it is static or something like that...
Please help.
Thank you
Its not a problem with your adapter. You have to call Loadlist() in onresume method instead of oncreate method in ActivityOne. It will work then.
First of all, have a look at this two articles:
http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
http://www.doubleencore.com/2013/06/context/
You shouldn't inflate your views with null in your inflate method if you have parent view available.
Also, using application context for inflating may cause strange behaviour, as it may not use correct theme you may've set in app manifest for your Activity.
On the other hand - why don't you use CursorAdapter instead of BaseAdapter?
The problem with your adapter is, that you don't set the data in it! :)
///EDIT:
I checked the wrong activity - why do you create second adapter in there?
The easiest solution would be to move the LoadList() to onStart.
If you want to do it right, you should use ContentObserver and (probably) CursorAdapter.

refresh listview after data has changed from custom adapter

I have seen several posts on this but I cannot seem to follow one well enough to fix my problem.
I am trying to refresh my ListView after I update or delete a record. I am currently using notifyDataSetChanged() however it does not refresh upon deletion. I can delete, and then if i back our and reload my history.java it will show the updates because I am reloading all of the data.
here is my HistoryAdapter.java
public class HistoryAdapter extends BaseAdapter {
private Context mContext;
Cursor cursor;
history historyClass = new history();
MySQLiteHelper db;
public HistoryAdapter(Context context, Cursor cur){
super();
mContext = context;
cursor = cur;
db = new MySQLiteHelper(context);
}
public int getCount(){
// return the number of records in cursor
return cursor.getCount();
}
// getView method is called for each item of ListView
public View getView(final int position, View view, ViewGroup parent){
// inflate the layout for each item of listView
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.history_list_item, null);
// move the cursor to required position
cursor.moveToPosition(position);
final String id = cursor.getString(cursor.getColumnIndex("_id"));
final long deleteId = Long.parseLong(id);
// fetch the information for each card
String pricePerGallon = cursor.getString(cursor.getColumnIndex("pricePerGallon"));
String gallons = cursor.getString(cursor.getColumnIndex("gallons"));
String odometer = cursor.getString(cursor.getColumnIndex("odometer"));
String date = cursor.getString(cursor.getColumnIndex("date"));
String filledOrNot = cursor.getString(cursor.getColumnIndex("filledOrNot"));
String comments = cursor.getString(cursor.getColumnIndex("comments"));
//String milesPerGallon = cursor.getString(cursor.getColumnIndex("miledPerGallon"));
String totalSpent = cursor.getString(cursor.getColumnIndex("totalSpent"));
// get the reference of TextViews
TextView textViewPricePerGallon = (TextView) view.findViewById(R.id.cardPrice);
TextView textViewGallons = (TextView) view.findViewById(R.id.cardGallons);
TextView textViewOdometer = (TextView) view.findViewById(R.id.cardOdometer);
TextView textViewDate = (TextView) view.findViewById(R.id.cardDate);
TextView textViewFilledOrNot = (TextView) view.findViewById(R.id.cardFilledOrNot);
TextView textViewComments = (TextView) view.findViewById(R.id.cardComments);
//TextView textViewMilesPerGallon = (TextView) view.findViewById(R.id.mpg);
TextView textViewTotalSpent = (TextView) view.findViewById(R.id.usd);
TextView textViewDeleteButton = (TextView) view.findViewById(R.id.deleteButton);
// Set the data to each TextView
textViewPricePerGallon.setText(pricePerGallon);
textViewGallons.setText(gallons);
textViewOdometer.setText(odometer);
textViewDate.setText(date);
textViewFilledOrNot.setText(filledOrNot);
textViewComments.setText(comments);
//textViewMilesPerGallon.setText(milesPerGallon);
textViewTotalSpent.setText(totalSpent);
final HistoryAdapter historyAdapter = this;
textViewDeleteButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.d("History Adapter", "" + deleteId);
//need to delete here
deleteRecord(deleteId);
historyAdapter.notifyDataSetChanged();
}
});
return view;
}
public Object getItem(int position){
return position;
}
public long getItemId(int position){
return position;
}
private void deleteRecord(long id){
db.deleteGasLog(id);
}
}
here is my history.java which sets the adapter and creates the listview
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
context = this;
initViews();
cursor = db.getAllLogs();
// Create the Adapter
historyAdapter = new HistoryAdapter(this, cursor);
// Set the adapter to ListView
listContent.setAdapter(historyAdapter);
}
I guess you will need to get a new cursor.
Try moving this
cursor = db.getAllLogs();
into the adapter and call it again before the notifyDataSetChanged() call.
You are deleting the row but you are never updating or getting a new cursor, which has the result set the adapter uses to layout the list. You need to give the adapter a new cursor after you delete a row, then call notifyDatasetChanged(). If you use SimpleCursorAdapter
instead of BaseAdapter, you can use its swapCursor() method to set the new cursor.
Make sure to call:
registerDataSetObserver(...)
from your BaseAdapter subclass.
Pass it the reference to your DataSetObserver implementation. Possibly through an inner class of HistoryAdapter:
public class HistoryAdapter extends BaseAdapter {
. . .
public class MyDataSetObserver extends DataSetObserver {
public void onChanged() {
// Data Set changed.... do something...
}
public void onValidated() {
// Your implementation here
}
}
. . .
public HistoryAdapter(Context context, Cursor cur) {
. . .
registerDataSetObserver(new MyDataSetObserver());
. . .
}
}
HTH

Gallery widget using Lazy List

For this app I'm trying to write, the idea is that I'm going to host some pictures online and save the individual urls into a sqlite database. Then I will extract each url from the database and download the picture to be shown in a gallery widget. I read about Lazy List (kudos for the great work!) but I'm having problems implementing it. I have tried to modify the coding from Lazy List but it doesnt seem to work. I'm not sure if there is an error in my app or have I modified the Lazy List wrongly. Any help is greatly appreciated and thank you in advance! =)
Code for my app:
public class ResultDetails extends ListActivity {
protected int foodId;
protected String pic1, pic2, pic3, pic4, pic5;
LazyAdapter adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result_details);
foodId = getIntent().getIntExtra("FOOD_ID", 0);
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT _id, pic1, pic2, pic3, pic4, pic5 FROM database WHERE _id = ?", new String[]{""+foodId});
pic1 = cursor.getString(cursor.getColumnIndex("pic1"));
pic2 = cursor.getString(cursor.getColumnIndex("pic2"));
pic3 = cursor.getString(cursor.getColumnIndex("pic3"));
pic4 = cursor.getString(cursor.getColumnIndex("pic4"));
pic5 = cursor.getString(cursor.getColumnIndex("pic5"));
String[] mStrings={
pic1,
pic2,
pic3,
pic4,
pic5};
Gallery g = (Gallery) findViewById(R.id.photobar);
adapter1=new LazyAdapter(this, mStrings);
g.setAdapter(adapter1);
}
I have modified the LazyAdapter as such:
public class LazyAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private Activity activity;
private String[] data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, String[] d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public LazyAdapter(Context c) {
mContext = c;
TypedArray b = c.obtainStyledAttributes(R.styleable.Theme);
mGalleryItemBackground = b.getResourceId(
R.styleable.Theme_android_galleryItemBackground,
0);
b.recycle();
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView vi = new ImageView(mContext);
imageLoader.DisplayImage(data[position], vi);
vi.setLayoutParams(new Gallery.LayoutParams(150, 100));
vi.setScaleType(ImageView.ScaleType.FIT_XY);
return vi;
}
}
With the help of Fedor, I figured out what was wrong with the implementation. Whether for list or gallery, there is no need to change the LazyAdapter! Just use the adapter as it is and use the following code in your app to load the pictures:
g = (Gallery) findViewById(R.id.photobar);
adapter1=new LazyAdapter(this, mStrings);
g.setAdapter(adapter1);}
I noticed that there are a lot of examples on using LazyList for lists and not galleries. To help those who want to use it for galleries, here is an example of the implementation:
public class ResultDetails extends ListActivity {
protected int foodId;
protected String pic1, pic2, pic3, pic4, pic5;
LazyAdapter adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result_details);
foodId = getIntent().getIntExtra("FOOD_ID", 0);
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT _id, pic1, pic2, pic3, pic4, pic5 FROM database WHERE _id = ?", new String[]{""+foodId});
pic1 = cursor.getString(cursor.getColumnIndex("pic1"));
pic2 = cursor.getString(cursor.getColumnIndex("pic2"));
pic3 = cursor.getString(cursor.getColumnIndex("pic3"));
pic4 = cursor.getString(cursor.getColumnIndex("pic4"));
pic5 = cursor.getString(cursor.getColumnIndex("pic5"));
String[] mStrings={pic1, pic2, pic3, pic4, pic5};
g = (Gallery) findViewById(R.id.photobar);
adapter1=new LazyAdapter(this, mStrings);
g.setAdapter(adapter1);}

Restoring my custom listview and data after calling onDestroy(), then onCreate() in android

I have a an app with an IM style page, the text is displayed using a custom listview
When I leave the activity and come back I want to still have the listview with all my data in it. SO far I have tried saving the contents of my arraylist using onSavedInstance and onRestoredInstance then setting the adapter again in onRestoredInstance but that doesn't work.
Here is my code for my activity:
private ArrayList<String> nameList = new ArrayList<String>();
private ArrayList<String> messageList = new ArrayList<String>();
private ArrayList<String> timeList = new ArrayList<String>();
Button send = (Button) findViewById(R.id.chat_send);
EditText send = (EditText) findViewById(R.id.edit_text);
ListView chat_list = (ListView) findViewById(R.id.chat_list);
MyCustomArrayAdapter myArrayAdapter = new MyCustomArrayAdapter(this, messageList, nameList,
timeList, receiverName, senderName, language_chosen);
chat_list.setAdapter(myArrayAdapter);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String new_text = edit_text.getText().toString();
String sys_time = new Time(System.currentTimeMillis())
.toString();
timeList.add(sys_time);
messageList.add(new_text);
nameList.add(username);
myArrayAdapter.notifyDataSetChanged();
chat_list.setSelection(chat_list.getChildCount()-1);
}
});
And here is the code for my Adapter
public MyCustomArrayAdapter(Context context, ArrayList<String> planetList,
ArrayList<String> NameList, ArrayList<String> TimeList,
String receiver, String sender, String language) {
super(context, R.layout.custom_chat_layout, planetList);
this.context = context;
messageList = planetList;
nameList = NameList;
timeList = TimeList;
receiverName = receiver;
senderName = sender;
language_chosen = language;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
rowView = inflater.inflate(R.layout.custom_chat_layout, parent, false);
holder.chat_name = (TextView) rowView
.findViewById(R.id.custom_chat_name);
holder.chat_time = (TextView) rowView
.findViewById(R.id.custom_chat_timestamp);
holder.chat_text = (TextView) rowView
.findViewById(R.id.custom_chat_text);
holder.chat_name.setText(nameList.get(position));
holder.chat_time.setText(timeList.get(position));
holder.chat_text.setText(messageList.get(position));
return rowView;
}
static class ViewHolder {
TextView chat_name;
TextView chat_time;
TextView chat_text;
RelativeLayout relative;
RelativeLayout relative1;
}
You should save the data in onPause and re-populate the adapter in onResume. Things like instant messages should be saved to persistent data storage (for example, an SQLite database), and then loaded with a CursorAdapter. A lot of the details of maintaining the data load across the Activity lifecycle can be abstracted out by making use of the LoaderManager and loading the data with a CursorLoader instead.
It also sounds like you want to have a Service running in the background that can receive messages and save instant messages to the data store even when the Activity isn't in focus.
in:
onPause(){
open sharedpreferences, save your lists.
}
in:
onResume(){
open sharedpreferences, restore your lists, setdata changed
}
onSaveInstanceState() is only used at the time your app is running. After your app stopped, all data in bundle will be released.
You should use SharedPreferences.

Custom Spinner Crashing

I asked a question on here about a week or so ago about a custom spinner and got led to this guide. http://app-solut.com/blog/2011/03/using-custom-layouts-for-spinner-or-listview-entries-in-android/
I followed it and I've tried adapting it to work with my code and pull the results from a database onto the spinner but it keeps crashing.
This is the code for the spinner.
public class EditTeam extends Activity {
private final List<SpinnerEntry> spinnerContent = new LinkedList<SpinnerEntry>();
private Spinner D1Spinner;
private final ETSpinnerAdapter D1Adapter = new ETSpinnerAdapter(spinnerContent, this);
DataBaseHelper myDbHelper = new DataBaseHelper(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editteam);
myDbHelper = new DataBaseHelper(this);
myDbHelper.openDataBase();
fillSpinner();
}
private void fillSpinner() {
Cursor c = myDbHelper.FetchDrivers();
startManagingCursor(c);
// create an array to specify which fields we want to display
String[] from = new String[]{"FirstName", "LastName"};
// create an array of the display item we want to bind our data to
int[] to = new int[]{android.R.id.text1};
spinnerContent.add(new SpinnerEntry(1, null, "Test"));
//adapter.setDropDownViewResource( R.layout.spinner_entry_with_icon );
D1Spinner = (Spinner) findViewById(R.id.spr_Driver1);
D1Spinner.setAdapter((SpinnerAdapter) D1Adapter);
}
}
And I am using the two classes from that contacts example which are un-modified at the moment.
As you can see I'm trying to just manually add one item at the moment but it just crashes when you load it.
This seems to be the breaking point?
05-25 15:17:34.773: E/AndroidRuntime(241): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.f1manager.android/com.f1manager.android.EditTeam}: java.lang.ClassCastException: com.f1manager.android.ETSpinnerAdapter
Any ideas would be great.
Thanks.
ETSpinnerAdapter Code (Unmodified from the original code in the example):
public class ETSpinnerAdapter {
private final List<SpinnerEntry> content;
private final Activity activity;
public ETSpinnerAdapter(List<SpinnerEntry> content, Activity activity) {
super();
this.content = content;
this.activity = activity;
}
public int getCount() {
return content.size();
}
public SpinnerEntry getItem(int position) {
return content.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final LayoutInflater inflater = activity.getLayoutInflater();
final View spinnerEntry = inflater.inflate(
R.layout.spinner_entry_with_icon, null); // initialize the layout from xml
final TextView contactName = (TextView) spinnerEntry
.findViewById(R.id.spinnerEntryContactName);
final ImageView contactImage = (ImageView) spinnerEntry
.findViewById(R.id.spinnerEntryContactPhoto);
final SpinnerEntry currentEntry = content.get(position);
contactName.setText(currentEntry.getContactName());
//contactImage.setImageBitmap(currentEntry.getContactPhoto());
return spinnerEntry;
}
}
It would seem like your ETSpinnerAdapter is not a SpinnerAdapter as your are getting a class cast exceptin. Maybe you can post your code for the ETSpinnerAdapter?

Categories

Resources