ListView Refresh with web service Response in android - java

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;
}
}

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

I am using a git repo called LikeButton, but the state of my button keeps jumping around in my recyclerview?

I am using a git repo called LikeButton, but the state of my button keeps jumping around in my recyclerview? Here is the repo https://github.com/jd-alexander/LikeButton. Basically when I click on a recyclerview item, it sets a textview to the word true or false based on if the user liked the post or not, and this works. However, the state of my button is doing some weird stuff, it jumps around...
Here is my Adapter, is their anything wrong with it?
public class ViewpagerAdapter extends RecyclerView.Adapter<ViewpagerAdapter.ViewDashboard>{
private LayoutInflater mLayoutInflater;
private ArrayList<QuestionData> data = new ArrayList<>();
public ViewpagerAdapter(Context context) {
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<QuestionData> listBlogs) {
this.data = listBlogs;
notifyItemRangeChanged(0,listBlogs.size());
}
#Override
public ViewDashboard onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.customizejson, parent, false);
ViewDashboard viewholder = new ViewDashboard(view);
return viewholder;
}
#Override
public void onBindViewHolder(ViewDashboard holder, int position) {
QuestionData questionHolder = data.get(position);
holder.questionText.setText(questionHolder.getMtext());
//This sets the text, to a true or a false String
holder.mStudentVoted.setText(questionHolder.getVoters());
holder.mLikeButton.setTag(holder);
}
#Override
public int getItemCount() {
return data.size();
}
class ViewDashboard extends RecyclerView.ViewHolder {
private TextView questionText;
private LikeButton mLikeButton;
private TextView mStudentVoted;
public ViewDashboard(View itemView) {
super(itemView);
questionText = (TextView)itemView.findViewById(R.id.questionText);
mStudentVoted = (TextView)itemView.findViewById(R.id.studentVoted);
mLikeButton = (LikeButton)itemView.findViewById(R.id.like_button_viewpager);
mLikeButton.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onUpVote();
}
#Override
public void unLiked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onDownVote();
}
});
}
}
}
Voting Class
public class Voting {
private int adapterPosition;
private RecyclerView.Adapter adapter;
private String stringId;
private TextView studentVoted;
//TODO Trim Constructor
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
stringId = questionId.getText().toString();
this.adapter = adapter;
this.studentVoted=studentVoted;
}
public void onUpVote() {
final RequestQueue mRequestQueue = VolleySingleton.getInstance().getRequestQueue();
StringRequest postVoteUp = new StringRequest(Request.Method.PUT, PUT_VOTE_UP, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println("Succesful Upvote The Students Value is " + studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed Upvote");
}
});
mRequestQueue.add(postVoteUp);
}
public void onDownVote() {
final RequestQueue mrequestQueue = VolleySingleton.getInstance().getRequestQueue();
//TODO Delete Token(inserted for student 3 for testing purposes)
StringRequest postVoteDown = new StringRequest(Request.Method.PUT, PUT_VOTE_DOWN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//TODO OnResponse, must setLiked(False)
//Succesful downVote The Students Value is true
//studentVoted.setText("false");
System.out.println("Succesful downVote The Students Value is "+studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed downVote");
}
});
mrequestQueue.add(postVoteDown);
}
public void realTimeUpVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)+1;
textView.setText("" + voteNumber);
}
public void realTimeDownVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)-1;
textView.setText("" + voteNumber);
}
}
Json Request and Parsing Methods
public void JsonRequestMethod() {
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_HOME, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
mListblogs.clear();
mListblogs = new YourTask().execute(response).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mRequestQueue.add(request);
}
private ArrayList<QuestionData> parseJSONResponse(JSONArray response) {
if (!response.equals("")) {
try {
StringBuilder data = new StringBuilder();
for (int x = 0; x < response.length(); x++) {
JSONObject currentQuestions = response.getJSONObject(x);
JSONArray arrSubcategory = currentQuestions.optJSONArray("questions");
for (int y = 0; y < arrSubcategory.length(); y++) {
JSONObject objectSubcategory = arrSubcategory.getJSONObject(y);
String text = objectSubcategory.optString("text");
String studentId = objectSubcategory.optString("studentId");
String votes=objectSubcategory.optString("votes");
/*JSONArray cycles through the array of voters, when a user votes
their ID is added to the array.When they downvote, it is removed
*/
JSONArray voters= objectSubcategory.optJSONArray("voters");
QuestionData questionData = new QuestionData();
questionData.setMstudentId(studentId);
questionData.setMtext(text);
questionData.setVotes(votes);
questionData.setVoters(checkIfVoted(voters));
mQuestionDataArrayList.add(questionData);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mQuestionDataArrayList;
}
private static String checkIfVoted(JSONArray jsonArray ) {
/*pass in a json Array, copy the array into ints, and if
the students Id is contained in the array return the string true
*/
int[] voteIds = new int[jsonArray.length()];
for(int i=0;i<voteIds.length;i++){
voteIds[i] = jsonArray.optInt(i);
}
for(int i=0;i<voteIds.length;i++){
if(voteIds[i]== Integer.parseInt(Login.getUserId())){
//TODO String was only used for Testing purposes, Convert to Boolean later
return "true";
}
}
return "false";
}
you are currently only updating the textview which is why your recycleview changes state when scrolling.
Should change your voting class and pass the question Data rather textview
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
change to
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, QuestionData questionData, TextView studentVoted) {
// make other changes for the data
and then in
public void realTimeUpVoting(QuestionData questionData){
data.votes++ //something like that. idont know your model
// now call back using interface the recyleview data changed method so it updates the count in recycleview automatically.
Edit
passing the question Data in click button
class ViewDashboard extends RecyclerView.ViewHolder {
public int position
public void onBindViewHolder(ViewDashboard holder, int position) {
holder.position = position
}
public void liked(LikeButton likeButton) {
QuestionData questionHolder = data.get(position);

remove beacon from list if not detected

I'm trying to make a simple app that lists all the found Ibeacons in a ListView and changes the RSSI values according to the distance the user is from the beacons itself.
The app works fine, but the problem I'm having is that if a beacon is out of reach it does not get removed from the list. Any ideas on how to remove the item when the beacon isn't in range anymore?
I have the following code:
MainActivity.java:
public class MainActivity extends Activity implements BeaconConsumer {
public ListView list;
public BeaconAdapter adapter;
public ArrayList<Beacon> arrayL = new ArrayList<>();
public LayoutInflater inflater;
public BeaconManager mBeaconManager;
public boolean beaconPresent;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView)findViewById(R.id.lijst);
mBeaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
mBeaconManager.setForegroundBetweenScanPeriod(100);
mBeaconManager.bind(this);
adapter = new BeaconAdapter();
list.setAdapter(adapter);
inflater =(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void onBeaconServiceConnect() {
Region region = new Region("all-beacons-region", null, null, null);
try {
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
mBeaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(final Collection<Beacon> beacons, Region region) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ArrayList<Beacon> allRangedBeacons = (ArrayList<Beacon>) beacons;
ArrayList<Beacon> newRangedBeacons = new ArrayList<>();
ArrayList<Beacon> cloneArraylistIBeacon = (ArrayList<Beacon>) arrayL.clone();
ArrayList<Beacon>nonRangedBeacons = new ArrayList<>();
int index = 0;
for (Beacon presentBeacons : cloneArraylistIBeacon) {
beaconPresent = false;
for (Beacon eachRangedBeacon : allRangedBeacons) {
if (presentBeacons.equals(eachRangedBeacon)) {
arrayL.remove(index);
arrayL.add(index, eachRangedBeacon);
beaconPresent = true;
}
if(beaconPresent = false) {
nonRangedBeacons.add(presentBeacons);
}
}
index++;
}
for (Beacon eachRangedBeacon : allRangedBeacons) {
beaconPresent = false;
for (Beacon presentBeacons : cloneArraylistIBeacon) {
if (eachRangedBeacon.equals(presentBeacons)) {
beaconPresent = true;
}
}
if (!beaconPresent) {
newRangedBeacons.add(eachRangedBeacon);
}
}
arrayL.remove(nonRangedBeacons);
arrayL.addAll(newRangedBeacons);
adapter.notifyDataSetChanged();
}
});
}
});
}
protected void onPause() {
super.onPause();
mBeaconManager.unbind(this);
}
private class BeaconAdapter extends BaseAdapter {
#Override
public int getCount() {
if (arrayL != null && arrayL.size() > 0) {
return arrayL.size();
} else {
return 0;
}
}
#Override
public Beacon getItem(int position) {
return arrayL.get(position);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
holder = new ViewHolder(convertView = inflater.inflate(R.layout.tupple_monitoring, null));
try {
holder.uuid.setText("UUID: " + arrayL.get(position).getId2());
holder.rssi.setText("RSSI: " + arrayL.get(position).getRssi());
holder.txpow.setText("TXPOW: " + arrayL.get(position).getTxPower());
return convertView;
}catch(Exception e) {
e.printStackTrace();
}
return convertView;
}
}
private class ViewHolder {
private TextView uuid;
private TextView rssi;
private TextView txpow;
public ViewHolder(View view) {
uuid = (TextView)view.findViewById(R.id.BEACON_uuid);
rssi = (TextView)view.findViewById(R.id.BEACON_rssi);
txpow = (TextView)view.findViewById(R.id.BEACON_txpower);
view.setTag(this);
}
}
}
If you only want to display beacons in range, every time you receive a list of beacons simply change the adapter source list.
arrayL.clear();
arrayL.addAll(beacons);
adapter.notifyDataSetChanged();
To avoid jumping around if list items, maybe sort the beacons by their RSSI before displaying them.
Because the Android Beacon Library already tracks the list of visible beacons and updates it in the ranging callback, you can simply refresh the whole list in your BeaconAdapter each time. Like this:
#Override
public void didRangeBeaconsInRegion(final Collection<Beacon> beacons, Region region) {
runOnUiThread(new Runnable() {
#Override
public void run() {
arrayL = new ArrayList<Beacon>(beacons);
adapter.notifyDataSetChanged();
}
});
}

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();
}

Loading images in listview asynchronously with callback

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);

Categories