ListView populates but each view is blank at first? - android

I'm using a ListView inside a Fragment which downloads notes from Firebase storage and then displays them. However, the problem I'm running into is when it displays the notes its just a empty note layout, but when I switch activities and go back they're no longer blank, they're loaded. I'm not sure where exactly I'm going wrong, I've tried calling onDataSetChange to the Adapter Everywhere, also tried invalidate() and invalidateViews() on the ListView hoping it would just simply refresh the views, but unfortunately that didnt work either :/ the code is below, thank you in advanced for any help! :)
this is where I'm setting the Adapter in my Notes fragment
mNoteStorage = FirebaseStorage.getInstance().getReference().child("Notes").child(currentUser.getUid());
mNotesDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
my_notes.setAdapter(null);
Iterable<DataSnapshot> all_keys = dataSnapshot.getChildren();
filename_arrayList = new ArrayList<>();
na = null;
for (DataSnapshot each_key : all_keys) {
String each = each_key.getKey();
filename_arrayList.add(each);
}
for (String each_filename : filename_arrayList) {
downloadFile(each_filename);
Note each_note = Utilities.getNoteByName(getContext(), each_filename + Utilities.FileExtention);
each_note_array.add(each_note);
}
if (each_note_array == null || each_note_array.size() == 0) {
Toast.makeText(getActivity().getApplicationContext(), "No Notes!", Toast.LENGTH_LONG).show();
} else {
na = new MyNotesAdapter(getContext(), R.layout.item_note, each_note_array);
my_notes.setAdapter(na);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
and Here's my Adapter
class MyNotesAdapter extends ArrayAdapter<Note> {
Context ctx;
public MyNotesAdapter(#NonNull Context context, int resource, ArrayList<Note> note) {
super(context, resource, note);
this.ctx = context;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//return super.getView(position, convertView, parent);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_note, null);
}
Note note = getItem(position);
if(note != null) {
TextView title = (TextView) convertView.findViewById(R.id.list_note_title);
TextView content = (TextView) convertView.findViewById(R.id.list_note_content);
TextView date = (TextView) convertView.findViewById(R.id.list_note_date);
Typeface music_font = Typeface.createFromAsset(getContext().getAssets(), "fonts/melodymakernotesonly.ttf");
Typeface scribble_card = Typeface.createFromAsset(getContext().getAssets(), "fonts/the unseen.ttf");
if (getThemeCountInt() == 0) {
title.setTypeface(music_font);
} else if (getThemeCountInt() == 1) {
title.setTypeface(scribble_card);
}
content.setTypeface(scribble_card);
title.setText(note.getTitle());
date.setText(note.getDateTimeFormatted(getContext()));
if(note.getContent().length() > 25) {
content.setText(note.getContent().substring(0,25) + "...");
} else {
content.setText(note.getContent());
}
if(note.getContent().length() <= 0) {
content.setText("(Empty Note..)");
} else {
content.setText(note.getContent());
}
if (note.getTitle().length() <= 0) {
title.setText("(Untitled)");
} else {
title.setText(note.getTitle());
}
}
return convertView;
}
private int getThemeCountInt() {
SharedPreferences mSharedPreferences = this.getContext().getSharedPreferences("theme", MODE_PRIVATE);
int selectedTheme = mSharedPreferences.getInt("theme", 0);
return selectedTheme;
}
}
downloadFile
private void downloadFile(final String filenames) {
final String each_filename = filenames + Utilities.FileExtention;
final long file_size = 1024 * 1024;
mNoteStorage.child(each_filename).getBytes(file_size).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
FileOutputStream stream;
FileInputStream streamIn;
try {
File dir = getActivity().getApplication().getFilesDir();
File file = new File(dir, each_filename);
stream = new FileOutputStream(file);
stream.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
Utilities.getNoteByName
public static Note getNoteByName(Context context, String filename) {
File file = new File(context.getFilesDir(), filename);
Note note;
if (file.exists()) {
FileInputStream fis;
ObjectInputStream ois;
try {
fis = context.openFileInput(filename);
ois = new ObjectInputStream(fis);
note = (Note) ois.readObject();
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
return note;
}
return null;
}

After you create MyNotesAdapter call notifyDataSetChanged() method to let ListView instance knows that underlying data has changed.
my_notes.setAdapter(na);
na.notifyDataSetChanged();
Personally I prefer to create and set adapter instance once and then use its add() method to manipulate its underlying data. Once I finished, I call adapter notifyDataSetChanged().
Recreating new adapter instance each time database change may trigger garbage collector to run more often.

Related

Cant access viewHolder in a customArrayadapter in another function?

I am creating an application with a list that list cards based on the value from the server.
I created a StudentCardArrayAdapter to achieve this and everything works fine. All the data has been populated in card list. also I able to get the values on button click in each card separately.
What I need is on clicking the button it will call a method requestion server for data asynchronously and get a value from the server and according to that value, i need to change the button text in that particular card.
My StudentCardArrayAdapter code:
public class StudentCardArrayAdapter extends ArrayAdapter<StudentCard> {
private static final String TAG = "CardArrayAdapter";
private List<StudentCard> cardList = new ArrayList<StudentCard>();
private Context mContext;
String selected = "0";
PreferenceHelper prefs;
CardViewHolder viewHolder;
View row;
ProgressDialog pd;
static class CardViewHolder {
TextView studentname;
TextView stop;
Button selectbutton;
CircleImageView imageId;
}
public StudentCardArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.mContext = context;
prefs = new PreferenceHelper(this.mContext);
pd = new ProgressDialog(this.mContext);
}
#Override
public void add(StudentCard object) {
cardList.add(object);
super.add(object);
}
#Override
public int getCount() {
return this.cardList.size();
}
#Override
public StudentCard getItem(int index) {
return this.cardList.get(index);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.student_card, parent, false);
viewHolder = new CardViewHolder();
viewHolder.studentname = (TextView) row.findViewById(R.id.studentname);
viewHolder.stop = (TextView) row.findViewById(R.id.stop);
viewHolder.selectbutton = (Button) row.findViewById(R.id.selectbutton);
viewHolder.imageId = (CircleImageView) row.findViewById(R.id.imageId);
row.setTag(viewHolder);
} else {
viewHolder = (CardViewHolder)row.getTag();
}
StudentCard card = getItem(position);
viewHolder.studentname.setText(card.getStudName());
viewHolder.studentname.setTextColor(Color.parseColor("#000000"));
viewHolder.stop.setText(card.getStudStop());
viewHolder.stop.setTextColor(Color.parseColor("#000000"));
if(card.getSelected().equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
else{
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.select));
viewHolder.selectbutton.setEnabled(true);
}
final String studid = card.getStudId();
final String busname = prefs.getString("busname", "0");
final String schoolid = prefs.getString("schoolid", "");
viewHolder.selectbutton.setOnClickListener(new View.OnClickListener()
{
String updatedvalue = "0";
#Override
public void onClick(View v)
{
Log.e("studid",studid);
Log.e("busname",busname);
Log.e("schoolid",schoolid);
selectstudent(v, studid, busname, schoolid,mContext);
//Toast.makeText(v.getContext(), amountinfo, Toast.LENGTH_SHORT).show();
/*SnackbarManager.show(Snackbar.with(this) // context
.text(amountinfo));*/
}
});
Picasso.with(mContext).load(card.getImageUrl()).fit().error(R.mipmap.ic_launcher).into(viewHolder.imageId);
return row;
}
public void selectstudent(final View v, String studid, String busname, String schoolid, final Context mContext) {
String returnedselected = "0";
Log.e("BASE_URL_STUDENT_UPDATE", Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid);
RestClientHelper.getInstance().get(Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid, new RestClientHelper.RestClientListener() {
#Override
public void onSuccess(String response) {
Log.e("RESULT", response);
try {
JSONObject result = new JSONObject(response);
JSONArray posts = result.optJSONArray("status");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
String status = post.optString("status");
if (status.equals("true")) {
selected = post.optString("selected");
} else {
selected = post.optString("selected");
String error = post.optString("error");
SnackbarManager.show(Snackbar.with(getContext()) // context
.text(error));
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
} finally {
if(selected.equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
}
}
#Override
public void onError(String error) {
Log.e("error", error);
selected = "0";
}
});
}
}
I used the below code but nothing works.. No error also.. and not change in button text.I get value of selected as 1 from server.
if(selected.equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
I am new to android.. and is stuck here. Please help me out.
FINALLY IT WORKED
As changes mention by Krish, I updated the code suggested by him.
And added this changes in onClick it worked
if(card.getSelected().equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
Change the code like this,
public void selectstudent(StudentCard card, String studid, String busname, String schoolid, final Context mContext) {
String returnedselected = "0";
Log.e("BASE_URL_STUDENT_UPDATE", Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid);
RestClientHelper.getInstance().get(Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid, new RestClientHelper.RestClientListener() {
#Override
public void onSuccess(String response) {
Log.e("RESULT", response);
try {
JSONObject result = new JSONObject(response);
JSONArray posts = result.optJSONArray("status");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
String status = post.optString("status");
if (status.equals("true")) {
selected = post.optString("selected");
} else {
selected = post.optString("selected");
String error = post.optString("error");
SnackbarManager.show(Snackbar.with(getContext()) // context
.text(error));
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
} finally {
if(selected.equals("1")){
card.setSelected("1");
notifyDataSetChanged();
}
}
}
#Override
public void onError(String error) {
Log.e("error", error);
selected = "0";
}
});
}
and change this line like this ,
final StudentCard card = getItem(position);
and call method inside onclick.
selectstudent(card, studid, busname, schoolid,mContext);

Remove an item from view inside an adapter

I am trying to remove an item from view when its flag become 4. I tried mObjects.remove(position) and then notifyDataSetChanged(). but it didn't worked.we tried all the following
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
also this one
// mObjects.remove(position)
// notifyDataSetChanged();
and this one
// mObjects.remove(position);
//remove(position);
//mainObjects.remove(position);
//notifyDataSetChanged();
and this one
// Object toRemove = adapter.getItem(position);
// mObjects.remove(toRemove);
// mObjects.clear();
and all the time we got java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0.Here is the complete adapter class
private class MatchedDataAdapter extends BaseAdapter implements Filterable {
private AQuery aQuery;
private Activity mActivity;
private LayoutInflater mInflater;
private SessionManager sessionManager;
private int uflag;
MyFilter mfilter;
DatabaseHandler db;
ArrayList<LikeMatcheddataForListview> mObjects;
ArrayList<LikeMatcheddataForListview> mainObjects;
Context context;
public MatchedDataAdapter(Activity context,
ArrayList<LikeMatcheddataForListview> objects,
int imageHeigthAndWidth[]) {
this.mObjects = objects;
mainObjects = objects;
//Log.e("size", Integer.toString(mObjects.size()));
this.mActivity = context;
try {
mInflater = (LayoutInflater) mActivity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
catch (Exception e)
{
e.printStackTrace();
}
aQuery = new AQuery(context);
db = new DatabaseHandler(context);
}
#Override
public int getCount() {
return mObjects.size();
}
#Override
public LikeMatcheddataForListview getItem(int position) {
return mObjects.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.matchedlistviewitem,
null);
holder.imageview = (ImageView) convertView
.findViewById(R.id.userimage);
holder.textview = (TextView) convertView
.findViewById(R.id.userName);
holder.lastMasage = (TextView) convertView
.findViewById(R.id.lastmessage);
holder.imgStatus = (ImageView) convertView
.findViewById(R.id.imgStatus);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(getItem(position).getUserName());
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
we want to remove Item with flag 4,we are reading this flag with a service from db and onrecive we call class DisplayContentTask as below
class GetLikeMatchedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
new DisplayContentTask(intent).execute();
}
}
how we can get Item position in order to remove the Item with flag 4...or My be another approach to remove Item with flag 4 we don't know but appreciate your help on this
class DisplayContentTask extends AsyncTask<Void, Void, Void> {
Intent intent;
private Ultilities mUltilities = new Ultilities();
private List<NameValuePair> getuserparameter;
private String likedmatchedata, Unmatchedata;
int match1;
private LikedMatcheData matcheData;
private ArrayList<com.appdupe.flamer.pojo.Likes> likesList;
private LikeMatcheddataForListview matcheddataForListview;
DatabaseHandler mDatabaseHandler = new DatabaseHandler(getActivity());
private boolean isResponseSuccess = true;
ArrayList<LikeMatcheddataForListview> tempArray = new ArrayList<LikeMatcheddataForListview>();
#Override
protected void onPreExecute() {
super.onPreExecute();
AppLog.Log(TAG, "BackgroundTaskForFindLikeMatched onPreExecute ");
}
DisplayContentTask(Intent intent) {
this.intent = intent;
}
#Override
protected Void doInBackground(Void... voids) {
try {
File appDirectory = mUltilities
.createAppDirectoy(getResources().getString(
R.string.appdirectory));
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground appDirectory "
+ appDirectory);
File _picDir = new File(appDirectory, getResources().getString(
R.string.imagedirematchuserdirectory));
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground ");
// getuserparameter = mUltilities.getUserLikedParameter(params);
likedmatchedata = intent.getStringExtra("GET_MATCHED_RESPONSE");
// Unmatchedata = intent.getStringExtra("GET_UNMATCHED_RESPONSE");//hadi
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likedmatchedata "
+ likedmatchedata);
Gson gson = new Gson();
matcheData = gson.fromJson(likedmatchedata,
LikedMatcheData.class);
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground matcheData "
+ matcheData);
// "errNum": "51",
// "errFlag": "0",
// "errMsg": "Matches found!",
if (matcheData.getErrFlag() == 0) {
likesList = matcheData.getLikes();
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likesList "
+ likesList);
if (tempArray != null) {
tempArray.clear();
}
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likesList sized "
+ likesList.size());
Log.v("Matches", "" + likesList.size());
match1 = likesList.size();
for (int i = 0; i < likesList.size(); i++) {
Log.d("likelist", likesList.toString());
matcheddataForListview = new LikeMatcheddataForListview();
String userName = likesList.get(i).getfName();
String facebookid = likesList.get(i).getFbId();
// Log.i(TAG, "Background facebookid......"+facebookid);
String picturl = likesList.get(i).getpPic();
int falg = likesList.get(i).getFlag();
// if (likesList.get(i).getFlag()==4) {
// likesList.remove(getId());
// }
Log.i("komak10",""+likesList.get(i).getFlag());
String latd = likesList.get(i).getLadt();
matcheddataForListview.setFacebookid(facebookid);
matcheddataForListview.setUserName(userName);
matcheddataForListview.setImageUrl(picturl);
matcheddataForListview.setFlag("" + falg);
matcheddataForListview.setladt(latd);
// matcheddataForListview.setFilePath(filePath);
File imageFile = mUltilities.createFileInSideDirectory(
_picDir, userName + facebookid + ".jpg");
// logDebug("BackGroundTaskForUserProfile doInBackground imageFile is profile "+imageFile.isFile());
Utility.addBitmapToSdCardFromURL(likesList.get(i)
.getpPic().replaceAll(" ", "%20"), imageFile);
matcheddataForListview.setFilePath(imageFile
.getAbsolutePath());
if (!preferences.getString(Constant.FACEBOOK_ID, "")
.equals(facebookid)) {
tempArray.add(matcheddataForListview);
}
}
DatabaseHandler mDatabaseHandler = new DatabaseHandler(
getActivity());
// SessionManager mSessionManager = new SessionManager(
// MainActivity.this);
String userFacebookid = preferences.getString(
Constant.FACEBOOK_ID, "");
//
boolean isdataiserted = mDatabaseHandler.insertMatchList(
tempArray, userFacebookid);
} else if (matcheData.getErrFlag() == 1) {
if(tempArray!=null)
{
tempArray.clear();
}
} else {
// do nothing
}
} catch (Exception e) {
AppLog.handleException(
"BackgroundTaskForFindLikeMatched doInBackground Exception ",
e);
// some thing wrong happend
isResponseSuccess = false;
}
return null;
}
Don't remove the object in getview, if you have to filter it, filter it before sending out to adapter. May be possible that while creating the child view the 1st cell has tag "4" now the view didn't create(since return was not called) but you are trying to remove its position, so it will definitely give you IndexOutOfBoundsException.
My best solution would be, set the adapter with
new ArrayList<LikeMatcheddataForListview>()
whenever you start the screen. Once your AsyncTask completes filter out the child with tags "4"(better filter it out in the asynctask only, less task in ui thread) then refresh the adapter, like
public void refresh(ArrayList<LikeMatcheddataForListview>() arrObjects){
objects = arrObjects;
notifyDataSetChanged();
}
Check it out, it should do the trick
Please try following
Your code
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
}
TO
do not set adapter again to list view
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
notifyDataSetChanged();
}
This may not be correct approach to remove the item form listview.
Whenever your adapter data is getting changed then just check if that flag matches your string i.e. "4" in each item and remove the respective item from the list and just call notifyItemRemoved with position insted of notifyDataSetChanged

Android: Change image for a particular item in listview

In the above image, there is a list view which contains list of items that the user can download. This is the image which tells user that he can download the file. On completion of download, the image will change to . My problem is when I download a file, the status image(which denotes that download has completed) gets changed for another row, instead, it should change for the row that I had selected. At present, if I download first file in the list, the image gets changed for 4th or 5th item in the list. Also, when I try to download any other file from the list. it opens up last downloaded file(This is functionality of the app that if file is already downloaded, then open it in pdf reader),i.e., if I download 1st file in the list and then go for second item,then instead of downloading 2nd file, it opens up last downloaded file. More over, if I scroll the listview, the status of download gets changed for other items in the list also. Below,is my adapter code:
public class DownloadListAdapter extends BaseAdapter {
Context ctx;
public ArrayList<DownloadListDao> mDownloadList;
String readMoreLink;
public static final String TAG = "DownloadListAdapter";
ProgressDialog mProgressDialog;
private boolean isSDCardPresent;
File tieDir;
int downloadState[];
public DownloadListAdapter(Context ctx,
ArrayList<DownloadListDao> mDownloadList) {
this.ctx = ctx;
this.mDownloadList = mDownloadList;
downloadState = new int [mDownloadList.size()];
for(int i = 0; i < mDownloadList.size(); i++) {
downloadState[i] = 0;
}
tieDir = new File(Environment.getExternalStorageDirectory().toString()
+ "/tie");
}// Constructor
public int getCount() {
return this.mDownloadList.size();
}// getCount
public Object getItem(int position) {
return this.mDownloadList.get(position);
}// getItem
public long getItemId(int position) {
return 0;
}// getItemId
static class ViewHolder {
TextView txtTitle, txtTheme, txtDate;
ImageView imgDownload;
}// ViewHolder
ViewHolder holder;
public View getView(final int position, View convertView, ViewGroup parent) {
final String url = mDownloadList.get(position).getUrl();
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.downlist_adapter, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView
.findViewById(R.id.txtTitle);
holder.txtTheme = (TextView) convertView
.findViewById(R.id.txtTheme);
holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
holder.imgDownload = (ImageView) convertView
.findViewById(R.id.imgDload);
holder.imgDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File mediaFile = null;
if (url != null && !url.equals("null") && !url.equals("")) {
String fileName = url.toString().substring(
url.toString().lastIndexOf("/") + 1,
url.toString().length());
mediaFile = new File(tieDir, fileName);
}
processFile(mediaFile, url, position);
int pos = (Integer)v.getTag();
downloadState[pos] = 1;
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (mDownloadList != null && mDownloadList.size() > 0) {
if (mDownloadList.get(position).getTitle() != null
&& !mDownloadList.get(position).getTitle().equals("null")
&& !mDownloadList.get(position).getTitle().equals("")) {
holder.txtTitle.setText(mDownloadList.get(position).getTitle());
}
if (mDownloadList.get(position).getTheme() != null
&& !mDownloadList.get(position).getTheme().equals("null")
&& !mDownloadList.get(position).getTheme().equals("")) {
holder.txtTheme.setText(mDownloadList.get(position).getTheme());
}
if (mDownloadList.get(position).getDate() != null
&& !mDownloadList.get(position).getDate().equals("null")
&& !mDownloadList.get(position).getDate().equals("")) {
holder.txtDate.setText(mDownloadList.get(position).getDate());
}
if (downloadState[position] == 1) {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dloaded));
} else {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dload));
}
}
holder.imgDownload.setTag(position);
return convertView;
}// getView
protected void downloadFile(String url, int position, String fileName) {
Log.v(TAG, "Preparing to download");
mProgressDialog = new ProgressDialog(ctx);
mProgressDialog.setMessage("Dowloading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
isSDCardPresent = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
if (!isSDCardPresent) {
noSDCardAlert(ctx);
} else {
if ((tieDir.exists()) && (tieDir != null)) {
if (NetworkConnection.isOnline(ctx)) {
if (tieDir.isDirectory()) {
Log.v(TAG, "if tie dir URL:::" + url);
new DownloadAudioAsync(ctx, position, fileName).execute(url);
}
} else {
((DownloadListActivity) ctx)
.OpenNetErrDialog("Please check your internet connection...");
}
} else {
boolean isDirectoryCreated = tieDir.mkdirs();
if (isDirectoryCreated) {
Log.v(TAG, "if tie not dir URL:::" + url);
if (NetworkConnection.isOnline(ctx)) {
new DownloadAudioAsync(ctx, position, fileName).execute(url);
} else {
((DownloadListActivity) ctx)
.OpenWiFiDialog("Please check your internet connection...");
}
}
}
}
}
private void noSDCardAlert(Context ctx) {
AlertDialog.Builder ad = new AlertDialog.Builder(ctx);
ad.setMessage("No sd card present..");
ad.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
if (!((DownloadDetail) ctx).isFinishing()) {
ad.show();
}
}
public void OpenDialog(String messageID) {
final Dialog dialog = new Dialog(ctx,
android.R.style.Theme_Translucent_NoTitleBar);
dialog.setContentView(R.layout.dialog_base);
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
dialog.setCancelable(false);
TextView alertMessage = (TextView) dialog.findViewById(R.id.txtMessage);
Button btnOK = (Button) dialog.findViewById(R.id.btnOk);
btnOK.setText("Show");
alertMessage.setText(messageID);
dialog.show();
btnOK.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
protected void showPdf(File mediaFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(mediaFile), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
ctx.startActivity(intent);
}
public class DownloadAudioAsync extends AsyncTask<String, String, String> {
Context ctx;
int pos;
private ProgressDialog pd;
String fileName;
public DownloadAudioAsync(Context ctx, int pos, String fileName) {
this.ctx = ctx;
this.pos = pos;
this.fileName = fileName;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v(TAG, "inside on pre execute");
pd = new ProgressDialog(ctx);
pd.setMessage("Downloading...\nPlease wait..");
pd.show();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
Log.v(TAG,
"inside do in background with url::"
+ aurl[0].toString());
aurl[0] = aurl[0].replaceAll(" ", "%20");
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
fileName = URLDecoder.decode(fileName, "UTF-8");
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(tieDir + "/"
+ fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(String unused) {
if (!((DownloadListActivity) ctx).isFinishing()) {
pd.dismiss();
updateView(pos);
}
}
private void updateView(int pos) {
View v = ((DownloadListActivity) ctx).menuListView.getChildAt(pos
- ((DownloadListActivity) ctx).menuListView
.getFirstVisiblePosition());
ImageView imgDloadBtn = (ImageView) v.findViewById(R.id.imgDload);
imgDloadBtn.setImageDrawable(ctx.getResources().getDrawable(
R.drawable.ic_dloaded));
notifyDataSetChanged();
}
}
private void processFile(File mediaFile, String url, int pos) {
if (url != null && !url.equals("null") && !url.equals("")) {
if (mediaFile != null) {
Log.v(TAG, "in processFile FileName " + mediaFile.getName());
Log.v(TAG, "in processFile Position " + pos);
if(!mediaFile.exists()) {
Log.v(TAG, "in processFile Media file doesn't exists");
downloadFile(url, pos, mediaFile.getName());
} else {
Log.v(TAG, "in processFile Media file exists");
try {
showPdf(mediaFile);
} catch (ActivityNotFoundException anfe) {
OpenDialog("PDF Reader is not installed on your device.");
}
}
}
}
}
}// DownloadAdapter
I had read this post for recycling the view(Thanks to Knickedi for in depth explaination). But, I can't figure out where is actual problem.
Issue with getview Method which keep recreating whenever you scroll your view, to handle exact position you have to play with setTag & getTag,check below few stackvoerflow answers to understand setTag & getTag:
Button in ListView using ArrayAdapter
Getting radio button value from custom list in android
and even store downloaded state into one booleanarray like below:
int boxState[];
within adapter constructor, set zero initially:
for (int i = 0; i < getData.size(); i++) {
boxState[i] = 0;
}
within adapter getview method:
holder.imgDownload.setTag(position);
Now you click on download button set value as 1 (Inside onclick of button):
pos = (Integer) v.getTag();
boxState[pos]=1;
At last when you scroll your view check condition into following way(put below code inside getview method):
if (boxState[position] == 0) {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dloaded)); //which aren't downloaded
} else {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dload)); // which are downloaded.
}

how to get user online or offline in asmack, android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
XMPP aSmack - How can I get the current user state (offline/online/away/etc.)?
I am developing chat app on Android base on asmack lib. I display all the user on the ListView but I use an image to show online/offline user. But It return offline image only, even the user is online, here is my code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.buddies);
Controller.getInstance().roster = Controller.getInstance().connection.getRoster();
// ArrayList<Buddy> buddies = new ArrayList<Buddy>();
Collection<RosterEntry> entries = Controller.getInstance().roster.getEntries();
Controller.getInstance().buddyList = new Buddy[entries.size()];
int i = 0;
for (RosterEntry r : entries) {
Buddy bud = new Buddy();
VCard card = new VCard();
try {
ProviderManager.getInstance().addIQProvider("vCard",
"vcard-temp", new VCardProvider());
card.load(Controller.getInstance().connection, r.getUser());
} catch (XMPPException e) {
Log.e("ChatOnAndroid", e.getMessage() + " " + r.getUser() + " "
+ e.getLocalizedMessage());
}
bud.jid = r.getUser();
bud.name = r.getName();
bud.status = Controller.getInstance().roster.getPresence(r.getUser());
Controller.getInstance().buddies.add(bud);
Controller.getInstance().buddyList[i++] = bud;
}
BuddyAdapter adapter = new BuddyAdapter(this, R.layout.buddy, Controller.getInstance().buddies);
setListAdapter(adapter);
/*
* list = (ListView) findViewById(R.id.buddiesList);
* list.setAdapter(adapter);
*/
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
startActivity(new Intent(this, Conferences.class));
}
public class BuddyAdapter extends ArrayAdapter<Buddy> {
private ArrayList<Buddy> items;
public BuddyAdapter(Context context, int textViewResourceId,
ArrayList<Buddy> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.buddy, null);
}
Buddy buddy = items.get(position);
if (buddy != null) {
TextView tt = (TextView) v.findViewById(R.id.buddyName);
ImageView iv = (ImageView) v.findViewById(R.id.buddyThumb);
//buddy.status = Controller.getInstance().roster.getPresence(buddy.jid);
if (buddy.status != null) {
buddy.img = R.drawable.status_online;
iv.setImageResource(buddy.img);
} else if (buddy.status == null) {
buddy.img = R.drawable.status_offline;
iv.setImageResource(buddy.img);
}
//iv.setImageResource(buddy.img);
if (tt != null) {
tt.setText(buddy.name);
}
}
return v;
}
}
You can get online and offline friends via RosterListener like i did below and then update listview with new data.
roster.addRosterListener(new RosterListener() {
#Override
public void presenceChanged(final Presence presence) {
System.out.println("Presence changed: " + presence.getFrom()
+ " " + presence);
runOnUiThread(new Runnable() {
public void run() {
// / To Update listview should clear arraylists first
// then inavalidate Listview to redraw then add new data
// to Arraylists then notify adapter.
JID.clear();
Names.clear();
Status.clear();
Image.clear();
list.invalidateViews();
for (RosterEntry entry : entries) {
card = new VCard();
presencek = roster.getPresence(entry.getUser());
try {
card.load(Main.conn, entry.getUser());
} catch (Exception e) {
e.printStackTrace();
}
JID.add(entry.getUser());
Names.add(card.getField("FN"));
Status.add(presencek.getType().name());
Log.d("Prescence", "" + presencek.getType().name());// //num
// one
// log
// if (bud.name == null)
// bud.name = bud.jid;
// buddies.add(bud);
byte[] img = card.getAvatar();
if (img != null) {
int len = img.length;
Image.add(BitmapFactory.decodeByteArray(img, 0,
len));
} else {
Drawable d = getApplicationContext()
.getResources().getDrawable(
R.drawable.save);
Bitmap bitmap = ((BitmapDrawable) d)
.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
stream);
img = stream.toByteArray();
int len = img.length;
Image.add(BitmapFactory.decodeByteArray(img, 0,
len));
// Image.add(null);
}
// buddyList[i++] = bud;
}
adapter.notifyDataSetChanged();
}
#Override
public void entriesUpdated(Collection<String> addresses) {
// TODO Auto-generated method stub
}
#Override
public void entriesDeleted(Collection<String> addresses) {
// TODO Auto-generated method stub
}
#Override
public void entriesAdded(Collection<String> addresses) {
// TODO Auto-generated method stub
}
});
There is a means to find the offline/online status of the user. It can be done by seeking the PRESENCE OF THE USER. Here is the code snippet :
//here is how you can get is ONLINE or OFFLINE
Presence availability = roster.getPresence(user);
And here is the code to get its presence mode i.e if user is available then is he AWAY,DONOT DISTURB MODE or ONLINE For CHAT.
public int retrieveState_mode(Mode userMode, boolean isOnline) {
int userState = 0;
/** 0 for offline, 1 for online, 2 for away,3 for busy*/
if(userMode == Mode.dnd) {
userState = 3;
} else if (userMode == Mode.away || userMode == Mode.xa) {
userState = 2;
} else if (isOnline) {
userState = 1;
}
return userState;
}
you can save this state in an array list as :-
mFriendsDataClass.friendState = retrieveState_mode(availability.getMode(),availability.isAvailable());
Please let me know if you have any queries regarding xmpp/smack in chat type application

Am I creating my custom ArrayAdapter correctly?

My ListView populates correctly, but for some reason adding and removing is quirky and does not work properly! Am I doing something wrong?
Set things up in OnCreate()
listView = (ListView) findViewById(R.id.ListView);
registerForContextMenu(listView);
deserializeQuotes();
if(quotes == null || quotes.size() == 0){
quotes = new ArrayList<Quote>();
//populateDefaultQuotes();
//serializeQuotes();
//getQuotesFromYQL();
}
this.quotesAdapter = new QuoteAdapter(this, R.layout.mainrow, quotes);
listView.setAdapter(this.quotesAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
deserializeQuotes();
Quote myQuote = quotes.get(position);
Toast toast = Toast.makeText(getApplicationContext(), myQuote.getName(), Toast.LENGTH_SHORT);
toast.show();
}
});
Quote Adapter Private Class
private class QuoteAdapter extends ArrayAdapter<Quote> {
private ArrayList<Quote> items;
public QuoteAdapter(Context context, int textViewResourceId,
ArrayList<Quote> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.mainrow, null);
}
Quote q = items.get(position);
if (q != null) {
TextView nameText = (TextView) v.findViewById(R.id.nameText);
TextView priceText = (TextView) v.findViewById(R.id.priceText);
TextView changeText = (TextView) v.findViewById(R.id.changeText);
if (nameText != null) {
nameText.setText(q.getSymbol());
}
if (priceText != null) {
priceText.setText(q.getLastTradePriceOnly());
}
if (changeText != null) {
changeText.setText(q.getChange());
}
}
return v;
}
}
Remove an item from the list (THIS DOESNT WORK, DOES NOTHING)
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle()=="Remove"){
deserializeQuotes();
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
quotesAdapter.remove(quotes.get(info.position));
quotesAdapter.notifyDataSetChanged();
serializeQuotes();
}
else {
return false;
}
return true;
}
Add an item to the list (THIS WORKS)
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
deserializeQuotes();
this.quotesAdapter = new QuoteAdapter(this, R.layout.mainrow, quotes);
quotesAdapter.notifyDataSetChanged();
listView.setAdapter(quotesAdapter);
}
}
Here is how I serialize and deserialize
private void serializeQuotes(){
FileOutputStream fos;
try {
fos = openFileOutput(Constants.FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(quotes);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void deserializeQuotes(){
try{
FileInputStream fis = openFileInput(Constants.FILENAME);
ObjectInputStream ois = new ObjectInputStream(fis);
quotes = (ArrayList<Quote>) ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
The code seems to be alright. Can you try using this in your remove?:
if("Remove".equals(item.getTitle())) {
//....
}
Edit:
I just noticed you are de-serializing "Quote" objects by calling deserializeQuotes(). Have you overridden the boolean equals(Object) method of Quote object? When you de-serialize, the object created are not the "same", i.e. they are new objects altogether and if you haven't overridden the equals method:
quotesAdapter.remove(quotes.get(info.position));
will fail because it won't find any Quote object to remove in the list.
Can you check that?

Categories

Resources