ListView does not refresh dynamically and causes Error - android

I am unable to remove an object in a ListView. I have been trying to remove an object from an adapter, and then call onDataSetChanged(); but it does not seem to ever remove the object from the screen.
I can successfully remove the object from the database, but the object persists on screen regardless.
I believe that because the view does not refresh properly, it allows me to continue to swipe-to-dismiss the items in the list and eventually leads to an IndexOutOfBoundsException.
Does anyone see why my ListView will not update properly? I know there are plenty of questions similar to this one, but most refer to onDataSetChanged() as a solution, and it doesn't seem to be my problem.
06-01 19:33:46.734: E/AndroidRuntime(9011): Process: com.example.datetracker, PID: 9011
06-01 19:33:46.734: E/AndroidRuntime(9011): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
06-01 19:33:46.734: E/AndroidRuntime(9011): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
06-01 19:33:46.734: E/AndroidRuntime(9011): at java.util.ArrayList.get(ArrayList.java:308)
06-01 19:33:46.734: E/AndroidRuntime(9011): at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
06-01 19:33:46.734: E/AndroidRuntime(9011): at com.example.datetracker.MainActivity$1.onDismiss(MainActivity.java:97)
06-01 19:33:46.734: E/AndroidRuntime(9011): at com.example.datetracker.SwipeDismissListViewTouchListener$3.onAnimationEnd(SwipeDismissListViewTouchListener.java:362)
06-01 19:33:46.734: E/AndroidRuntime(9011): at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1056)
06-01 19:33:46.734: E/AndroidRuntime(9011): at android.animation.ValueAnimator.access$400(ValueAnimator.java:50)
06-01 19:33:46.734: E/AndroidRuntime(9011): at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:644)
06-01 19:33:46.734: E/AndroidRuntime(9011): at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:660)
MainActivity
public class MainActivity extends FragmentActivity implements OnClickListener {
ListView listView;
int lastIndex = -1;
List<Event> lstEvents = new ArrayList<Event>();
// detail view
TextView tvTitle, tvTime, tvDate;
ImageView ivPic;
View vw_master;
boolean _isBack = true;
ImageButton add;
String title;
String date;
String time;
int resId;
Context context;
static final int PICK_CONTACT_REQUEST = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// // get detail controls
tvTitle = (TextView) findViewById(R.id.textViewTitle);
tvDate = (TextView) findViewById(R.id.textViewDate);
tvTime = (TextView) findViewById(R.id.textViewTime);
ivPic = (ImageView) findViewById(R.id.imageView1);
add = (ImageButton) findViewById(R.id.add);
add.setOnClickListener(this);
// /////////////////////////////DATABASE/////////////////////////////////////////////
DatabaseHandler db = new DatabaseHandler(this);
// /////////////////////////////DATABASE/////////////////////////////////////////////
// ///////////////////////////////LISTVIEW////////////////////////////////////////
// Create the adapter to convert the array to views
EventAdapter adapter = new EventAdapter(this, db.getAllContacts());
// attach adapter to a list view
listView = (ListView) findViewById(R.id.listViewFragment);
listView.setAdapter(adapter);
context = this;
SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(
listView,
new SwipeDismissListViewTouchListener.DismissCallbacks() {
DatabaseHandler db = new DatabaseHandler(context);
EventAdapter adapter = new EventAdapter(context,
db.getAllContacts());
#Override
public boolean canDismiss(int position) {
return true;
}
#Override
public void onDismiss(ListView listView,
int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
adapter.addAll(db.getAllContacts());
db.deleteEvent(adapter.getItem(position));
adapter.remove(adapter.getItem(position));
}
adapter.clear();
adapter.notifyDataSetChanged();
}
});
listView.setOnTouchListener(touchListener);
// Setting this scroll listener is required to ensure that during
// // ListView scrolling,
// // we don't look for swipes.
listView.setOnScrollListener(touchListener.makeScrollListener());
adapter.addAll(db.getAllContacts());
adapter.notifyDataSetChanged();
}
// #Override
// protected void onResume() {
// // TODO Auto-generated method stub
// super.onResume();
// //
// /////////////////////////////DATABASE/////////////////////////////////////////////
// DatabaseHandler db = new DatabaseHandler(this);
// //
// /////////////////////////////DATABASE/////////////////////////////////////////////
//
// super.onResume();
// adapter.swapItems(db.getAllContacts());
// }
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.add:
Intent intent = new Intent(this, CreateActivity.class);
startActivityForResult(intent, 100);
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// /////////////////////////////DATABASE/////////////////////////////////////////////
DatabaseHandler db = new DatabaseHandler(this);
// /////////////////////////////DATABASE/////////////////////////////////////////////
// Create the adapter to convert the array to views
EventAdapter adapter = new EventAdapter(this, db.getAllContacts());
// attach adapter to a list view
listView = (ListView) findViewById(R.id.listViewFragment);
listView.setAdapter(adapter);
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
Bundle b = data.getExtras();
title = b.getString("TITLE");
time = b.getString("TIME");
date = b.getString("DATE");
Bitmap bitmap = b.getParcelable("BITMAP");
// ///CONVERTING A BITMAP TO A BYTE[]
byte[] image = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
image = bos.toByteArray();
// ///////
// /////////////////////////////DATABASE/////////////////////////////////////////////
/**
* CRUD OPERATIONS
*/
Log.e("Insert: ", "Inserting ..");
db.addEvent(new Event((int) Math.floor(Math.random() * 101),
title, time, date, image));
// Reading all contacts
Log.e("Reading: ", "Reading all contacts..");
adapter.addAll(db.getAllContacts());
adapter.notifyDataSetChanged();
// logging all events
for (Event ev : db.getAllContacts()) {
String log = "Id: " + ev.get_Id() + " ,Title: "
+ ev.get_title() + " ,Date: " + ev.get_date()
+ " ,RESOURCEID: " + ev.get_image();
// Writing Contacts to log
Log.e("Name: ", log);
}
// /////////////////////////////DATABASE/////////////////////////////////////////////
}
}
}
}
EventAdapter
public class EventAdapter extends ArrayAdapter<Event> {
private List<Event> events;
// View lookup cache
private static class ViewHolder {
//adding drawable to imageview
ImageView img;
TextView title;
TextView time;
TextView date;
}
public EventAdapter(Context context, List<Event> objects) {
super(context, R.layout.date_detail);
this.events = events;
// TODO Auto-generated constructor stub
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Event event = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.date_detail, null);
viewHolder.title = (TextView) convertView
.findViewById(R.id.textViewTitle);
viewHolder.time = (TextView) convertView
.findViewById(R.id.textViewTime);
viewHolder.date = (TextView) convertView
.findViewById(R.id.textViewDate);
//adding drawable to imageview
viewHolder.img = (ImageView) convertView
.findViewById(R.id.imageView1);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.title.setText(event._title);
viewHolder.time.setText(event._time);
viewHolder.date.setText(event._date);
//convert from byte array to bitmap
Bitmap bitmap = convertByteArrayToBitmap(event._image);
// CONVERT BITMAP TO DRAWABLE
viewHolder.img.setImageBitmap(bitmap);
// Return the completed view to render on screen
return convertView;
}
public static Bitmap convertByteArrayToBitmap(
byte[] byteArrayToBeCOnvertedIntoBitMap)
{
Bitmap bitmap = BitmapFactory.decodeByteArray(
byteArrayToBeCOnvertedIntoBitMap, 0,
byteArrayToBeCOnvertedIntoBitMap.length);
return bitmap;
}
public void swapItems(List<Event> events) {
this.events = events;
notifyDataSetChanged();
}
}

The problem was solved by removing the following lines of code in the swipeDismissViewListener and the OnActivityResult.
DatabaseHandler db = new DatabaseHandler(context);
EventAdapter adapter = new EventAdapter(context, db.getAllContacts());

Related

Expandable Listview slow performance in Android

I want to make my expandable list smooth.
After looking a lot in the internet,
I added a viewHolder and changed my method where I load the data to be asynchronously. But my list is still slow!!!.
Can you take a look? I added the activity where I load asynchronously the data with my DataProvider and then I init my adapter. This help me to see my activity and a spinner until the data is loaded and then updated on my view.
But I dont have a fluid list when I scroll or when I try to expand a category. Can you help and tell me what to change ? I think that it can be the images but I save them locally to make it faster (I added my methods) and it can be something else....
MyActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set layout for this activity
setContentView(R.layout.expandable_list);
// Set actionbar title
getActionBar().show();
getActionBar().setTitle(Html.fromHtml("<font color='#fffffff'>Groups</font>"));
if (loggedUserId != null)
Log.d("TAG", "My Groups for user ID: " + loggedUserId);
// Connect between buttons to layout id
expandableListView = (ExpandableListView) findViewById(R.id.exp_list);
spinner = (ProgressBar) findViewById(R.id.spinner);
createCategoryButton = (ImageButton) findViewById(R.id.createCategory);
textLoading = (TextView) findViewById(R.id.textLoading);
// Loading data to expandable group list asynchronously
AsyncTask<String, String, HashMap<String, List<Group>>> task = new AsyncTask<String, String, HashMap<String, List<Group>>>() {
#Override
protected HashMap<String, List<Group>> doInBackground(String... params) {
return DataProvider.getInfo();
}
#Override
protected void onPostExecute(HashMap<String, List<Group>> listHashMap) {
super.onPostExecute(listHashMap);
// Setting adapter and creating group list
groupCategories = listHashMap;
groupsList = new ArrayList<String>(groupCategories.keySet());
adapter = new Adapter(GroupsListActivity.this, groupCategories, groupsList, GroupsListActivity.this);
expandableListView.setAdapter(adapter);
// Hide spinner after loading
spinner.setVisibility(View.GONE);
textLoading.setVisibility(View.GONE);
}
};
task.execute();
My adapter:
#Override
public View getGroupView(final int parent, boolean isExpanded, View convertView, ViewGroup parentView) {
final String categoryName = (String) getGroup(parent);
ParentViewHolder pHolder = null;
if (convertView == null) {
// Creates a ViewHolder and store references to layouts we want to bind data to.
pHolder = new ParentViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.expandable_list_parent, parentView, false);
// Connect between buttons to layout id
pHolder.categoryNameTextView = (TextView) convertView.findViewById(R.id.categoryName);
pHolder.editCategory = (ImageButton) convertView.findViewById(R.id.editCategory);
pHolder.deleteCategory = (ImageButton) convertView.findViewById(R.id.deleteCategory);
//Save holder
convertView.setTag(pHolder);
} else {
// Get the ViewHolder back
pHolder = (ParentViewHolder) convertView.getTag();
}
// Hide edit and delete button for category name Others
if (categoriesList.get(parent).equals("Others")) {
pHolder.editCategory.setVisibility(View.GONE);
pHolder.deleteCategory.setVisibility(View.GONE);
} else {
pHolder.editCategory.setVisibility(View.VISIBLE);
pHolder.deleteCategory.setVisibility(View.VISIBLE);
}
// Set category name on row
pHolder.categoryNameTextView.setTypeface(null, Typeface.BOLD);
pHolder.categoryNameTextView.setText(categoryName + ": " + getChildrenCount(parent));
// Set edit category button listener
final ParentViewHolder finalPHolder = pHolder;
pHolder.editCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalPHolder.editCategory.setEnabled(false);
editCategoryName(activity, finalPHolder.categoryNameTextView.getText().toString().toString().split(": ")[0], finalPHolder.editCategory, parent);
}
});
// Set delete category button listener
pHolder.deleteCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalPHolder.deleteCategory.setEnabled(false);
deleteCategory(activity, categoryName, finalPHolder.deleteCategory);
}
});
return convertView;
}
#Override
public View getChildView(final int parent, final int child, boolean lastChild, View convertView, ViewGroup parentView) {
final Group group = (Group) getChild(parent, child);
ChildViewHolder cHolder = null;
if (convertView == null) {
// Creates a ViewHolder and store references to layouts we want to bind data to.
cHolder = new ChildViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.expandable_list_child, parentView, false);
// Connect between buttons to layout id
cHolder.groupImage = (ImageView) convertView.findViewById(R.id.groupImage);
cHolder.groupName = (TextView) convertView.findViewById(R.id.groupName);
cHolder.moveCategory = (ImageButton) convertView.findViewById(R.id.moveCategory);
cHolder.groupFavoritesButton = (ImageButton) convertView.findViewById(R.id.groupFavorites);
cHolder.groupLeaveGroupButton = (Button) convertView.findViewById(R.id.groupLeave);
cHolder.groupImageProgressbar = (ProgressBar) convertView.findViewById(R.id.groupImageProgressBar);
//Save holder
convertView.setTag(cHolder);
} else {
// Get the ViewHolder back
cHolder = (ChildViewHolder) convertView.getTag();
}
// Set group name on row
cHolder.groupName.setText(group.getName());
// Load group image
cHolder.groupImageProgressbar.setVisibility(View.VISIBLE);
final ChildViewHolder finalHolder = cHolder;
Model.getInstance().getGroupImage(group.getImageName(), new Model.LoadImageListener() {
#Override
public void onResult(Bitmap imageBmp) {
if (imageBmp != null) {
finalHolder.groupImage.setImageBitmap(imageBmp);
finalHolder.groupImageProgressbar.setVisibility(View.GONE);
finalHolder.groupImage.setVisibility(View.VISIBLE);
}
}
});
// Set move category button listener
cHolder.moveCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalHolder.moveCategory.setEnabled(false);
showDialogMoveCategory(activity, group.getGroupID(), finalHolder.moveCategory);
}
});
// After click on group image - open profile for this group
cHolder.groupImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onGroupSelected(group.getGroupID());
}
});
// Setting favorite Button Image
boolean isFavorite = Model.getInstance().groupIsFavorite(loggedUserId, group.getGroupID());
if (isFavorite)
cHolder.groupFavoritesButton.setBackgroundResource(R.mipmap.favorites_on);
else
cHolder.groupFavoritesButton.setBackgroundResource(R.mipmap.favorites_off);
// Setting favorite Button Action
cHolder.groupFavoritesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Add group to favorites
if (!Model.getInstance().groupIsFavorite(loggedUserId, group.getGroupID())) {
finalHolder.groupFavoritesButton.setBackgroundResource(R.mipmap.favorites_on);
Toast.makeText(activity,
"The group " + group.getName() + " was added to favorites", Toast.LENGTH_SHORT).show();
Model.getInstance().changeFavoriteStatus(loggedUserId, group.getGroupID(), "true");
} else {
// Delete group from favorites
finalHolder.groupFavoritesButton.setBackgroundResource(R.mipmap.favorites_off);
Toast.makeText(activity,
"The group " + group.getName() + " was removed from favorites", Toast.LENGTH_SHORT).show();
Model.getInstance().changeFavoriteStatus(loggedUserId, group.getGroupID(), "false");
}
}
});
// After click on group action - leave group
cHolder.groupLeaveGroupButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalHolder.groupLeaveGroupButton.setEnabled(false);
showDialogLeaveGroup(activity, "Are you sure ?", "This action will remove yourself from the group " + group.getName(), group.getGroupID(), parent, child);
finalHolder.groupLeaveGroupButton.setEnabled(true);
}
});
return convertView;
}
Images methods:
public void getGroupImage(final String imageName, final LoadImageListener listener) {
AsyncTask<String, String, Bitmap> task = new AsyncTask<String, String, Bitmap>() {
#Override
protected Bitmap doInBackground(String... params) {
Bitmap bmp = loadImageFromFile(imageName); //first try to find the image on the device
// Bitmap bmp = null;
if (bmp == null) { //if image not found - try downloading it from parse
bmp = modelParse.getGroupImage(imageName);
if (bmp != null)
saveImageToFile(bmp, imageName); //save the image locally for next time *****
}
Bitmap scaledBitmap = scaleDown(bmp, 200, true);
return scaledBitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
listener.onResult(result);
}
};
task.execute();
}
private void saveImageToFile(Bitmap imageBitmap, String imageFileName) {
FileOutputStream fos;
OutputStream out = null;
try {
File dir = context.getExternalFilesDir(null);
out = new FileOutputStream(new File(dir, imageFileName + ".jpg"));
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Bitmap loadImageFromFile(String fileName) {
Bitmap bitmap = null;
try {
File dir = context.getExternalFilesDir(null);
InputStream inputStream = new FileInputStream(new File(dir, fileName + ".jpg"));
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}

How to update the ListView after adding new items?

I am working on a grocery list app and having trouble refreshing the list view after adding a new item. After I add a new item in the database the ListView is not refreshed. If I go in the item details page and then come back to main activity the onCreate is called again and it refreshes it correctly.
If I call the refresh method in the addItemToDb() (on button clicked) method it duplicates my items but does not add them to the database.
Has anyone had this problem before???
Here is the code:
The list view adapter
public class ItemListViewAdapter extends ArrayAdapter<ItemModel> {
Activity activity;
int layoutResource;
ArrayList<ItemModel> itemModelArrayList = new ArrayList<>();
public ItemListViewAdapter(Activity act, int resource, ArrayList<ItemModel> data) {
super(act, resource, data);
activity = act;
layoutResource = resource;
itemModelArrayList = data;
notifyDataSetChanged();
}
#Override
public int getCount() {
return itemModelArrayList.size();
}
#Override
public ItemModel getItem(int position) {
return itemModelArrayList.get(position);
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
final ViewHolder holder;
if (row == null || (row.getTag()) == null) {
LayoutInflater inflater = LayoutInflater.from(activity);
row = inflater.inflate(layoutResource, null);
holder = new ViewHolder();
holder.hItemName = (TextView) row.findViewById(R.id.custom_row_productName);
holder.hItemPrice = (TextView) row.findViewById(R.id.custom_row_productPrice);
holder.hItemType = (TextView) row.findViewById(R.id.custom_row_productType);
holder.hCheckBox = (CheckBox) row.findViewById(R.id.custom_row_checkBox);
holder.hItemEdit = (ImageView) row.findViewById(R.id.custom_row_edit);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
holder.hModel = getItem(position);
holder.hItemName.setText(holder.hModel.getItemName());
holder.hItemPrice.setText(String.valueOf(holder.hModel.getItemPrice()));
holder.hItemType.setText(holder.hModel.getItemType());
holder.hItemEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int itemID = holder.hModel.getItemId();
String itemName = holder.hModel.getItemName();
String itemPrice = String.valueOf(holder.hModel.getItemPrice());
String itemType = holder.hModel.getItemType();
String itemDate = holder.hModel.getItemDate();
Intent intent = new Intent(activity, ItemDetail.class);
intent.putExtra("id", itemID);
intent.putExtra("product", itemName);
intent.putExtra("price", itemPrice);
intent.putExtra("type", itemType);
intent.putExtra("date", itemDate);
startActivity(activity, intent, null);
}
});
return row;
}
public class ViewHolder {
ItemModel hModel;
TextView hItemName;
TextView hItemPrice;
TextView hItemType;
TextView hItemDate;
CheckBox hCheckBox;
ImageView hItemEdit;
}
}
And main activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHandler = new DatabaseHandler(getApplicationContext());
itemNameText = (EditText) findViewById(R.id.activity_main_productName);
itemPriceText = (EditText) findViewById(R.id.activity_main_productPrice);
itemTypeSpinner = (Spinner) findViewById(R.id.activity_main_spinner);
addButton = (Button) findViewById(R.id.activity_main_addButton);
saveListButton = (FloatingActionButton) findViewById(R.id.activity_main_fab);
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array.productTypes, R.layout.spinner_item);
itemTypeSpinner.setAdapter(spinnerAdapter);
//USE BUTTONS
addButton.setOnClickListener(this);
saveListButton.setOnClickListener(this);
//LIST_VIEW
listView = (ListView) findViewById(R.id.activity_main_listView);
//calling methods
refreshData();
}
public void refreshData() {
modelArrayListContainer.clear();
//GET ITEMS FROM DB
ArrayList<ItemModel> modelArrayListFromDB = dbHandler.getAllItems();
for (int i = 0; i < modelArrayListFromDB.size(); i++) {
int ditemID = modelArrayListFromDB.get(i).getItemId();
String dItemName = modelArrayListFromDB.get(i).getItemName();
double dItemPrice = modelArrayListFromDB.get(i).getItemPrice();
String dItemType = modelArrayListFromDB.get(i).getItemType();
String dItemDate = modelArrayListFromDB.get(i).getItemDate();
ItemModel newModel = new ItemModel();
newModel.setItemId(ditemID);
newModel.setItemName(dItemName);
newModel.setItemPrice((int) dItemPrice);
newModel.setItemType(dItemType);
newModel.setItemDate(dItemDate);
modelArrayListContainer.add(newModel);
}
//setup Adapter
itemListViewAdapter = new ItemListViewAdapter(MainActivity.this, R.layout.custom_product_layout_activity_main, modelArrayListContainer);
listView.setAdapter(itemListViewAdapter);
itemListViewAdapter.notifyDataSetChanged();
}
public void addItemToDb() {
ItemModel model = new ItemModel();
String spinnerValue = itemTypeSpinner.getSelectedItem().toString();
model.setItemName(itemNameText.getText().toString().trim()); model.setItemPrice(Double.parseDouble((itemPriceText.getText().toString().trim())));
model.setItemType(spinnerValue);
dbHandler.addItem(model);
dbHandler.close();
Log.v(TAG, "::addItemToDb - itemAdded");
}
}
You need to call refreshData() in your addItemToDb function like:
public void addItemToDb() {
ItemModel model = new ItemModel();
String spinnerValue = itemTypeSpinner.getSelectedItem().toString();
model.setItemName(itemNameText.getText().toString().trim()); model.setItemPrice(Double.parseDouble((itemPriceText.getText().toString().trim())));
model.setItemType(spinnerValue);
dbHandler.addItem(model);
dbHandler.close();
Log.v(TAG, "::addItemToDb - itemAdded");
refreshData();
}
But if you need to update data automatically from database, you need to use CursorAdaptor and use Content Providers
UPDATE
Also change your getAllItems() function in dbhandler and include the following statement in the first line of the function:
modelArrayList.clear();

ListView won't refresh using notifyDataSetChanged

I'm trying to refresh the listview from the adapter class ( non activity class) I tried notifyDataSetChanged() but it wont work , I also tried to call the displayListView() in the adapter class but it crashes as well
this is my displayListView() Method in The ActivityClass
Cursor cursor = dbHelper.fetchAllCountries();
// The desired columns to be bound
String[] columns = new String[]{
DBAdapter.qty,
DBAdapter.price,
DBAdapter.PRODUCT_NAME
};
// the XML defined views which the data will be bound to
int[] to = new int[]{
R.id.qtyL,
R.id.priceL,
R.id.PRODUCT_NAMEL
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.country_inf,
cursor,
columns,
to,
0);
HorizontalListView listView = (HorizontalListView) findViewById(R.id.cartCeckOutList);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
dataAdapter.notifyDataSetChanged();
And this is the Adapter Class I use
package com.abdullahadhaim.finegrillresturant.adater;
public class CustomListAdapter extends BaseAdapter {
Context c;
// DBHelper myDataBaseHelper ;
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
DBAdapter myADapterDB;
WaiterActivity waiterAct;
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
final TextView title = (TextView) convertView.findViewById(R.id.title);
TextView price = (TextView) convertView.findViewById(R.id.rating);
// myDataBaseHelper=new DBHelper(activity, "CDB", null, 1);
myADapterDB = new DBAdapter(activity);
myADapterDB.open();
waiterAct = new WaiterActivity();
// getting movie data for the row
final Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
// price
price.setText("Price: " + "SR " + String.valueOf(m.getPrice()));
Button add = (Button) convertView.findViewById(R.id.button1);
Button plus = (Button) convertView.findViewById(R.id.plus_butt);
Button minus = (Button) convertView.findViewById(R.id.minus_butt);
final EditText qty = (EditText) convertView
.findViewById(R.id.editText1);
plus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String the_qty = qty.getText().toString();
int my_qty = Integer.parseInt(the_qty) + 1;
qty.setText(my_qty + "");
}
});
minus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String the_qty = qty.getText().toString();
int my_qty = Integer.parseInt(the_qty) - 1;
qty.setText(my_qty + "");
}
});
add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int myQTY = Integer.parseInt(qty.getText().toString());
String myTitle = m.getTitle().toString();
String myCategory = m.getCategory().toString();
int myCategoryN = m.getOrderNum();
double myPrice = m.getPrice() * myQTY;
if (myQTY == 0)
Toast.makeText(activity, "Orders Must be 1 Atleast",
Toast.LENGTH_SHORT).show();
else {
myADapterDB.checkIfExcist(activity, "productName", myTitle,
myQTY, myPrice, m.getPrice(), myTitle, myCategory,
myCategoryN + "", myQTY);
myADapterDB.deleteZeroOrLessValues();
}
}
});
return convertView;
}
public void notifyDataSetChanged() {
// TODO Auto-generated method stub
super.notifyDataSetChanged();
}
}
take a look at Loaders. I think this is the prefered way to load data from datebase into views. With Loaders you get callbacks if the data has changed and the view is updated for you.
http://developer.android.com/guide/components/loaders.html
Here is a good tutorial I think:
http://code.tutsplus.com/tutorials/android-fundamentals-properly-loading-data--mobile-5673

ListView disappears after reloading it again

I have 3 arraylist that i have combined to show in listview. Wehen i click on to generate listview, it works fine the first time but when i hit back and then click the button again, the listview shows nothing. Not sure what is cause it. I checked other post but couldnt find an answer. I am not too good with Arraylist so any details would be greatly appreciated.
I have also noticed this message in Log cat. not sure what it means.
onVisibilityChanged() is called, visibility : 0
public class Edit extends Activity implements OnItemClickListener {
private int pic;
public String filename ="User Info";
//Declaring SHareddPreference as userprofile
static SharedPreferences userprofile;
ListView listView;
List<RowItem> rowItems;
// String[] titles, descriptions;
File imgpath=null;
Context context=this;
CustomListAdapter adapter;
private List<String> Titles = new ArrayList<String>();
private List<String> Actions = new ArrayList<String>();
private List<Bitmap> Images = new ArrayList<Bitmap>();
int x;
int y=1;
int z=1;
static int a=1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aname);
listView = (ListView)findViewById(R.id.listing);
userprofile = getSharedPreferences(filename,0);
Intent pdf=getIntent();
pic= userprofile.getInt("lastpic",pic);
x=pic;
Log.d("editpic",new Integer(pic).toString());
while(y!=x){
String comment = commentresult();
Titles.add(comment);
y++;
Log.d("y",new Integer(y).toString());
}
while(z!=x){
String act = actionresult();
Actions.add(act);
z++;
Log.d("z",new Integer(z).toString());}
while(a!=x){
Bitmap photo = getbitmap();
Images.add(photo);
a++;
Log.d("a",new Integer(a).toString());}
Titles.toArray();
Actions.toArray();
Images.toArray();
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < Images.size(); i++) {
RowItem item = new RowItem(Images.get(i), Titles.get(i),Actions.get(i));
rowItems.add(item);
}
Log.d("TAG", "listview null? " + (listView == null));
CustomListAdapter adapter = new CustomListAdapter(this,
R.layout.aname_list_item, rowItems);
Log.d("TAG", "adapter=null? " + (adapter == null));
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
listView.setOnItemClickListener(this);
}
public static Bitmap getbitmap() {
String photo1 =userprofile.getString("picpath"+a, "");
File imgpath=new File(photo1);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bmp=DecodeImage.decodeFile(imgpath, 800, 1000, true);
bmp.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
Bitmap photo2=bmp;
return photo2;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
}
public String commentresult()
{
// String com2 = null;
// while(y!=x){
String comment=userprofile.getString("comment"+y, "");
String com1=comment;
String com2=com1;
// }
return com2;
}
public String actionresult()
{
// String act2 = null;
// while(y!=x){
String action=userprofile.getString("action"+z, "");
String act1=action;
String act2=act1;
// }
return act2;
}
private static final long delay = 2000L;
private boolean mRecentlyBackPressed = false;
private Handler mExitHandler = new Handler();
private Runnable mExitRunnable = new Runnable() {
#Override
public void run() {
mRecentlyBackPressed=false;
}
};
#Override
public void onBackPressed() {
//You may also add condition if (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount() != 0) // in case of Fragment-based add
if (mRecentlyBackPressed) {
mExitHandler.removeCallbacks(mExitRunnable);
mExitHandler = null;
super.onBackPressed();
}
else
{
mRecentlyBackPressed = true;
Toast.makeText(this, "press again to exit", Toast.LENGTH_SHORT).show();
mExitHandler.postDelayed(mExitRunnable, delay);
}
}
#Override
public void onDestroy() {
// Destroy the AdView.
super.onDestroy();
}
Custom List Adapter:
public class CustomListAdapter extends ArrayAdapter<RowItem> {
Context context;
List<RowItem> items;
public CustomListAdapter(Context context, int resourceId,
List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
this.items = items;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public RowItem getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtDesc;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.aname_list_item, null);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.rab);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
// String name=items.get(position).getDesc();
holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageBitmap(rowItem.getImageId());
// holder.imageView.setImageResource(Images.get(position) .getPlaceholderleft());
return convertView;
}
}
It looks like this is because you've made your variables x, y, z and a all static, which means there is a single instance of the variables shared by all instances of the class. Therefore, when you call onCreate the second time, all your while loop termination conditions are already met, so the while loops never execute. It's unclear to me why you've made these static, so unless you need them to be, you should remove the static keyword for these variables.
Why are you creating another object of ListView in onCreate() and onResume()
Remove code from onResume()
Also replace this line in onCreate()
old line ListView listView = (ListView)findViewById(R.id.listing);
New line listView = (ListView)findViewById(R.id.listing);

Referencing or Creating a Drawable from its Res ID (Int) Value?

I would like to be able to store a drawables INT value (ResourceID) in SQLite and later be able to pull it from the database and convert it to a drawable to be viewed in a listview.
The following snippit generates 2 values, the ResID portion is a int value that I would like to be able to convert back to the drawable in another activity.\
Drawable myDrawable = getResources().getDrawable(
images[position]);
Log.e("DRAWABLE", "DrawableId 1: " + myDrawable);
int resId = images[position];
Log.e("DRAWABLE", "DrawableId 2: " + resId);
What should I do to convert ResID to a drawable? If possible
PicturePickerFragment
public class PicturePickerFragment extends DialogFragment {
ListView listView;
ArrayList<RowItem> rowItems = new ArrayList<RowItem>();
// attach adapter to a list view
// A String[] array that will hold the names of the items.
public static final String[] descriptions = { "Baby", "Baking",
"Barbershop", "Camping", "Conference Call", "Funeral", "Gambling",
"Gardening", "Halloweeen", "Medicine", "Meeting", "Poker",
"Christmas", "Wedding" };
public static final Integer[] images = { R.drawable.baby,
R.drawable.baking, R.drawable.barbershop, R.drawable.camping,
R.drawable.conferencecall, R.drawable.funeral, R.drawable.gambling,
R.drawable.gardening, R.drawable.halloween, R.drawable.medicine,
R.drawable.meeting, R.drawable.poker, R.drawable.santa,
R.drawable.wedding };
Button btn_pic;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.dialog_view, null);
// defining the alertdialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(convertView);
builder.setTitle(R.string.event_type);
builder.setPositiveButton(R.string.select_picture,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// call the method on the parent activity when
// user click the positive button
}
});
// populating the array list
for (int i = 0; i < descriptions.length; i++) {
RowItem item = new RowItem(images[i], descriptions[i]);
rowItems.add(item);
}
// defining listview and using array adapter
listView = (ListView) convertView.findViewById(R.id.listViewFragment2);
DrawableAdapter adapter = new DrawableAdapter(getActivity(), rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
// final int item = images[position];
Drawable myDrawable = getResources().getDrawable(
images[position]);
Log.e("DRAWABLE", "DrawableId 1: " + myDrawable);
int resId = images[position];
Log.e("DRAWABLE", "DrawableId 2: " + resId);
Button b = (Button) getActivity()
.findViewById(R.id.btn_picture);
b.setCompoundDrawablesWithIntrinsicBounds(null, myDrawable,
null, null);
}
});
adapter.addAll(rowItems);
return builder.create();
}
}
CreateActivity
public class CreateActivity extends Activity implements OnClickListener {
EditText etTitle;
Button btDate;
Button btTime;
Button btPic;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//onclicklistener
findViewById(R.id.btn_confirm).setOnClickListener(this);
findViewById(R.id.btn_back).setOnClickListener(this);
etTitle = (EditText) findViewById(R.id.editTextTitle);
btDate = (Button) findViewById(R.id.btn_date);
btTime = (Button) findViewById(R.id.btn_time);
btPic = (Button) findViewById(R.id.btn_picture);
}
// Will be called via the onClick attribute
// of the buttons in main.xml
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_confirm:
String title = etTitle.getText().toString();
String time = btTime.getText().toString();
String date = btDate.getText().toString();
Drawable drawable = btPic.getCompoundDrawables()[1];
int
Log.e("DRAWABLE", "DrawableId 3: " + drawable);
//Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
Log.e("LOG", title);
Log.e("LOG", time);
Log.e("LOG", date);
Bundle newBundle = new Bundle();
newBundle.putString("TITLE", title);
newBundle.putString("TIME", time);
newBundle.putString("DATE", date);
//newBundle.putInt
//Trying to pass a drawable from one activity to another
//newBundle.putParcelable("DRAWABLE", bitmap);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtras(newBundle);
setResult(RESULT_OK, intent);
finish();
break;
case R.id.btn_back:
finish();
break;
}
}
public void showTimePickerDialog(View v) {
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "timePicker");
}
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
public void showPicturePickerDialog(View v) {
DialogFragment newFragment = new PicturePickerFragment();
newFragment.show(getFragmentManager(), "picturePicker");
}
}
Main Activity
public class MainActivity extends FragmentActivity implements OnClickListener {
ListView listView;
int lastIndex = -1;
ArrayList<Event> lstEvents = new ArrayList<Event>();
// detail view
TextView tvTitle, tvTime, tvDate;
ImageView ivPic;
View vw_master;
boolean _isBack = true;
ImageButton add;
String title;
String date;
String time;
int resId;
static final int PICK_CONTACT_REQUEST = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// // get detail controls
tvTitle = (TextView) findViewById(R.id.textViewTitle);
tvDate = (TextView) findViewById(R.id.textViewDate);
tvTime = (TextView) findViewById(R.id.textViewTime);
ivPic = (ImageView) findViewById(R.id.imageView1);
add = (ImageButton) findViewById(R.id.add);
add.setOnClickListener(this);
/////////////////////////////////LISTVIEW////////////////////////////////////////
// Create the adapter to convert the array to views
EventAdapter adapter = new EventAdapter(this, lstEvents);
// attach adapter to a list view
listView = (ListView) findViewById(R.id.listViewFragment);
listView.setAdapter(adapter);
/////////////////////////////////LISTVIEW////////////////////////////////////////
// /////////////////////////////DATABASE/////////////////////////////////////////////
DatabaseHandler db = new DatabaseHandler(this);
// /////////////////////////////DATABASE/////////////////////////////////////////////
List<Event> events = db.getAllContacts();
adapter.addAll(events);
adapter.notifyDataSetChanged();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.add:
Intent intent = new Intent(this, CreateActivity.class);
startActivityForResult(intent, 100);
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// /////////////////////////////DATABASE/////////////////////////////////////////////
DatabaseHandler db = new DatabaseHandler(this);
// /////////////////////////////DATABASE/////////////////////////////////////////////
// Create the adapter to convert the array to views
EventAdapter adapter = new EventAdapter(this, lstEvents);
// attach adapter to a list view
listView = (ListView) findViewById(R.id.listViewFragment);
listView.setAdapter(adapter);
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
Bundle b = data.getExtras();
title = b.getString("TITLE");
time = b.getString("TIME");
date = b.getString("DATE");
// retrieving bitmap from CreateActivity
int drawable = b.getInt("DRAWABLE");
//Bitmap bitmap = (Bitmap) b.getParcelable("DRAWABLE");
// converting from bitmap to drawable
//Drawable drawable = new BitmapDrawable(getResources(), bitmap);
// Event newEvent = new Event();
// newEvent.set_date(date);
// newEvent.set_title(title);
// newEvent.set_time(time);
// set drawable
// newEvent.set_drawable(drawable);
// lstEvents.add(newEvent);
// adapter.addAll(lstEvents);
// adapter.notifyDataSetChanged();
///////////////////////////////DATABASE/////////////////////////////////////////////
/**
* CRUD OPERATIONS
*/
Log.e("Insert: ", "Inserting ..");
db.addEvent(new Event(0, title, time, date, drawable));
// Reading all contacts
Log.e("Reading: ", "Reading all contacts..");
// List<Event> events = db.getAllContacts();
List<Event> events = db.getAllContacts();
adapter.addAll(events);
adapter.notifyDataSetChanged();
//logging all events
for (Event ev : events) {
String log = "Id: " + ev.get_Id() + " ,Title: "
+ ev.get_title() + " ,Date: " + ev.get_date();
// Writing Contacts to log
Log.e("Name: ", log);
}
///////////////////////////////DATABASE/////////////////////////////////////////////
}
}
}
}
I believe storing the Resource Id is not the right approach, since Id's are only unique to each type of resource. So there are possible of same Id for two different resources.
The best approach would be to store the file name of resource as string.
You can retrieve the resource id with the resource file name using Resource Identifier
int resourceId = getResources().getIdentifier("file_name", "drawable", getPackageName());

Categories

Resources