I have an list with an custom adapter, and upon refresh I want to add new data to be displayed(if any available).
But the list isn't being update. I tried all the methods with notifyDataSetChanged for the adapter but it's not updated.
Please help. I lost so much time with this and I feel like I'm loosing my mind with this one.
Here is the code:
NewsFeedArrayAdapter
public class NewsFeedArrayAdapter extends ArrayAdapter<FeedItem> {
private final String TAG_DEBUG = this.getClass().getName();
private LayoutInflater inflator;
public final static String PREFS_NAME = "shared_pref_eid";
ImageLoader imageLoader;
Utils utils;
public NewsFeedArrayAdapter(Activity context) {
super(context, R.layout.feed_story_content);
this.utils = new Utils(context);
inflator = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = ImageLoader.getInstance(context);
}
/**
* Static Inner class.
*
* Makes the ListView more efficient since Android recycles views in a ListView.
*/
public static class ViewHolder {
public ImageView profilePicture, image;
public TextView author, timePast, message, likes, comments;
public LinearLayout like, comment, share, likesCommentsCounter;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = null;
FeedItem feedItem = FeedItemParser.FEEDS.get(position);
ViewHolder holder = null;
if (convertView == null) {
rowView = inflator.inflate(R.layout.feed_story_content, parent, false);
holder = new ViewHolder();
holder.profilePicture = (ImageView) rowView.findViewById(R.id.feed_story_profile_picture);
holder.author = (TextView) rowView.findViewById(R.id.feed_story_author);
holder.timePast = (TextView) rowView.findViewById(R.id.feed_story_time_past);
holder.message = (TextView) rowView.findViewById(R.id.feed_story_message);
holder.image = (ImageView) rowView.findViewById(R.id.feed_story_image);
holder.like = (LinearLayout) rowView.findViewById(R.id.feed_feedback_like_container);
holder.comment = (LinearLayout) rowView.findViewById(R.id.feed_feedback_comment_container);
holder.share = (LinearLayout) rowView.findViewById(R.id.feed_feedback_share_container);
holder.likes = (TextView) rowView.findViewById(R.id.feed_story_likes);
holder.comments = (TextView) rowView.findViewById(R.id.feed_story_comments);
rowView.setTag(holder);
} else {
rowView = convertView;
holder = ((ViewHolder) rowView.getTag());
}
Log.i(TAG_DEBUG, "feedItem = " + feedItem);
if (feedItem != null) {
if (!TextUtils.isEmpty(feedItem.feed_story_from_name)) {
holder.author.setText(feedItem.feed_story_from_name);
} else {
holder.author.setText("Unknown");
}
if (!TextUtils.isEmpty(feedItem.feed_story_created_time)) {
// Convert the date to calendar date
Calendar calendarDate = null;
try {
calendarDate = ISO8601.toCalendar(feedItem.feed_story_created_time);
} catch (ParseException e) {
e.printStackTrace();
}
CharSequence relativeTimeSpan = DateUtils.getRelativeTimeSpanString(
calendarDate.getTimeInMillis(),
System.currentTimeMillis(),
DateUtils.SECOND_IN_MILLIS);
holder.timePast.setText(relativeTimeSpan);
} else {
holder.timePast.setText("Unknown");
}
Log.i(TAG_DEBUG, "feedItem.feed_story_message = " + feedItem.feed_story_message);
if (!TextUtils.isEmpty(feedItem.feed_story_message)) {
holder.message.setText(feedItem.feed_story_message);
} else {
holder.message.setText("Unkown");
// holder.message.setVisibility(View.GONE);
}
// Display the icon of the feed
int defaultResourceIcon = R.drawable.no_avatar;
if (feedItem.feed_story_from_id != null) {
String iconUrl = "https://graph.facebook.com/" + feedItem.feed_story_from_id + "/picture?type=normal";
if (Session.getActiveSession() != null &&
Session.getActiveSession().getAccessToken() != null) {
iconUrl += "&access_token=" + Session.getActiveSession().getAccessToken();
}
Log.i(TAG_DEBUG, "iconUrl = " + iconUrl);
imageLoader.displayImage(iconUrl, holder.profilePicture, 70, defaultResourceIcon);
} else {
imageLoader.cancelDisplayTaskFor(holder.profilePicture);
holder.profilePicture.setImageResource(defaultResourceIcon);
}
// Display the picture of the feed
int defaultResourcePicture = R.drawable.empty;
if (!TextUtils.isEmpty(feedItem.feed_story_picture)) {
holder.image.setVisibility(View.VISIBLE);
Log.i(TAG_DEBUG, "feed_picture = " + feedItem.feed_story_picture + "\nfeed_picture_height = " + feedItem.feed_story_picture_height);
imageLoader.displayImage(feedItem.feed_story_picture, holder.image, -1, defaultResourcePicture);
} else {
imageLoader.cancelDisplayTaskFor(holder.image);
// holder.image.setImageResource(defaultResourcePicture);
holder.image.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(feedItem.feed_story_likes)) {
holder.likes.setVisibility(View.VISIBLE);
String likes = feedItem.feed_story_likes + " like";
if (!feedItem.feed_story_likes.contentEquals("1")) {
likes += "s";
}
holder.likes.setText(likes);
} else {
holder.likes.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(feedItem.feed_story_comments)) {
holder.comments.setVisibility(View.VISIBLE);
String comments = feedItem.feed_story_comments + " comment";
if (!feedItem.feed_story_comments.contentEquals("1")) {
comments += "s";
}
holder.comments.setText(comments);
} else {
holder.comments.setVisibility(View.GONE);
}
holder.like.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
utils.customToast("Like content - TBA");
}
});
holder.comment.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
utils.customToast("Comment section - TBA");
}
});
holder.share.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
utils.customToast("Sharing content - TBA");
}
});
}
return rowView;
}
#Override
public int getCount() {
return FeedItemParser.FEEDS.size();
}
}
The adapter on the list is set after the first request, when I get my first results, like this:
ListView actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
registerForContextMenu(actualListView);
// Sort the list before displaying
Collections.sort(FeedItemParser.FEEDS, Comparators.CREATED_TIME);
// Set the custom adapter
customAddapter = new NewsFeedArrayAdapter(activity);
// Populate the fragment with the data from JSON
actualListView.setAdapter(customAddapter);
FeedItemParser is an custom class where I store my custom objects:
public class FeedItemParser {
// JSON Node names
public static final String
TAG_DATA = "data", // Array
TAG_ID = "id", // String
TAG_FROM = "from", // Object
TAG_FROM_ID = "id", // String
TAG_FROM_CATEGORY = "category", // String
TAG_FROM_NAME = "name", // String
TAG_TO = "to", // Object
TAG_TO_DATA = "data", // Array
TAG_TO_DATA_ID = "id", // String
TAG_TO_DATA_NAME = "name", // String
TAG_MESSAGE = "message", // String
TAG_PICTURE = "picture", // String
TAG_ACTIONS = "actions", // Array
TAG_ACTIONS_NAME = "name", // String
TAG_ACTIONS_LINK = "link", // String
TAG_PRIVACY = "privacy", // Object
TAG_PRIVACY_VALUE = "value", // String
TAG_TYPE = "type", // String
TAG_STATUS_TYPE = "status_type", // String
TAG_CREATED_TIME = "created_time", // String
TAG_UPDATED_TIME = "updated_time", // String
TAG_LIKES = "likes", // Object
TAG_LIKES_COUNT = "count", // String
TAG_COMMENTS = "comments", // Object
TAG_COMMENTS_DATA = "data", // Array
TAG_PAGING = "paging", // Object
TAG_PAGING_PREVIOUS = "previous",// String
TAG_PAGING_NEXT = "next"; // String
/**
* An array of Shelter items.
*/
public static List<FeedItem> FEEDS = new ArrayList<FeedItem>();
/**
* A map of Array items, by ID.
*/
public static Map<String, FeedItem> FEED_MAP = new HashMap<String, FeedItem>();
public static void addItem(FeedItem item) {
FEEDS.add(FEEDS.size(), item);
FEED_MAP.put(item.feed_story_id, item);
}
public static void addPicture (String feed_story_id, String picture, String height) {
FeedItem feedItem = FEED_MAP.get(feed_story_id);
feedItem.feed_story_picture = picture;
feedItem.feed_story_picture_height = height;
}
public static class FeedItem {
public String feed_story_id, feed_story_from_id, feed_story_from_category,
feed_story_from_name, feed_story_message, feed_story_picture, feed_story_picture_height,
feed_story_privacy, feed_story_type, feed_story_status_type, feed_story_created_time,
feed_story_updated_time, feed_story_likes, feed_story_comments;
/**
* #param feed_story_id
* #param feed_story_from_id
* #param feed_story_from_category
* #param feed_story_from_name
* #param feed_story_message
* #param feed_story_picture
* #param feed_story_privacy
* #param feed_story_type
* #param feed_story_status_type
* #param feed_story_created_time
* #param feed_story_updated_time
*/
public FeedItem(String feed_story_id, String feed_story_from_id, String feed_story_from_category,
String feed_story_from_name, String feed_story_message, String feed_story_picture,
String feed_story_picture_height, String feed_story_privacy, String feed_story_type,
String feed_story_status_type, String feed_story_created_time, String feed_story_updated_time,
String feed_story_likes, String feed_story_comments) {
this.feed_story_id = feed_story_id;
this.feed_story_from_id = feed_story_from_id;
this.feed_story_from_category = feed_story_from_category;
this.feed_story_from_name = feed_story_from_name;
this.feed_story_message = feed_story_message;
this.feed_story_picture = feed_story_picture;
this.feed_story_picture_height = feed_story_picture_height;
this.feed_story_privacy = feed_story_privacy;
this.feed_story_type = feed_story_type;
this.feed_story_status_type = feed_story_status_type;
this.feed_story_created_time = feed_story_created_time;
this.feed_story_updated_time = feed_story_updated_time;
this.feed_story_likes = feed_story_likes;
this.feed_story_comments = feed_story_comments;
}
#Override
public String toString() {
return feed_story_message;
}
}
}
When I request new data(refresh), I add the new data in my object (the same way I do the first time):
FeedItemParser.addItem(new FeedItem(
id,
from_id,
from_category,
from_name,
message,
null, // Will be gotten through another request
null,
privacy_value,
type,
status_type,
created_time,
updated_time,
likes,
comments));
After that I call
ListView actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
registerForContextMenu(actualListView);
// Sort the list before displaying
Collections.sort(FeedItemParser.FEEDS, Comparators.CREATED_TIME);
// Notify list adapter to update the list
customAddapter.notifyDataSetChanged();
SOLUTION
Based on the recommendations of #Selvin I have managed to update my list after adding more data. Basically I changed my adapter(I'm not using an filtered list anymore, but I'm directly using my custom objects). And after I add new Object, I update the list by calling notifyDataSetChanged() on the existing adapter.
I have also update my code, maybe it will help someone else that is stuck is this situation.
Thanks again #Selvin.
Related
when i click + button increment the price and click - button decrease the price it's work perfectly but when i scroll listview the value of tvPrices (TextView) is changed.
What should i do for the stay increment price?
here is my adapter
public class ListAdapter extends BaseAdapter {
public ArrayList<Integer> quantity = new ArrayList<Integer>();
public ArrayList<Integer> price = new ArrayList<Integer>();
private String[] listViewItems, prices, static_price;
TypedArray images;
View row = null;
static String get_price, get_quntity;
int g_quntity, g_price, g_minus;
private Context context;
CustomButtonListener customButtonListener;
static HashMap<String, String> map = new HashMap<>();
public ListAdapter(Context context, String[] listViewItems, TypedArray images, String[] prices) {
this.context = context;
this.listViewItems = listViewItems;
this.images = images;
this.prices = prices;
for (int i = 0; i < listViewItems.length; i++) {
quantity.add(0);
price.add(0);
}
}
public void setCustomButtonListener(CustomButtonListener customButtonListner) {
this.customButtonListener = customButtonListner;
}
#Override
public int getCount() {
return listViewItems.length;
}
#Override
public String getItem(int position) {
return listViewItems[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListViewHolder listViewHolder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.activity_custom_listview, parent, false);
listViewHolder = new ListViewHolder();
listViewHolder.tvProductName = (TextView) row.findViewById(R.id.tvProductName);
listViewHolder.ivProduct = (ImageView) row.findViewById(R.id.ivproduct);
listViewHolder.tvPrices = (TextView) row.findViewById(R.id.tvProductPrice);
listViewHolder.btnPlus = (ImageButton) row.findViewById(R.id.ib_addnew);
listViewHolder.edTextQuantity = (EditText) row.findViewById(R.id.editTextQuantity);
listViewHolder.btnMinus = (ImageButton) row.findViewById(R.id.ib_remove);
static_price = context.getResources().getStringArray(R.array.Price);
row.setTag(listViewHolder);
} else {
row = convertView;
listViewHolder = (ListViewHolder) convertView.getTag();
}
listViewHolder.ivProduct.setImageResource(images.getResourceId(position, -1));
try {
listViewHolder.edTextQuantity.setText(quantity.get(position) + "");
} catch (Exception e) {
e.printStackTrace();
}
listViewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, 1);
quantity.set(position, quantity.get(position) + 1);
price.set(position, price.get(position) + 1);
row.getTag(position);
get_price = listViewHolder.tvPrices.getText().toString();
g_price = Integer.valueOf(static_price[position]);
get_quntity = listViewHolder.edTextQuantity.getText().toString();
g_quntity = Integer.valueOf(get_quntity);
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
listViewHolder.tvPrices.setText("" + g_price * g_quntity);
// Log.d("A ", "" + a);
// Toast.makeText(context, "A" + a, Toast.LENGTH_LONG).show();
// Log.d("Position ", "" + position);
// System.out.println(+position + " Values " + map.values());
ShowHashMapValue();
listViewHolder.tvPrices.setText("" + g_price * g_quntity);
}
}
});
listViewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, -1);
if (quantity.get(position) > 0)
quantity.set(position, quantity.get(position) - 1);
get_price = listViewHolder.tvPrices.getText().toString();
g_minus = Integer.valueOf(get_price);
g_price = Integer.valueOf(static_price[position]);
int minus = g_minus - g_price;
if (minus >= g_price) {
listViewHolder.tvPrices.setText("" + minus);
}
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
ShowHashMapValue();
}
}
});
listViewHolder.tvProductName.setText(listViewItems[position]);
listViewHolder.tvPrices.setText(prices[position]);
return row;
}
private void ShowHashMapValue() {
/**
* get the Set Of keys from HashMap
*/
Set setOfKeys = map.keySet();
/**
* get the Iterator instance from Set
*/
Iterator iterator = setOfKeys.iterator();
/**
* Loop the iterator until we reach the last element of the HashMap
*/
while (iterator.hasNext()) {
/**
* next() method returns the next key from Iterator instance.
* return type of next() method is Object so we need to do DownCasting to String
*/
String key = (String) iterator.next();
/**
* once we know the 'key', we can get the value from the HashMap
* by calling get() method
*/
String value = map.get(key);
System.out.println("Key: " + key + ", Value: " + value);
}
}
}
In onclick, after you decrement the value call notifyDataSetChanged()
notifyDataSetChanged
but its a costly operation, since it refreshes complete list
its my following code.
public class Wishlist extends Activity {
Button checkout;
ListView ListCart;
String name, cusid, ffname, llname, phone, fax, password, email;
String[] qu, s;
int[] g;
int k = 0;
String cost;
ProgressDialog pDialog = null;
List<CartProducts> product_list;
Context ctx;
Integer pos = 0, total = 0, q = 0, gtot = 0, total1 = 0, sum = 0;
SQLiteDatabase FavData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_modifywishlist);
Intent page1 = getIntent();
cusid = page1.getStringExtra("cus_id");
ffname = page1.getStringExtra("fname");
llname = page1.getStringExtra("lname");
phone = page1.getStringExtra("ph");
fax = page1.getStringExtra("fax");
password = page1.getStringExtra("password");
email = page1.getStringExtra("email");
ListCart = (ListView) findViewById(R.id.list_item);
pDialog = new ProgressDialog(this);
ctx = this;
FavData = Wishlist.this.openOrCreateDatabase("SHOPPING_CARTFAV", MODE_PRIVATE, null);
FavData.execSQL("CREATE TABLE IF NOT EXISTS fav_items(product_id varchar, name varchar, price varchar, quantity integer, model varchar, image varchar, manufacturer varchar )");
ArrayList<CartProducts> myList = new ArrayList<CartProducts>();
Cursor crsr = FavData.rawQuery("SELECT * FROM fav_items", null);
final String[] productID = new String[crsr.getCount()];
final String[] ProductName = new String[crsr.getCount()];
final String[] ProductPrice = new String[crsr.getCount()];
final String[] ProductQuantity = new String[crsr.getCount()];
final String[] ProductModel = new String[crsr.getCount()];
final String[] ProductImage = new String[crsr.getCount()];
final String[] ProductManufacturer = new String[crsr.getCount()];
int j = 0;
while (crsr.moveToNext()) {
String id = crsr.getString(crsr.getColumnIndex("product_id"));
productID[j] = id;//product_id,name,price,quantity,model,image,manufacturer
name = crsr.getString(crsr.getColumnIndex("name"));
ProductName[j] = name;
String price = crsr.getString(crsr.getColumnIndex("price"));
ProductPrice[j] = price;
String s = ProductPrice[j].toString();
s = s.replace(",", "");
String[] parts = s.split("\\."); // escape .
String part1 = parts[0];
String part2 = parts[1];
part1 = part1.replace("₹", "");
total = Integer.parseInt(part1); // Toast.makeText(Table.this, part1, Toast.LENGTH_SHORT).show();
String qnty = crsr.getString(crsr.getColumnIndex("quantity"));
ProductQuantity[j] = qnty;
String s2 = ProductQuantity[j].toString();
total1 = Integer.parseInt(s2);
sum = total * total1;
String model = crsr.getString(crsr.getColumnIndex("model"));
ProductModel[j] = model;
String image = crsr.getString(crsr.getColumnIndex("image"));
ProductImage[j] = image;
String manufacturer = crsr.getString(crsr.getColumnIndex("manufacturer"));
ProductManufacturer[j] = manufacturer;
//Toast.makeText(getApplicationContext(), productID[j] + "" + ProductName[j] + "" + ProductPrice[j] + "" + ProductQuantity[j] + "" + ProductModel[j] + "" + ProductImage[j] + "" + ProductManufacturer[j], Toast.LENGTH_SHORT).show();
myList.add(new CartProducts(productID[j], ProductName[j], ProductPrice[j], ProductQuantity[j], ProductModel[j], ProductImage[j], ProductManufacturer[j]));
gtot = gtot + sum;
j++;
}
ListCart.setAdapter(new Wishlist_Listadapter(ctx, R.layout.activity_wishlist_cartrow, myList));
getListViewSize(ListCart);
String s1 = ProductPrice.toString();
}
public static void getListViewSize(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
//do nothing return null
return;
}
//set listAdapter in loop for getting final size
int totalHeight = 0;
for (int size = 0; size < myListAdapter.getCount(); size++) {
View listItem = myListAdapter.getView(size, null, myListView);
if (listItem != null) {
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
}
//setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
if (params != null) {
params.height = totalHeight
+ (myListView.getDividerHeight() * (myListAdapter
.getCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
}
myListView.requestLayout();
// print height of adapter on log
Log.i("height of listItem:", String.valueOf(totalHeight));
}
}
Adapter class
Public class Wishlist_Listadapter extends ArrayAdapter<CartProducts> {
Bitmap bitmap;
ImageView img;
String urll, name,totalps;
SQLiteDatabase FavData;
Integer total = 0, quanty = 1, grandtot = 0, i = 0;
String it;
Button addbtn, minbtn;
EditText editqu;
int total1 = 0, quantity=0, fulltotal = 0, sum;
SQLiteOpenHelper dbhelper;
Wishlist_Listadapter cart = Wishlist_Listadapter.this;
private int resource;
private LayoutInflater inflater;
private Context context;
int count=1 ;
public Wishlist_Listadapter(Context ctx, int resourceId, List<CartProducts> objects) {
super(ctx, resourceId, objects);
resource = resourceId;
inflater = LayoutInflater.from(ctx);
context = ctx;
}
public View getView(int position, View convertView, ViewGroup parent) {
/* create a new view of my layout and inflate it in the row */
convertView = (RelativeLayout) inflater.inflate(resource, null);
final ViewHolder viewholder;
viewholder = new ViewHolder();
final CartProducts banqt = getItem(position);
totalps=(banqt.getPrice());
String s = totalps.toString();
s = s.replace(",", "");
String[] parts = s.split("\\."); // escape .
String part1 = parts[0];
String part2 = parts[1];
part1 = part1.replace("₹", "");// Toast.makeText(getContext(), part1, Toast.LENGTH_LONG).show();
total = Integer.parseInt(part1);
quanty = Integer.parseInt(banqt.getQuantity());
grandtot = total *quanty;
viewholder.total = (TextView) convertView.findViewById(R.id.txt_total);
viewholder.total.setText(String.valueOf(grandtot));
Button delet = (Button) convertView.findViewById(R.id.btn_remove);
delet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*delete function*/
it = banqt.getProduct_id();
FavData = context.openOrCreateDatabase("SHOPPING_CARTFAV", context.MODE_PRIVATE, null);
FavData.execSQL("DELETE FROM fav_items WHERE product_id=" + it + ";");
Intent intent = ((Wishlist) context).getIntent();
((Wishlist) context).finish();
context.startActivity(intent);
}
});
viewholder.txtName = (TextView) convertView.findViewById(R.id.product_name);
viewholder.txtName.setText(banqt.getName());
img = (ImageView) convertView.findViewById(R.id.img_product);
urll = banqt.getImage().toString();
urll = urll.replaceAll(" ", "%20");// Toast.makeText(getContext(),urll,Toast.LENGTH_LONG).show();
new LoadImage().execute(urll);
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView total;
EditText editqu;
TextView txtprice;
}
private class LoadImage extends AsyncTask<String, String, Bitmap> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Bitmap doInBackground(String... args) {
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
protected void onPostExecute(Bitmap image) {
if (image != null) {
img.setImageBitmap(image);
// pDialog.dismiss();
} else {
// pDialog.dismiss();
Toast.makeText(getContext(), "Image Does Not exist or Network Error", Toast.LENGTH_SHORT).show();
}
}
}
}
listview is working properly
i just inflate cardview in listview.
when using this code image cannot displaying. only dispaly last image in list view
params.height = totalHeight
+ (myListView.getDividerHeight() * (myListAdapter
.getCount() - 1));
my problem is: In listview only displaying last image
check this image:
Try adding your ImageView to Holder class and use like viewholder.img.setImageBitmap(new LoadImage().execute(urll)) and change the return type to Bitmap
Use BaseAdapter instead of ArrayAdapter. Load and show image with UIL, Picasso or other image loader library.
public class ImageAdapter extends BaseAdapter {
private List<ImageBean> list;
private ArrayList<ImageBean> arraylist;
private LayoutInflater inflater;
public ImageAdapter(Context context, List<ImageBean> list) {
this.list = list;
inflater = LayoutInflater.from(context);
this.arraylist = new ArrayList<>();
}
#Override
public int getCount() {
return list.size();
}
#Override
public ImageBean getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.recycler_view_item, parent, false);
holder.ivImage = (ImageView) convertView.findViewById(R.id.ivImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Loading image with UIL example
ImageLoader.getInstance().displayImage(getItem(position).getUrl(), holder.ivImage, ImageUtils.UIL_USER_AVATAR_DISPLAY_OPTIONS);
return convertView;
}
private class ViewHolder {
public ImageView ivImage;
}
}
I am new to android and my list view is not working correctly. The list displays all the data from an array list as a single row.
My MainActivity looks like this:
public class MainActivity extends FragmentActivity implements OnClickListener{
..
ArrayList<StorylineData> storylineData;
ArrayList<SummaryData> summary;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinnerAPI = (Spinner) findViewById(R.id.spinnerAPI);
mButtonSubmit = (Button) findViewById(R.id.buttonSubmit);
mEditTextResponse = (ListView) findViewById(R.id.editResponse);
mProgressRequest = (ProgressBar) findViewById(R.id.progressRequest);
mButtonSubmit.setOnClickListener(this);
storylineData = new ArrayList<StorylineData>();
...
#Override
public void onClick(View v) {
toggleProgress(true);
switch (mSpinnerAPI.getSelectedItemPosition()) {
case 0: // Authenticate
...
case 4: // Get Summary Day
MovesAPI.getSummary_SingleDay(summaryHandler, "20150418", null);//Date changed to "20150117"
break;
...
case 10: // Get Storyline Day
MovesAPI.getStoryline_SingleDay(storylineHandler, "20150418", "20140714T073812Z", false);//Date changed to "20150418" "null changed to"20140714T073812Z"
break;
...
toggleProgress(false);
break;
}
}
...
private MovesHandler<ArrayList<StorylineData>> storylineHandler = new MovesHandler<ArrayList<StorylineData>>() {
#Override
public void onSuccess(ArrayList<StorylineData> result) {
toggleProgress(false);
updateResponse(
"Date:\t" + result.get(0).getDate() + "\n"
+ "-----------Activity 1 Summary--------\t" + "\n"
+ "Activity:\t" + result.get(0).getActivity().toString() + "\n"//returns 1587 with .getCaloriesIdle()
...
+ "-----------Activity 2 Summary---------\t" + "\n"
+ "Activity:\t" + result.get(0).getSummary().get(0).getActivity() + "\n"//returns 1587 with .getCaloriesIdle()
...
+ "-----------Segments---------\t" + "\n"
+ "Type:\t" + result.get(0).getSegments().get(0).getType() + "\n"//returns 1587 with .getCaloriesIdle()
...
}
public void updateResponse(final String message) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mButtonSubmit.setText(message);
StorylineAdapter adapter = new StorylineAdapter(MainActivity.this, R.layout.item_storyline, storylineData);
mEditTextResponse.setAdapter(adapter);
}
});
}
}
My ArrayAdapter class looks like this:
public class StorylineAdapter extends ArrayAdapter<StorylineData> {
private Context context;
private ArrayList<StorylineData> storylineData;
public StorylineAdapter(Context context, int resource, ArrayList<StorylineData> objects) {
super(context, resource, objects);
this.context = context;
this.storylineData = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_storyline, parent, false);
//Display in the TextView widget
StorylineData storylineData1 = storylineData.get(position);
TextView tv = (TextView) view.findViewById(R.id.textView1);
tv.setText(storylineData1.getDistance());
return view;
}
#Override
public int getCount()
{
if (storylineData!=null)
{
return storylineData.size();
}
else
{
Log.e("Adapter", "Summary array is null");
return 0;
}
}
}
Here is my parser class:
public class StorylineData extends ArrayList<StorylineData> {
...Getters/Setters...
/**
* Parse a {#link org.json.JSONObject} from storyline {#link org.json.JSONArray}, then return the corresponding {#link StorylineData} object.
*
* #param jsonObject : the storyline JSON object received from server
* #return corresponding {#link StorylineData}
*/
public static StorylineData parse(JSONObject jsonObject) throws JSONException {
if (jsonObject != null) {
StorylineData storylineData = new StorylineData();
storylineData.date = jsonObject.optString("date");
storylineData.caloriesIdle = jsonObject.optInt("caloriesIdle");
storylineData.lastUpdate = jsonObject.optString("lastUpdate");
storylineData.summary = new ArrayList<SummaryData>();
storylineData.segments = new ArrayList<SegmentData>();
/**Get the data associated with the array named summary **To get a specific JSONArray: Summary*/
JSONArray summariesJsonArray = jsonObject.optJSONArray("summary");
if (summariesJsonArray != null)
for (int i = 0; i < summariesJsonArray.length(); i++) {
/**each time through array will need to get a reference of current object*/
JSONObject summaryJsonObject = summariesJsonArray.optJSONObject(i);
if (summaryJsonObject != null) {
/**===============Translate data from json to Java=================*/
/**Create a new OBJECT OF ARRAY STORYLINE/SUMMARY*/
ArrayList<SummaryData> summary = new ArrayList<SummaryData>(); // initialisation must be outside the loop
storylineData.setSummary(summary);
/**Get summary from json into java*/
summariesJsonArray.getJSONObject(i).getString("distance");
/**Get date from json into java*/
String date = summaryJsonObject.optString("date");
storylineData.setDate(date);
/**Get group from json into java*/
String group = summaryJsonObject.optString("group");//Get name using key e.g. date
storylineData.setGroup(group);
...
storylineData.summary.add(SummaryData.parse(summaryJsonObject));
Log.d("StorylineDataCls \t sJo", summaryJsonObject.toString() + "Log\n");
System.out.println("print distance" + summariesJsonArray.getJSONObject(i).getString("distance"));
System.out.println("print summary" + summaryJsonObject);
}
}
JSONArray segmentsJsonArray = jsonObject.optJSONArray("segments");
if (segmentsJsonArray != null) {
for (int i = 0; i < segmentsJsonArray.length(); i++) {
JSONObject segment = segmentsJsonArray.optJSONObject(i);
if (segment != null) {
ArrayList<SegmentData> segments = new ArrayList<SegmentData>(); // initialisation must be outside the loop
storylineData.setSegments(segments);
String type = segment.optString("type");
storylineData.setType(type);
...
storylineData.segments.add(SegmentData.parse(segment));
Log.d("StorylineDataCls \t sSo", segment.toString());
}
}
}
return storylineData;
}
return null;
}
}
After I decided to implement Universal Image Loader, because I had implemented a method that convert URL to Drawable, but since I don't know how many images it will return my SQLite query I decided to implement an Image Loader...
The thing is I'm stuck at the moment, cause I thought I did all what the GitHub say but at the time I load the Image it stays white and never loads.
On my Adapter class I've changed the line of the drawable as :
Picasso.with(context)
.load(Uri.parse(String.valueOf(item.icon)))
.resize(180, 180)
.placeholder(R.drawable.ic_launcher).into(viewHolder.ivIcon);
It works, beucase it shows yo me the ic_launcher icon... but never changes to the real image.
On my class where I fetch the data I have this (on my OnCreate()) :
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new MyAsyncTask().execute();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// progress.dismiss();
}
});
}
}).start();
}
Then I created an inner class where I fetch the data into my ListView... but it doesn't works. I don't know If I've to delte those methods since I've changed it to Picasso.
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
Conexion = new MarketSQLite(getActivity(), "market", null, 1);
mItems = new ArrayList<ListViewItem>();
db = Conexion.getReadableDatabase();
Cursor c;
c = db.rawQuery("Select NOM_OFER,PREU_OFERTA,DATA_F,FOTO,PERCENTDESCOMPTE from T_OFERTA", null);
c.moveToFirst();
if (c != null) {
do {
for (int i = 0; i < c.getColumnCount(); i++) {
Title = c.getString((c.getColumnIndex("NOM_OFER")));
Preu = c.getColumnIndex("PREU_OFERTA");
percent = c.getString((c.getColumnIndex("PERCENTDESCOMPTE")));
data_f = c.getString((c.getColumnIndex("DATA_F")));
URLTest = c.getString((c.getColumnIndex("FOTO")));
FOTO = Imagehandler(URLTest);
Log.e("", "" + c.getString(i));
// initialize and set the list adapter
// Toast.makeText(getActivity(), "Title" + Title + "Preu" + Preu + "Percent" + percent + "Cheese is " + data_f, Toast.LENGTH_LONG).show();
}
mItems.add(new ListViewItem(FOTO, Title, Preu.toString(), percent, data_f));
}while (c.moveToNext());
}
c.close();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
myAdapter = new ListViewDemoAdapter(getActivity(), mItems);
setListAdapter(myAdapter);
}
}
Where ImageHandler is a method that I've created before this is :
protected Drawable Imagehandler(String url) {
try {
url=url.replaceAll(" ", "%20");
InputStream is = (InputStream)this.fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e)
{
System.out.println(url);
System.out.println("error at URI"+e);
return null;
}
catch (IOException e)
{
System.out.println("io exception: "+e);
System.out.println("Image NOT FOUND");
return null;
}
}
protected Object fetch(String address) throws MalformedURLException,IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
I don't know why isn't the image loading on my ListView if it shows all of the rest of data...
Instead of Drawable, try to get url string in your adapter like
Change From
public ListViewItem(Drawable icon, String title, String precio, String descuento, String date) {
this.icon = icon;
this.title = title;
this.precio = precio;
this.descuento = descuento;
this.date = date;
}
To
public ListViewItem(String icon_url, String title, String precio, String descuento, String date) {
this.icon_url = icon_url;
this.title = title;
this.precio = precio;
this.descuento = descuento;
this.date = date;
}
and use Picasso where you are loading your imageview like this -
Picasso.with(context)
.load(icon_url))
.resize(180, 180)
.placeholder(R.drawable.ic_launcher).into(viewHolder.ivIcon);
1) Your ListViewItem class should be like this -
public class ListViewItem {
public final String icon; // the drawable for the ListView item ImageView
public final String title; // the text for the ListView item title
public final String precio; // the price for the ListView item
public final String descuento; // the price for the discount for the ListView item
public final String date; //the date for the sale for the ListView item
// the text for the ListView item description
public ListViewItem(String icon_url, String title, String precio, String descuento, String date) {
this.icon = icon_url;
this.title = title;
this.precio = precio;
this.descuento = descuento;
this.date = date;
}
}
2) ListViewDemoAdapterClass
public class ListViewDemoAdapter extends ArrayAdapter<ListViewItem> {
Context context;
public ListViewDemoAdapter(Context context, List<ListViewItem> items) {
super(context, R.layout.listview_item, items);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
// inflate the GridView item layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listview_item, parent, false);
// initialize the view holder
viewHolder = new ViewHolder();
viewHolder.ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
viewHolder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice);
viewHolder.tvDiscount = (TextView) convertView.findViewById(R.id.tvDiscount);
viewHolder.tvDate = (TextView) convertView.findViewById(R.id.tvDatas);
convertView.setTag(viewHolder);
} else {
// recycle the already inflated view
viewHolder = (ViewHolder) convertView.getTag();
}
// update the item view
ListViewItem item = getItem(position);
Picasso.with(context)
.load(item.icon)
.resize(180, 180)
.placeholder(R.drawable.ic_launcher).into(viewHolder.ivIcon);
viewHolder.tvTitle.setText(item.title);
viewHolder.tvDiscount.setText(item.descuento);
viewHolder.tvPrice.setText(item.precio);
viewHolder.tvDate.setText(item.date);
return convertView;
}
private static class ViewHolder {
ImageView ivIcon;
TextView tvTitle;
TextView tvDiscount;
TextView tvPrice;
TextView tvDate;
}
}
ListFragment code, just add this
Cursor c;
c = db.rawQuery("Select
NOM_OFER,PREU_OFERTA,DATA_F,FOTO,PERCENTDESCOMPTE from T_OFERTA", null);
c.moveToFirst();
if (c != null) {
do {
for (int i = 0; i < c.getColumnCount(); i++) {
Title = c.getString((c.getColumnIndex("NOM_OFER")));
Preu = c.getColumnIndex("PREU_OFERTA");
percent = c.getString((c.getColumnIndex("PERCENTDESCOMPTE")));
data_f = c.getString((c.getColumnIndex("DATA_F")));
URLTest = c.getString((c.getColumnIndex("FOTO")));
Hope this helps :)
you just need to add your picasso code snippet as the following in your ImageHandler method and nothing else-
Picasso.with(context)
.load(url))
.resize(180, 180)
.placeholder(R.drawable.ic_launcher).into(your_imageview);
you don't need to download the image or make the bitmap or convert that into drawable to load from url. hope this helps you.
I want to the change the text of the button which was clicked in a getView function. The text is changed but when the view is scrolled the text of other buttons which the same id is also changed. I don't want that. I want only the text of the button which was clicked to be changed.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int i=position;
List dialog = DialogList.get(i);
final Object memid = dialog.get(2).toString();
final String dialogid = dialog.get(3).toString();
final String dialogtype = dialog.get(4).toString();
ImageView imageViews;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(getContext());
convertView = layoutInflator.inflate(R.layout.invite_friends_list, null);
holder = new ViewHolder();
holder.friendsname = (TextView) convertView.findViewById(R.id.friendsname);
holder.profimage = (ImageView) convertView.findViewById(R.id.member_image);
holder.assign = (Button) convertView.findViewById(R.id.btnInvite);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
holder.friendsname.setText(user_name);
holder.assign.setTag(holder);
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("assigntext", holder.assign.getText().toString());
SharedPreferences prfs = _context.getSharedPreferences("MyPref",
Context.MODE_PRIVATE);
String token = prfs.getString("apptoken", "");
String url = null;
if(dialogtype.equals("V"))
{
url = "http://www.jjhjjkh.com/index.php?/alkjlkjlk/dialog/invjlkjlkjklialogmember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
if(dialogtype.equals("P"))
{
url = "http://www.ckjhuihiuhiu.com/index.php?/kjij/dialog/inviuhuihuihuimember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
List<String> urlList = new ArrayList<String>();
Log.d("cat",url.toString());
// JSON Node names
String TAG_DETAILS = "invitemembers";
String TAG_MSG = "msg";
// contacts JSONArray
JSONArray dialogpublish = null;
JSONArray dialogs = null;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
// Log.d("cat",json.toString());
try {
dialogpublish = json.getJSONArray(TAG_DETAILS);
// Log.d("apptoken",login.toString());
for (int i = 0; i < dialogpublish.length(); i++) {
JSONObject d = dialogpublish.getJSONObject(i);
String msg = d.getString(TAG_MSG);
//dialogs = d.getJSONArray("updatedialog");
if (msg.equals("success")) {
// ViewHolder mH = (ViewHolder)view.getTag();
//Integer currentPos = view.getTag();
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
ViewHolder mH = (ViewHolder)view.getTag();
mH.assign.setText("Invited");
}
//view.setText("Invited");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
I guess that is happenning because you are using the viewholder pattern. The viewholder pattern tends to cache views for performance optimization. try to write the adapter without using viewholder. If the list view items arent large in numbers.
Create a new HashMap in Adapter :
private HashMap<Integer, String> buttonTitleMap=new HashMap<Integer, String>();
Create a function getButtonTitle as below in Adapter :
private String getButtonTitle(int position){
if(buttonTitleMap.containsKey(position)){
return buttonTitleMap.get(position);
}else{
return "Your Normal Button text";
}
}
Then in getView() of Adapter, befor returning convertView, call :
....
holder.assign.setText(getButtonTitle(position));
holder.friendsname.setTag(position);
return convertView;
}
When the Button is clicked, you can get the list item position of the button. So what you need to do is to change the button title as you do before and also update the hashmap with the same value :
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
....
mH.assign.setText("Invited");
int position = (int)mH.friendsname.getTag();
buttonTitleMap.put(position,"Invited");
....
}
}
You are done.
Try
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
((Button)view).setText("Invited");
}