Loading images in listview asynchronously with callback - java

I'm using Parse in my app, and in order to load my 'profile' images, I need to retrieve a so called Parsefile. When the Parsefile is downloaded it uses a callback to notify when it's done. Now this is generally a nice way to do things but I encountered a problem with this when using a Listview and downloading the images with an Asynctask.
The problem is as follows:
In my ListView adapter in the getView method, I create an AsyncTask and execute it, this AsyncTask starts the retrieveProfileImage(callBack) function. In my callback I simply start a Runnable on the UI thread to update the ImageView in the View with the new (retrieved Image). The problem however as it seems, is the fact that as soon as I start my AsyncTask, the View is returned. So I can't set the other images to the correct row. I hope my code demonstrates my problem more clearly.
The ListAdapter:
public class FriendListAdapter extends ArrayAdapter<Profile> {
private int resource;
private Context context;
private List<Profile> friends;
private Profile fProfile;
private Bitmap profileImageBitmap;
private ProgressBar friendImageProgressBar;
//ui
private ImageView friendImage;
public FriendListAdapter(Context context, int resource,
List<Profile> objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.friends = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView friendName = null;
friendImage = null;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
rowView = inflater.inflate(R.layout.friendslist_row, null);
friendName = (TextView) rowView.findViewById(R.id.fName);
friendImage = (ImageView) rowView
.findViewById(R.id.fImage);
friendImageProgressBar = (ProgressBar) rowView.findViewById(R.id.friendImageProgressBar);
} else {
friendName = (TextView) convertView.findViewById(R.id.fName);
friendImage = (ImageView) convertView.findViewById(R.id.fImage);
friendImageProgressBar = (ProgressBar) convertView.findViewById(R.id.friendImageProgressBar);
}
fProfile = friends.get(position);
DownloadProfileImage dImg = new DownloadProfileImage();
dImg.execute();
friendName.setText(fProfile.getName());
return rowView;
}
private class DownloadProfileImage extends AsyncTask<Void, Integer, String> {
#Override
protected String doInBackground(Void... arg0) {
Log.d("logpp", "Starting download image for " + fProfile.getName());
fProfile.retrieveProfileImage(new ProfileImageCallback());
return null;
}
}
private class ProfileImageCallback extends GetDataCallback {
#Override
public void done(byte[] bytearray, ParseException e) {
if (e == null) {
Log.d("logpp", "Done downloading image for " + fProfile.getName() + ". Setting bitmap to:" +
" " + friendImage.getId());
profileImageBitmap = BitmapManager
.getBitmapFromByteArray(bytearray);
((Activity) context).runOnUiThread(new UpdateUi());
}
}
}
private class UpdateUi implements Runnable {
#Override
public void run() {
friendImage.setImageBitmap(profileImageBitmap);
friendImage.setVisibility(View.VISIBLE);
friendImageProgressBar.setVisibility(View.INVISIBLE);
}
}
}
The retrieveProfileImage method:
public void retrieveProfileImage(GetDataCallback callBack) {
this.image.getDataInBackground(callBack);
}
I hope someone can help me with this one.
Regards,
Tim

i solved this problem by following code
public View getView(int position, View convertView, ViewGroup parent) {
try {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.answer_item, null);
TextView name = (TextView) convertView.findViewById(R.id.textView_ans_user_name);
TextView body = (TextView) convertView.findViewById(R.id.textView_ans_user_body);
TextView timestamp = (TextView) convertView.findViewById(R.id.textView_ans_user_timestamp);
final CircularImageView thumbnail = (CircularImageView) convertView.findViewById(R.id.imageView_ans_user);
Parse_answer_model ans = answers.get(position);
name.setText(ans.getAns_by());
body.setText(ans.getAns_body());
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
sdfAmerica.setTimeZone(TimeZone.getDefault());
String sDateInAmerica = sdfAmerica.format(ans.getCreatedAt());
timestamp.setText(sDateInAmerica);
ParseQuery<User> query = ParseQuery.getQuery("_User");
query.whereEqualTo("username", ans.getAns_by());
query.getFirstInBackground(new GetCallback<User>() {
public void done(User user, ParseException e) {
// TODO Auto-generated method stub
if (e == null) {
img.DisplayImage(user.getprofile_pic_url(), thumbnail, false);
} else {
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
put your imageview as final dont make it global and you get image url from geturl() method, it is as defined by parse you can use below example
ParseFile fileObject = (ParseFile) object.get("image_file");
User user = new User();
user = (User) ParseUser.getCurrentUser();
user.setProfile_pic_url(fileObject.getUrl().toString());
user.saveInBackground();
update
last day i found new solution you can get user's data which related to parse object by following code and made some changes in model class,too.
void getchats() {
pd.show();
ParseQuery<Parse_chat_dialogs> query = ParseQuery.getQuery("chat_dialogs");
query.addDescendingOrder("updatedAt");
query.whereContains("users", ParseUser.getCurrentUser().getUsername());
query.findInBackground(new FindCallback<Parse_chat_dialogs>() {
public void done(List<Parse_chat_dialogs> dilogs, ParseException e) {
if (e == null) {
pd.hide();
dialoglist = (ArrayList<Parse_chat_dialogs>) dilogs;
adp = new ChatDialogAdapter(Chat_list.this, dialoglist);
list.setAdapter(adp);
for (int i = 0; i < dialoglist.size(); i++) {
ParseQuery<User> query = ParseQuery.getQuery("_User");
query.whereEqualTo("username", dialoglist.get(i).getUsers().trim()
.replace(ParseUser.getCurrentUser().getUsername(), "").replace(",", ""));
User user = new User();
try {
user = query.getFirst();
dialoglist.get(i).setFirstname(user.getFirstname());
dialoglist.get(i).setLastname(user.getLastname());
dialoglist.get(i).setProfileurl(user.getprofile_pic_url());
adp.notifyDataSetChanged();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} else {
Toast.makeText(Chat_list.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
as in above example i added three new param in parseobejct model class for storing values of user's firstname ,lastname and profile url.
i am also sharing model class for getting more idea
#ParseClassName("chat_dialogs")
public class Parse_chat_dialogs extends ParseObject {
private String firstname;
private String lastname;
private String profileurl;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getProfileurl() {
return profileurl;
}
public void setProfileurl(String profileurl) {
this.profileurl = profileurl;
}
/////////////////////////////////////////////////////////////////////////////
public String getLast_message() {
return getString("last_message");
}
public void setLast_message(String value) {
put("last_message", value);
}
public String getUsers() {
return getString("users");
}
public void setUsers(String value) {
put("users", value);
}
}

How about this!
Instead of using AsyncTask in the adapter class, use it in the MainActivity where you set the adapter for the listview. And in your done method in the Callback or the postExecute update the object/objects and call notifyDataSetChanged().
So, essentially you could have an update method in your adapter class, say, like this,
public void updateObject(int pos, byte[] byteArray){
//Assuming your Profile Object has some member to store this image data
friends.get(pos).setImageData(byteArray); //friends is the list in adapter class and setImageData may be the setter in your Profile object class
notifyDataSetChanged();
}
and in the getView(), you could do something like this
profileImageBitmap = BitmapManager
.getBitmapFromByteArray(friends.get(pos).getImageData);
friendImage.setImageBitmap(profileImageBitmap);

Related

Updating RecyclerView data slows down the UI of the activity

I am working on a chat application and I am having some problems displaying the chat messages. For storage I'm using a Room database and in order to display the messages I'm using a RecyclerView. The problem is that the activity gets very slow and not so responsive on scrolling through messages.
Here is my code:
ChatActivity.java
public class ChatActivity extends AppCompatActivity {
public static final String TAG = ChatActivity.class.getSimpleName();
public static Contact contact;
public static boolean isContactConnected;
private CircleImageView mContactPicture;
private ImageView mContactConnected;
private TextView mContactName;
private TextView mContactStatus;
private ChatAdapter mChatAdapter;
private RecyclerView mRecyclerView;
private EmojiconEditText mUserMessageInput;
private View rootView;
private ImageView emojiImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
initializeToolbar();
String contactPhone = Objects.requireNonNull(getIntent().getStringExtra("phone"));
contact = MainActivity.db.getContactDao().findByPhone(contactPhone);
if (MainActivity.notificationMessages.get(contact.getId()) != null) {
MainActivity.notificationMessages.put(contact.getId(), new ArrayList<Message>());
}
updateUI(contact);
initializeViews();
initializeRecyclerView();
EmojIconActions emojIconActions = new EmojIconActions(this, rootView, mUserMessageInput, emojiImageView);
emojIconActions.ShowEmojIcon();
emojIconActions.setIconsIds(R.drawable.ic_baseline_keyboard_24, R.drawable.ic_baseline_emoji_emotions_24);
mChatAdapter = new ChatAdapter(this, new ArrayList<Message>());
mRecyclerView.setAdapter(mChatAdapter);
MainActivity.db.getMessageDao().getLiveMessages(contactPhone).observe(this, new Observer<List<Message>>() {
#Override
public void onChanged(List<Message> newMessages) {
mChatAdapter.setMessages(newMessages);
mRecyclerView.scrollToPosition(newMessages.size() - 1);
}
});
}
[...]
private void updateUI(Contact contact) {
mContactName.setText(contact.getName());
if (!contact.isConnected()) {
Date currentTime = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.US);
isContactConnected = false;
mContactStatus.setText(
String.format(
"Last seen %s",
DateManager.getLastActiveText(
df.format(currentTime),
contact.getLastActive()
)
)
);
mContactConnected.setVisibility(View.GONE);
Log.d(TAG, "updateUI: initialized contact UI as disconnected");
} else {
mContactStatus.setText(R.string.active_now);
mContactConnected.setVisibility(View.VISIBLE);
isContactConnected = true;
Log.d(TAG, "updateUI: initialized contact UI as connected");
}
if (contact.getPhotoUri() != null) {
Uri imageUri = Uri.parse(contact.getPhotoUri());
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
mContactPicture.setImageBitmap(bitmap);
Log.d(TAG, "updateUI: loaded contact photo from device");
} catch (IOException e) {
Toast.makeText(
ChatActivity.this,
"Failed to load image from device.",
Toast.LENGTH_SHORT
).show();
e.printStackTrace();
}
}
}
[...]
private void initializeRecyclerView() {
mRecyclerView = findViewById(R.id.chat_recycler_view);
RecyclerView.LayoutManager layoutManager =
new LinearLayoutManager(ChatActivity.this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
Log.d(TAG, "initializeRecyclerView: initialized RecyclerView");
}
[...]
}
AppDatabase.java
#Database(entities = {Contact.class, Message.class}, version = 1)
#TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract ContactDao getContactDao();
public abstract MessageDao getMessageDao();
}
MessageDao.java
#Dao
public interface MessageDao {
#Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp")
List<Message> getMessages(String contact);
#Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp")
LiveData<List<Message>> getLiveMessages(String contact);
#Query("SELECT * FROM messages WHERE to_from =:contact AND status = 0")
List<Message> getUndeliveredMessages(String contact);
#Query("SELECT * FROM messages WHERE payloadId = :payloadId LIMIT 1")
Message getMessageByPayloadId(long payloadId);
#Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp DESC LIMIT 1")
Message getLastMessage(String contact);
#Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp DESC LIMIT 1")
LiveData<Message> getLastLiveMessage(String contact);
#Query("DELETE FROM messages")
void deleteAllMessages();
#Insert
void addMessage(Message message);
#Update
void updateMessage(Message message);
#Delete
void deleteMessage(Message message);
}
ChatAdapter.java
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<Message> messages;
public ChatAdapter(Context context, List<Message> messages) {
this.mContext = context;
this.messages = messages;
}
#Override
public int getItemViewType(int position) {
Message message = messages.get(position);
int status = message.getStatus();
if (status == Message.RECEIVED) {
return 0;
} else {
return 1;
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == 0) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_message_item, parent, false);
return new ChatUserViewHolder(itemView);
}
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_message_item2, parent, false);
return new ChatOtherViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Message currentMessage = messages.get(position);
String messageContent = currentMessage.getContent();
Date date = currentMessage.getTimestamp();
SimpleDateFormat ft = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.US);
Date currentDate = Calendar.getInstance().getTime();
switch (getItemViewType(position)) {
case 0:
ChatUserViewHolder mHolder = (ChatUserViewHolder) holder;
Contact sender = MainActivity.db.getContactDao().findByPhone(currentMessage.getToFrom());
if (sender.getPhotoUri() != null) {
Uri imageUri = Uri.parse(sender.getPhotoUri());
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), imageUri);
mHolder.getSenderProfilePicture().setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
mHolder.getSenderName().setText(sender.getName());
mHolder.getMessageContent().setText(messageContent);
mHolder.getTimestamp().setText(DateManager.getLastActiveText(ft.format(currentDate), ft.format(date)));
break;
case 1:
ChatOtherViewHolder nHolder = (ChatOtherViewHolder) holder;
SharedPreferences sharedPreferences = mContext.getSharedPreferences("LOGIN_DETAILS", MODE_PRIVATE);
String name = sharedPreferences.getString("name", "");
String photoUri = sharedPreferences.getString("photoUri", null);
if (photoUri != null) {
Uri imageUri = Uri.parse(photoUri);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), imageUri);
nHolder.getSenderProfilePicture().setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
nHolder.getSenderName().setText(name);
nHolder.getMessageContent().setText(messageContent);
nHolder.getTimestamp().setText(DateManager.getLastActiveText(ft.format(currentDate), ft.format(date)));
if (currentMessage.getStatus() == Message.SENT) {
nHolder.getMessageStatus().setImageResource(R.drawable.ic_baseline_done_24);
} else {
nHolder.getMessageStatus().setImageResource(R.drawable.ic_baseline_done_all_24);
}
break;
default:
break;
}
}
#Override
public int getItemCount() {
return messages.size();
}
public void setMessages(List<Message> messages) {
if (this.messages.size() > 0) {
this.messages.clear();
}
this.messages = messages;
notifyDataSetChanged();
}
ChatItemViewHolder.java
class ChatItemViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mUserProfilePic;
private ImageView mUserStatus;
private TextView mUserProfileName;
private EmojiconTextView mLastMessage;
private TextView mTimestamp;
public ChatItemViewHolder(#NonNull View itemView) {
super(itemView);
mUserProfilePic = itemView.findViewById(R.id.contact_image_item);
mUserProfileName = itemView.findViewById(R.id.contact_name_item);
mUserStatus = itemView.findViewById(R.id.status);
mLastMessage = itemView.findViewById(R.id.contact_status_item);
mTimestamp = itemView.findViewById(R.id.timestamp);
}
public CircleImageView getUserProfilePic() {
return mUserProfilePic;
}
public ImageView getUserStatus() {
return mUserStatus;
}
public TextView getUserProfileName() {
return mUserProfileName;
}
public EmojiconTextView getLastMessage() {
return mLastMessage;
}
public TextView getTimestamp() {
return mTimestamp;
}
}
ChatOtherViewHolder.java
class ChatOtherViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mSenderProfilePicture;
private TextView mSenderName;
private EmojiconTextView mMessageContent;
private TextView mTimestamp;
private ImageView mMessageStatus;
public ChatOtherViewHolder(#NonNull View itemView) {
super(itemView);
mSenderProfilePicture = itemView.findViewById(R.id.sender_profile_pic);
mSenderName = itemView.findViewById(R.id.sender_name);
mMessageContent = itemView.findViewById(R.id.message_content);
mTimestamp = itemView.findViewById(R.id.message_timestamp);
mMessageStatus = itemView.findViewById(R.id.message_status);
}
public CircleImageView getSenderProfilePicture() {
return mSenderProfilePicture;
}
public TextView getSenderName() {
return mSenderName;
}
public EmojiconTextView getMessageContent() {
return mMessageContent;
}
public TextView getTimestamp() {
return mTimestamp;
}
public ImageView getMessageStatus() {
return mMessageStatus;
}
}
Clearly the problem comes from the RV. Initially I thought that the observe method running on the UI thread could be causing problems, but I replaced the action in the onChanged method and the UI is very smooth, so the problem occurs only when I try updating the RV items.
What can I do to solve this issue?
There are two big issues I see
Never do database calls in your adapter, database calls are too expensive to use in there.
You are also loading entire bitmaps into memory, use an image loading library like Glide to load images, they handle recycled view and resizing the image to what they need to be along with asynchronous loading

Images dissapearing while scrolling Listiew (Android Studio)

guys.
I'm totally new to programming and Android programming and I have a problem. I fetch images from MySQL database as InputStream. Then I have Adapter where I load data, that I got from database, to corresponding objects. Hooray, listView is created and everything looks good! But... When I scroll down/up my images dissapear. I've read that listView recycles objects, but the problem is that I don't know/understand how can I fix this problem :///
Please help me guys !!
SHORT: images dissapear in listView on scroll. Too much newbie to understand how to fix it :/
Event class
public class Event {
private int id;
private String title;
private Date date;
private String place;
private String genre;
private String description;
private Double price;
public Event(int id, String title, Date date, String place, String genre, String description, Double price, InputStream image) {
this.id = id;
this.title = title;
this.date = date;
this.place = place;
this.genre = genre;
this.description = description;
this.price = price;
this.image = image;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public InputStream getImage() {
return image;
}
public void setImage(InputStream image) {
this.image = image;
}
private InputStream image;
}
Adapter Class
public class EventAdapter extends BaseAdapter {
LayoutInflater mInflater;
ArrayList<Event> data;
public EventAdapter(Context c, ArrayList<Event> d){
mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.data = d;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
// This is where data is assigned to coresponding fields in event_layout
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Hooks
View view = mInflater.inflate(R.layout.event_layout, null);
TextView eventName = (TextView) view.findViewById(R.id.eventName);
TextView dateYear = (TextView) view.findViewById(R.id.dateYear);
TextView dateDay = (TextView) view.findViewById(R.id.dateDay);
ImageView image = (ImageView) view.findViewById(R.id.eventImage);
// Changing date format
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
String date = sdf.format(data.get(position).getDate());
// Extracting date into seprate vars
String year = date.substring(8);
String day = date.substring(0, 1).toUpperCase() + date.substring(1, 3) + "." + date.substring(4, 7) + "d.";
// making Bitmap from InputStream
Bitmap bmp = BitmapFactory.decodeStream(data.get(position).getImage());
eventName.setText(data.get(position).getTitle());
dateYear.setText(year);
dateDay.setText(day);
image.setImageBitmap(bmp);
return view;
}
}
EventsPage class
public class EventsPage extends AppCompatActivity {
private EventAdapter eventAdapter;
private Context thisContext;
private ListView eventsListView;
private TextView progressBar;
private ArrayList<Event> events = new ArrayList<Event>();
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
// Set status bar color to main_green
if(Build.VERSION.SDK_INT >= 21){
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window.setStatusBarColor(this.getResources().getColor(R.color.main_green_color , this.getTheme()));
}
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_events_page);
Resources res = getResources();
eventsListView = (ListView) findViewById(R.id.eventsListView);
progressBar = (TextView) findViewById(R.id.progressBar);
thisContext = this;
progressBar.setText("");
GetData data = new GetData();
data.execute("");
}
public class GetData extends AsyncTask<String, String, String> {
private String msg;
private ArrayList<Event> bkc_events = new ArrayList<>();
private ArrayList<Event> tic_events = new ArrayList<>();
#Override
protected void onPreExecute(){
progressBar.setText("Connecting to database...");
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected String doInBackground(String... strings) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(DBstrings.JDBC_DRIVER);
conn = DriverManager.getConnection(DBstrings.URL, DBstrings.USERNAME, DBstrings.PASSWORD);
// Get BKC events
stmt = conn.createStatement();
String query = "SELECT * from `bkc_event` ORDER by `date` ASC";
ResultSet res = stmt.executeQuery(query);
while(res.next()){
Event temp = new Event(res.getInt("ID"), res.getString("title"),
res.getDate("date"), res.getString("place"),
res.getString("genre"), res.getString("description"),
res.getDouble("price"), res.getBinaryStream("image"));
this.bkc_events.add(temp);
}
res.close();
// Get TIC events
query = "SELECT * from `tic_event` ORDER by `date` ASC";
res = stmt.executeQuery(query);
while(res.next()){
Event temp = new Event(res.getInt("ID"), res.getString("title"),
res.getDate("date"), res.getString("place"),
res.getString("genre"), res.getString("description"),
res.getDouble("price"), res.getBinaryStream("image"));
tic_events.add(temp);
}
res.close();
stmt.close();
conn.close();
msg = "Process Completed";
PutDataTogether(bkc_events, tic_events);
} catch (ClassNotFoundException ex) {
msg = "Class not found ERROR";
Log.e("ClassNotFound", ex.getMessage());
} catch (SQLException ex) {
msg = "SQL exceltion";
Log.e("SQL:", ex.getMessage());
} finally {
try {
if(stmt != null)
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
// Combine data 2 sets into 1 set
#RequiresApi(api = Build.VERSION_CODES.N)
private void PutDataTogether(ArrayList<Event> bkc, ArrayList<Event> tic){
events.addAll(bkc);
for (Event t: tic) {
// counter for showing redundancy
int counter = 0;
for(Event r: events){
// Check if title and date is the same if so - increase counter by 1
if(t.getTitle().toLowerCase().equals(r.getTitle().toLowerCase()) &&
t.getDate().equals(r.getDate()))
counter++;
}
// if counter == 0, then we can add event to final result set
if(counter == 0)
events.add(t);
}
events.sort(Comparator.comparing(Event::getDate));
}
// To show the data
#Override
protected void onPostExecute(String msg){
progressBar.setText(this.msg);
/*new Handler().postDelayed(new Runnable() {
#Override
public void run() {
progressBar.setVisibility(View.INVISIBLE);
}
}, 1500); */
// We have stuff to display
if(events.size() > 0){
eventAdapter = new EventAdapter(thisContext, events);
eventsListView.setAdapter(eventAdapter);
}
}
} // END of GetDataEvents class
} // END of EventsPage
The problem:
Picture before scrolling
Picture after scrolling down and then back up
The issue is within the getView() method of your adapter. Recycling in a ListView means, that there is already an existing View which will be used to display your values, so you must not inflate a new one. Change your code like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Hooks
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.event_layout, null);
}
TextView eventName = (TextView) view.findViewById(R.id.eventName);
TextView dateYear = (TextView) view.findViewById(R.id.dateYear);
TextView dateDay = (TextView) view.findViewById(R.id.dateDay);
ImageView image = (ImageView) view.findViewById(R.id.eventImage);
// Changing date format
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
String date = sdf.format(data.get(position).getDate());
// Extracting date into seprate vars
String year = date.substring(8);
String day = date.substring(0, 1).toUpperCase() + date.substring(1, 3) + "." + date.substring(4, 7) + "d.";
// making Bitmap from InputStream
Bitmap bmp = BitmapFactory.decodeStream(data.get(position).getImage());
eventName.setText(data.get(position).getTitle());
dateYear.setText(year);
dateDay.setText(day);
image.setImageBitmap(bmp);
return view;
}
Note I only changed the first 4 lines of the method to use the provided View which comes from the ListView and only inflate a new one when there is no existing to reuse.

Using getShortClassName() method in Android

I'm trying to modify an application to use the getShortClassName() method instead of displaying the full class name (e.g. "com.google.app.MainActivity" to simply ".MainActivity"). The current setup gives me no errors but doesn't display the text.
I presume the solution is not complicated, although I just don't have the experience to make it work. Help?
#Override
public View getChildView (int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
MyActivityInfo activity = (MyActivityInfo)getChild(groupPosition, childPosition);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.all_activities_child_item, null);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
text1.setText(activity.getName());
//TextView text2 = (TextView) view.findViewById(android.R.id.text2);
//text2.setText(activity.getComponentName().getClassName());
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
text2.setText(activity.getShortClassName());
ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
icon.setImageDrawable(activity.getIcon());
return view;
}
public class MyActivityInfo implements Comparable<MyActivityInfo> {
public MyActivityInfo(ComponentName activity, PackageManager pm) {
this.component_name = activity;
ActivityInfo act;
try {
act = pm.getActivityInfo(activity, 0);
this.name = act.loadLabel(pm).toString();
try {
this.icon = (BitmapDrawable)act.loadIcon(pm);
}
catch(ClassCastException e) {
this.icon = (BitmapDrawable)pm.getDefaultActivityIcon();
}
this.icon_resource = act.getIconResource();
} catch (NameNotFoundException e) {
this.name = activity.getShortClassName();
this.icon = (BitmapDrawable)pm.getDefaultActivityIcon();
this.icon_resource = 0;
}
this.icon_resource_name = null;
if(this.icon_resource != 0) {
try {
this.icon_resource_name = pm.getResourcesForActivity(activity).getResourceName(this.icon_resource);
} catch (Exception e) {}
}
}
public ComponentName getComponentName() {
return component_name;
}
public BitmapDrawable getIcon() {
return icon;
}
public String getName() {
return name;
}
public String getIconResourceName() {
return icon_resource_name;
}
public String getShortClassName() {
return class_name;
}
protected ComponentName component_name;
protected BitmapDrawable icon;
protected int icon_resource;
protected String icon_resource_name;
protected String name;
protected String class_name;
#Override
public int compareTo(MyActivityInfo another) {
int cmp_name = this.name.compareTo(another.name);
if (cmp_name != 0) return cmp_name;
int cmp_component = this.component_name.compareTo(another.component_name);
return cmp_component;
}
#Override
public boolean equals(Object other) {
if(!other.getClass().equals(MyPackageInfo.class)) {
return false;
}
MyActivityInfo other_info = (MyActivityInfo)other;
return this.component_name.equals(other_info.component_name);
}
}
You could just use getSimpleName() method of class object:
String a = "Hello";
System.out.println(a.getClass().getSimpleName());
System.out.println(a.getClass().getName());
Output:
String
java.lang.String

ListView Refresh with web service Response in android

I have problem to set data into listview. Problem occurs after set message, message is set first after come 8th message from thread.
**below is my whole code :****(Here is my "Activity and adapter")**
public class Inboxreadmsg extends ActionBarActivity {
// <strong>Here is my global variable</strong>
ListView lv;
Handler h;
Custom_Inbox_Adapter ccAdpt;
Custom_Inbox_Adapter inadapter;
Runnable checker;
List<Dataset> dataset;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.messagesublistlayout);
// map id from layout</strong>
lv =(ListView)findViewById(R.id.readmessagelist);
/*****************************call thread of webservice with database****************************/
runThread();
startHandler();
/*****************************call thread of webservice with database****************************/
}
public void runThread()
{
h=new Handler();
checker=new Runnable()
{
#Override
public void run() {
// call webservice for fetch data
forthread();
h.postDelayed(checker,15000);
}
};
}
public void forthread()
{
// call webservice to fetch data
new InboxReadChat(null, InboxReadChat.TotalMessagesOfSingleSenderUser.geturl( recipientid,InAppUserid), InboxReadChat.TYPE_GET, InboxReadChat.TYPE_RECEIVE_MESSAGE_INBOX, new ServiceHitListenerInboxChat() {
#Override
public void onSuccess(Object Result, int id)
{
// After success of webservice response come this function
callFxnInSuccess(Result);
}
#Override
public void onError(String Error, int id)
{
// AfterError of webservice response come this function
// By this fxn set data from local database to listview
DBvaluesSet();
}
});
}
private void callFxnInSuccess(Object Result) {
dataset = new ArrayList<Dataset>();
String message="",alldatetime="",time="",date="",type="";
InboxDeliveredModel ibx=(InboxDeliveredModel) Result;
if(ibx.getTotalMessagesOfSingleSenderUser().size()>0)
{
// here webservice response data will add on local database
dbObject.Open();
for(int i=0;i<ibx.getTotalMessagesOfSingleSenderUser().size();i++)
{
message =ibx.getTotalMessagesOfSingleSenderUser().get(i).getMessage();
.....
dbObject.InboxMessageAll(message,InAppUsermobile,time,recipientid,type,date);
}
dbObject.close();
// After add data into database call below fxn to fetch data from database and set data in listview with adapter
try
{
DBvaluesSet();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public void DBvaluesSet() {
dataset = new ArrayList<Dataset>();
try
{
// By this code fetch data from local database
Cursor c;
dbObject.Open();
c=dbObject.getallmessages(recipientid);
int countRow = c.getCount();
int counter = 0;
while(c.moveToNext())
{
msgboxitem = c.getString(0);
// number = c.getString(1);
timeitem = c.getString(2);
typeitem = c.getString(4);
datedbitem = c.getString(5);
try {
dataset.add(db.new Dataset(datedbitem, msgboxitem, timeitem, typeitem));
} catch (Exception e) {
e.printStackTrace();
}
}
dbObject.close();
// by below set data into listview into adapter
lv.setAdapter(ccAdpt=new Custom_Inbox_Adapter( getApplicationContext(),dataset,R.layout.row));
ccAdpt.notifyDataSetChanged();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Here my adapter coding...
public class Custom_Inbox_Adapter extends BaseAdapter{
private Context gContext;
private List<Dataset> gData;
private int rEsource;
public Custom_Inbox_Adapter(Context cnt, List<Dataset> data ,int resource){
this.gData = data;
this.gContext = cnt;
this.rEsource = resource;
}
#Override
public int getCount() {
return gData.size();
}
#Override
public Dataset getItem(int position) {
return gData.get(position);
}
#Override
public long getItemId(int position) {> return gData.get(position).hashCode();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) gContext.getSystemService(gContext.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(rEsource, null);
TextView txtReceiveMsg = (TextView) convertView.findViewById(R.id.ReceiveMsg);
TextView txtReceiveTime = (TextView) convertView.findViewById(R.id.ReceiveTime);
TextView txtSendMsg = (TextView) convertView.findViewById(R.id.sendMsg);
TextView txtSendTime = (TextView) convertView.findViewById(R.id.senttime);
TextView date = (TextView) convertView.findViewById(R.id.date);
// layout text chat
RelativeLayout relSend = (RelativeLayout) convertView.findViewById(R.id.LinearReceive);
RelativeLayout relreceive = (RelativeLayout) convertView.findViewById(R.id.LinearSend);
// layout date chat
RelativeLayout LinearDATE= (RelativeLayout) convertView.findViewById(R.id.LinearDATE);
if(position == 0){
fetchdata= gData.get(position).getDate().trim();
date.setText(fetchdata);
}
else{
fetchdata = gData.get(position).getDate().trim();
dd = gData.get((position-1)).getDate().trim();
if(fetchdata.equalsIgnoreCase(dd))
{
LinearDATE.setVisibility(View.GONE);
}
else
{
LinearDATE.setVisibility(View.VISIBLE);
Log.w("INBOX READ", "INBOX_READ_ADAPTER::::(date for position '1'):"+fetchdata);
date.setText(fetchdata);
}
}
relreceive.setVisibility(View.GONE);
relSend.setVisibility(View.VISIBLE);
//txtReceiveNumber.setText(number);
txtReceiveMsg.setText(cutmsg);
txtReceiveTime.setText(time);
}
return convertView;
}
}

ListView not reflecting the change for notifyDataSetChanged()

What I am doing::
I have three buttons
When I click any one of the button, it must clear adapter & Assign
the newvalues.
The newvalues must reflect in the listview
Problem::
My listview is not reflecting the changes onclick of Button
No log Errors
DisplayBuffet_NotifyDataSetChanged_Fragment.java
public class DisplayBuffet_NotifyDataSetChanged_Fragment extends Fragment implements View.OnClickListener{
// Declaration
static ListView xmlFragmentListView;
static View layout;
static DisplayBuffetAsyncTask downloadTask=null;
Button btnRating,btnPrice,btnDistance;
private FileCache fileCache=null;
private MemoryCache memoryCache=null;
DisplayBuffetAdapter listViewAdapter;
static Bundle bundle=null;
DisplayBuffet_Json_Fragment fragment=null;
ArrayList<HashMap<String, String>> arrayListBuffet=null;
FindMyBuffetDatabaseHelper mHelper=null;;
SQLiteDatabase database=null;
public static DisplayBuffet_NotifyDataSetChanged_Fragment newInstance(FileCache _fileCache,MemoryCache _memoryCache) {
DisplayBuffet_NotifyDataSetChanged_Fragment fragment = new DisplayBuffet_NotifyDataSetChanged_Fragment();
bundle = new Bundle();
bundle.putSerializable(FindMyBuffetConstants.BUFFET_FILECACHE_KEY, _fileCache);
bundle.putSerializable(FindMyBuffetConstants.BUFFET_MEMORYCACHE_KEY, _memoryCache);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
layout = inflater.inflate(R.layout.display_buffets_fragment,container, false);
return layout;
}
private void initViews() {
fileCache = (FileCache) getArguments().getSerializable(FindMyBuffetConstants.BUFFET_FILECACHE_KEY);
memoryCache = (MemoryCache) getArguments().getSerializable(FindMyBuffetConstants.BUFFET_MEMORYCACHE_KEY);
xmlFragmentListView = ((ListView) layout.findViewById(R.id.sortrestaurantlistview));
btnRating=(Button) getActivity().findViewById(R.id.btnRating);
btnPrice=(Button) getActivity().findViewById(R.id.btnPrice);
btnDistance=(Button) getActivity().findViewById(R.id.btnDistance);
}
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
arrayListBuffet = new ArrayList<HashMap<String, String>>();
mHelper = new FindMyBuffetDatabaseHelper(FindMyBuffetApplication.currentActivityContext);
database = mHelper.getWritableDatabase();
initViews();
btnRating.setOnClickListener(this);
btnPrice.setOnClickListener(this);
btnDistance.setOnClickListener(this);
setListViewAdapter();
}
#Override
public void onClick(View v) {
String strOrder="asc";
if (FindMyBuffetApplication.isRatingOrderByDesc == false && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_RATING)){
btnRating.setBackgroundResource(R.drawable.tab_button_foucs_asc);
btnPrice.setBackgroundResource(R.drawable.tab_button_default);
btnDistance.setBackgroundResource(R.drawable.tab_button_default);
}
else if (FindMyBuffetApplication.isPriceOrderByDesc == false && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_PRICE)){
btnPrice.setBackgroundResource(R.drawable.tab_button_foucs_asc);
btnRating.setBackgroundResource(R.drawable.tab_button_default);
btnDistance.setBackgroundResource(R.drawable.tab_button_default);
}
else if (FindMyBuffetApplication.isDistanceOrderByDesc == false && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_DISTANCE)){
btnDistance.setBackgroundResource(R.drawable.tab_button_foucs_asc);
btnRating.setBackgroundResource(R.drawable.tab_button_default);
btnPrice.setBackgroundResource(R.drawable.tab_button_default);
}
else if (FindMyBuffetApplication.isRatingOrderByDesc == true && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_RATING)){
btnRating.setBackgroundResource(R.drawable.tab_button_foucs_dec);
btnDistance.setBackgroundResource(R.drawable.tab_button_default);
btnPrice.setBackgroundResource(R.drawable.tab_button_default);
}
else if (FindMyBuffetApplication.isPriceOrderByDesc == true && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_PRICE)){
btnPrice.setBackgroundResource(R.drawable.tab_button_foucs_dec);
btnDistance.setBackgroundResource(R.drawable.tab_button_default);
btnRating.setBackgroundResource(R.drawable.tab_button_default);
}
else if (FindMyBuffetApplication.isDistanceOrderByDesc == true && FindMyBuffetApplication.sortBy.equalsIgnoreCase(FindMyBuffetConstants.TAB_NAME_DISTANCE)){
btnDistance.setBackgroundResource(R.drawable.tab_button_foucs_dec);
btnPrice.setBackgroundResource(R.drawable.tab_button_default);
btnRating.setBackgroundResource(R.drawable.tab_button_default);
}
switch(v.getId()) {
case R.id.btnRating:
FindMyBuffetApplication.sortBy = FindMyBuffetConstants.TAB_NAME_RATING;
if (FindMyBuffetApplication.isRatingOrderByDesc == false)
FindMyBuffetApplication.isRatingOrderByDesc = true;
else
FindMyBuffetApplication.isRatingOrderByDesc = false;
//displayView();
if(FindMyBuffetApplication.isRatingOrderByDesc==true)strOrder="desc";
sortListView(FindMyBuffetConstants.SORT_BY_RATING_1,strOrder);
break;
case R.id.btnPrice:
FindMyBuffetApplication.sortBy = FindMyBuffetConstants.TAB_NAME_PRICE;
if (FindMyBuffetApplication.isPriceOrderByDesc == false)
FindMyBuffetApplication.isPriceOrderByDesc = true;
else
FindMyBuffetApplication.isPriceOrderByDesc = false;
//displayView();
if(FindMyBuffetApplication.isPriceOrderByDesc==true)strOrder="desc";
sortListView(FindMyBuffetConstants.SORT_BY_PRICE_1,strOrder);
break;
case R.id.btnDistance:
FindMyBuffetApplication.sortBy = FindMyBuffetConstants.TAB_NAME_DISTANCE;
if (FindMyBuffetApplication.isDistanceOrderByDesc == false)
FindMyBuffetApplication.isDistanceOrderByDesc = true;
else
FindMyBuffetApplication.isDistanceOrderByDesc = false;
//displayView();
if(FindMyBuffetApplication.isPriceOrderByDesc==true)strOrder="desc";
sortListView(FindMyBuffetConstants.SORT_BY_DISTANCE_1,strOrder);
break;
}
}
private void setListViewAdapter(){
downloadTask = new DisplayBuffetAsyncTask();
if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_RATING){
if (FindMyBuffetApplication.isDownloading) {
downloadTask.initilizeAsyncTask(
getFragmentManager(), xmlFragmentListView,downloadTask,
fileCache,memoryCache);
downloadTask.execute();
}
}
else if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_PRICE){
if (FindMyBuffetApplication.isDownloading) {
downloadTask.initilizeAsyncTask(
getFragmentManager(), xmlFragmentListView,
downloadTask,
fileCache,memoryCache);
downloadTask.execute();
}
}
else if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_DISTANCE){
if (FindMyBuffetApplication.isDownloading) {
downloadTask.initilizeAsyncTask(
getFragmentManager(), xmlFragmentListView,
downloadTask,
fileCache,memoryCache);
downloadTask.execute();
}
}
listViewAdapter = new DisplayBuffetAdapter(arrayListBuffet, fileCache,memoryCache);
xmlFragmentListView.setAdapter(listViewAdapter);
}
private void sortListView(String strSortBy,String strOrder) {
arrayListBuffet.clear();
if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_RATING) {
SortBuffets(FindMyBuffetConstants.SORT_BY_RATING_1, strOrder);
} else if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_PRICE) {
SortBuffets(FindMyBuffetConstants.SORT_BY_PRICE_1, strOrder);
} else if (FindMyBuffetApplication.sortBy == FindMyBuffetConstants.TAB_NAME_DISTANCE) {
SortBuffets(FindMyBuffetConstants.SORT_BY_DISTANCE_1, strOrder);
}
listViewAdapter.notifyDataSetChanged();
}
/*#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
}*/
private void displayView() {
Fragment objFragment = getFragmentManager().findFragmentById(getId());
if (objFragment != null) {
getFragmentManager().beginTransaction().remove(objFragment).commit();
//objFragment = new SortBuffetRating();
objFragment = DisplayBuffet_Json_Fragment.newInstance(fileCache,memoryCache);
getFragmentManager().beginTransaction().add(R.id.frame_container, objFragment).commit();
} else {
//objFragment = new SortBuffetRating();
objFragment = DisplayBuffet_Json_Fragment.newInstance(fileCache,memoryCache);
getFragmentManager().beginTransaction().add(R.id.frame_container, objFragment).commit();
}
}
/*
* Displays data from SQLite
*/
private void SortBuffets(String strSortBy,String strOrder){
Cursor mCursor = database.rawQuery("select * from " + BuffetTable.TABLE_NAME_BUFFET + " order by " + strSortBy +" "+strOrder, null);
try {
// looping through all rows and adding to list
if (mCursor.moveToFirst()) {
do {
HashMap<String, String> map=new HashMap<String, String>();
map.put(BuffetTable.COLUMN_ID,mCursor.getString(0));
map.put(BuffetTable.COLUMN_BUF_OFF_ID,mCursor.getString(1));
map.put(BuffetTable.COLUMN_FROM_TIME,mCursor.getString(2));
map.put(BuffetTable.COLUMN_TO_TIME,mCursor.getString(3));
map.put(BuffetTable.COLUMN_ONLINE_PRICE,mCursor.getString(4));
map.put(BuffetTable.COLUMN_RESERVED_PRICE,mCursor.getString(5));
map.put(BuffetTable.COLUMN_BUF_IMAGE_FILE_NAME,mCursor.getString(6));
map.put(BuffetTable.COLUMN_RES_NAME,mCursor.getString(7));
map.put(BuffetTable.COLUMN_RATING,mCursor.getString(8));
map.put(BuffetTable.COLUMN_LATITUDE,mCursor.getString(9));
map.put(BuffetTable.COLUMN_LONGITUDE,mCursor.getString(10));
map.put(BuffetTable.COLUMN_BUF_TYPE_NAME,mCursor.getString(11));
arrayListBuffet.add(map);
} while (mCursor.moveToNext());
}
}catch (SQLiteException e){
Log.i(FindMyBuffetApplication.applicationName+"."+FindMyBuffetConstants.PACKAGE_NAME+"."+FindMyBuffetConstants.PACKAGE_NAME,"Error Druing Sorting Buffets "+ e.getMessage());
e.printStackTrace();
Toast.makeText(FindMyBuffetApplication.currentActivityContext, "Error Druing Sorting The Buffets By" +strSortBy,Toast.LENGTH_LONG).show();
}catch (Exception e) {
Log.i(FindMyBuffetApplication.applicationName+"."+FindMyBuffetConstants.PACKAGE_NAME+"."+FindMyBuffetConstants.PACKAGE_NAME,"Error Druing Sorting Buffets "+ e.getMessage());
e.printStackTrace();
Toast.makeText(FindMyBuffetApplication.currentActivityContext, "Error Druing Sorting The Buffets By" +strSortBy,Toast.LENGTH_LONG).show();
}finally {
// Release the memory
mCursor.close();
}
}
#Override
public void onDestroy() {
super.onDestroy();
database.close();
//layout = null; // now cleaning up!
//bundle = null;
/*fragment = null;
if (downloadTask != null && downloadTask.getStatus() != AsyncTask.Status.FINISHED)
downloadTask=null;*/
}
}
DisplayBuffetAdapter.java
public class DisplayBuffetAdapter extends BaseAdapter {
// Declare Variables
ImageLoader imageLoader;
ArrayList<HashMap<String, String>> arrayListBuffet;
LayoutInflater inflater;
FileCache fileCache=null;
MemoryCache memoryCache=null;
int tmpLoopCnt=0;
public DisplayBuffetAdapter(ArrayList<HashMap<String, String>> _arraylist,FileCache _fileCache,MemoryCache _memoryCache) {
this.arrayListBuffet = _arraylist;
this.fileCache=_fileCache;
this.memoryCache=_memoryCache;
this.imageLoader=new ImageLoader(FindMyBuffetApplication.currentActivityContext,fileCache,memoryCache);
tmpLoopCnt=0;
}
public int getCount() {
return arrayListBuffet.size();
}
public Object getItem(int position) {
return arrayListBuffet.get(position);
}
public long getItemId(int position) {
return position;
}
private class ViewHolder {
// Declare Variables
ImageView imgRestBuffLogo;
TextView txtResName;
TextView txtRestBufType;
TextView txtRestTime;
TextView txtRestDistance;
TextView txtReservePrice;
TextView txtOnlinePrice;
RatingBar restRatingBar;
Button btnOnlinePrice;
Button btnReservedPrice;
}
public View getView(int position, View convertView, ViewGroup parent) {
tmpLoopCnt = tmpLoopCnt + 1;
Log.i("LIST VIEW ADAPATER COUNT", ""+tmpLoopCnt);
ViewHolder holder;
LayoutInflater inflater;
if (convertView == null) {
inflater = (LayoutInflater) FindMyBuffetApplication.currentActivityContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.display_buffet_listview, null);
holder = new ViewHolder();
Typeface txtResnameFontFace=Typeface.createFromAsset(FindMyBuffetApplication.currentActivityContext.getAssets(), "Roboto-Bold.ttf");
Typeface txtRestBufTypeFontFace=Typeface.createFromAsset(FindMyBuffetApplication.currentActivityContext.getAssets(), "Roboto-Medium.ttf");
Typeface txtRestTimeFontFace=Typeface.createFromAsset(FindMyBuffetApplication.currentActivityContext.getAssets(), "Roboto-Bold.ttf");
//Typeface txtReservePrice=Typeface.createFromAsset(FindMyBuffetApplicationCls.currentActivityContext.getAssets(),"Roboto-Bold.ttf");
//Typeface txtOnlinePrice=Typeface.createFromAsset(FindMyBuffetApplicationCls.currentActivityContext.getAssets(),"Roboto-Bold.ttf");
Typeface btnPrice=Typeface.createFromAsset(FindMyBuffetApplication.currentActivityContext.getAssets(), "Roboto-Bold.ttf");
Typeface txtRestDistanceFontFace=Typeface.createFromAsset(FindMyBuffetApplication.currentActivityContext.getAssets(),"Roboto-Light.ttf");
// Locate the TextViews in listview_item.xml
holder.txtResName = (TextView) convertView.findViewById(R.id.txtRestName);
holder.txtResName.setTypeface(txtResnameFontFace);
holder.txtRestBufType = (TextView) convertView.findViewById(R.id.txtRestBufType);
holder.txtRestBufType.setTypeface(txtRestBufTypeFontFace);
holder.txtRestTime = (TextView) convertView.findViewById(R.id.txtRestTime);
holder.txtRestTime.setTypeface(txtRestTimeFontFace);
holder.txtRestDistance = (TextView) convertView.findViewById(R.id.txtRestDistance);
holder.txtRestDistance.setTypeface(txtRestDistanceFontFace);
holder.restRatingBar=(RatingBar) convertView.findViewById(R.id.restRatingBar);
//holder.txtReservePrice = (TextView) convertView.findViewById(R.id.txtReservePrice);
//holder.txtReservePrice.setTypeface(txtReservePrice);
//holder.txtOnlinePrice = (TextView) convertView.findViewById(R.id.txtOnlinePrice);
//holder.txtOnlinePrice.setTypeface(txtOnlinePrice);
holder.btnOnlinePrice=(Button) convertView.findViewById(R.id.btnOnlinePrice);
holder.btnOnlinePrice.setTypeface(btnPrice);
holder.btnReservedPrice=(Button) convertView.findViewById(R.id.btnReservedPrice);
holder.btnOnlinePrice.setTypeface(btnPrice);
// Locate the ImageView in listview_item.xml
holder.imgRestBuffLogo = (ImageView) convertView.findViewById(R.id.imgRestBuffetLogo);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> objMap= arrayListBuffet.get(position);
holder.txtResName.setText(objMap.get(BuffetTable.COLUMN_RES_NAME));
holder.txtRestBufType.setText(objMap.get(BuffetTable.COLUMN_BUF_TYPE_NAME));
holder.restRatingBar.setRating(Float.valueOf(objMap.get(BuffetTable.COLUMN_RATING)));
holder.txtRestTime.setText(formatTime(objMap.get(BuffetTable.COLUMN_FROM_TIME))+" to "+formatTime(objMap.get(BuffetTable.COLUMN_TO_TIME)));
//txtOnlinePrice.setText(objMap.get("Online_Price"));
//txtReservePrice.setText(objMap.get("Reserved_Price"));
holder.btnOnlinePrice.setText(" Buy Now\n "+"Rs."+objMap.get(BuffetTable.COLUMN_ONLINE_PRICE)+" ");
holder.btnReservedPrice.setText(" Reserve\n "+"Rs."+objMap.get(BuffetTable.COLUMN_RESERVED_PRICE)+" ");
//double dist=objMap.get("Latitude")-objMap.get("Longitude");
//txtRestDistance.setText(String.valueOf(dist));
holder.txtRestDistance.setText(""+10+position+" Km");
String strUrl=FindMyBuffetApplication.URL+FindMyBuffetConstants.WEB_SERVER_PATH_BUF_IMAGE+objMap.get(BuffetTable.COLUMN_BUF_IMAGE_FILE_NAME);
imageLoader.DisplayImage(strUrl,holder.imgRestBuffLogo);
return convertView;
}
private String formatTime(String strTime){
//example For hour,minutes and seconds
// String strTime = "15:30:18 pm";
//SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a");
strTime=strTime.substring(0,5)+" am";
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
Date date = null;
try {
date = sdf.parse(strTime);
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sdf.format(date);
}
}
in private void sortListView(
before calling notifyDataSetChanged, you should submit the new dataset to your adapter. Otherwise you are only chaining the data inside the fragment. You could this both creating a new Adapter and calling setListAdapter again, or creating a method inside the Adapter to update the dataset. For instance:
public void updateData(ArrayList<HashMap<String, String>> _arraylist) {
this.arrayListBuffet = _arraylist;
}
and call it before
listViewAdapter.notifyDataSetChanged();
When you sort you are in fact adding to arrayListBuffet but that may not be your only problem. What you're doing is sorting an array that's not inside the adapter, you need to pass the newly sorted data, in your case arrayListBuffet back to the adapter before calling notifyDataSetChanged
Why? Because if you don't, the data that the adapter is using is still the one from when you initialised it, and therefore you'll see no changes. In other words, you didn't really change the dataset it's using.
How? You can create a method in your adapter and pass the newly sorted data source as a parameter, replacing the original content, you can actually call the notifyDataSetChanged from within that same method.
Code
In your adapter:
public void updateDataSource(ArrayList<HashMap<String, String>> sortedArrayListBuffet) {
this.arrayListBuffet = sortedArrayListBuffet;
this.notifyDataSetChanged();
}

Categories