android - Odd behavior in adding items to listview -
i have custom photo gallery , need selected images , display filenames in listview
this custom gallery:
import android.app.activity; import android.content.context; import android.content.intent; import android.database.cursor; import android.graphics.bitmap; import android.os.asynctask; import android.os.bundle; import android.provider.mediastore; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.button; import android.widget.checkbox; import android.widget.gridview; import android.widget.imageview; import android.widget.toast; public class customphotogallery extends activity { private gridview grdimages; private button btnselect; private imageadapter imageadapter; private string[] arrpath; private boolean[] thumbnailsselection; private int ids[]; private int count; string filename; /** * overrides methods */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.custom_gallery); grdimages= (gridview) findviewbyid(r.id.grdimages); btnselect= (button) findviewbyid(r.id.btnselect); final string[] columns = { mediastore.images.media.data, mediastore.images.media._id }; final string orderby = mediastore.images.media._id; @suppresswarnings("deprecation") cursor imagecursor = managedquery(mediastore.images.media.external_content_uri, columns, null, null, orderby); int image_column_index = imagecursor.getcolumnindex(mediastore.images.media._id); this.count = imagecursor.getcount(); this.arrpath = new string[this.count]; ids = new int[count]; this.thumbnailsselection = new boolean[this.count]; (int = 0; < this.count; i++) { imagecursor.movetoposition(i); ids[i] = imagecursor.getint(image_column_index); int datacolumnindex = imagecursor.getcolumnindex(mediastore.images.media.data); arrpath[i] = imagecursor.getstring(datacolumnindex); } imageadapter = new imageadapter(); grdimages.setadapter(imageadapter); imagecursor.close(); btnselect.setonclicklistener(new view.onclicklistener() { public void onclick(view v) { final int len = thumbnailsselection.length; int cnt = 0; string selectimages = ""; (int = 0; < len; i++) { if (thumbnailsselection[i]) { cnt++; selectimages = selectimages + arrpath[i] + "|"; } } if (cnt == 0) { toast.maketext(getapplicationcontext(), "please select @ least 1 image", toast.length_long).show(); } else { log.d("selectedimages", selectimages); intent = new intent(); i.putextra("data", selectimages); setresult(activity.result_ok, i); finish(); } } }); } @override public void onbackpressed() { setresult(activity.result_canceled); super.onbackpressed(); } /** * class method */ /** * method used set bitmap. * @param iv represented imageview * @param id represented id */ private void setbitmap(final imageview iv, final int id) { new asynctask<void, void, bitmap>() { @override protected bitmap doinbackground(void... params) { return mediastore.images.thumbnails.getthumbnail(getapplicationcontext().getcontentresolver(), id, mediastore.images.thumbnails.micro_kind, null); } @override protected void onpostexecute(bitmap result) { super.onpostexecute(result); iv.setimagebitmap(result); } }.execute(); } /** * list adapter * @author tasol */ public class imageadapter extends baseadapter { private layoutinflater minflater; public imageadapter() { minflater = (layoutinflater) getsystemservice(context.layout_inflater_service); } public int getcount() { return count; } public object getitem(int position) { return position; } public long getitemid(int position) { return position; } public view getview(int position, view convertview, viewgroup parent) { final viewholder holder; if (convertview == null) { holder = new viewholder(); convertview = minflater.inflate(r.layout.custom_gallery_item, null); holder.imgthumb = (imageview) convertview.findviewbyid(r.id.imgthumb); holder.chkimage = (checkbox) convertview.findviewbyid(r.id.chkimage); convertview.settag(holder); } else { holder = (viewholder) convertview.gettag(); } holder.chkimage.setid(position); holder.imgthumb.setid(position); holder.chkimage.setonclicklistener(new view.onclicklistener() { public void onclick(view v) { checkbox cb = (checkbox) v; int id = cb.getid(); if (thumbnailsselection[id]) { cb.setchecked(false); thumbnailsselection[id] = false; } else { cb.setchecked(true); thumbnailsselection[id] = true; } } }); holder.imgthumb.setonclicklistener(new view.onclicklistener() { public void onclick(view v) { int id = holder.chkimage.getid(); if (thumbnailsselection[id]) { holder.chkimage.setchecked(false); thumbnailsselection[id] = false; } else { holder.chkimage.setchecked(true); thumbnailsselection[id] = true; } } }); try { setbitmap(holder.imgthumb, ids[position]); } catch (throwable e) { } holder.chkimage.setchecked(thumbnailsselection[position]); holder.id = position; return convertview; } } /** * inner class * @author tasol */ class viewholder { imageview imgthumb; checkbox chkimage; int id; } }
now result based on selection goes main activity need display selected images in listview.
this i'm trying do
@override public void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (resultcode == result_ok) { if(requestcode == pick_image_multiple){ imagespathlist = new arraylist<string>(); string[] imagespath = data.getstringextra("data").split("\\|"); try{ lnrimages.removeallviews(); }catch (throwable e){ e.printstacktrace(); } (int i=0;i<imagespath.length;i++){ //toast.maketext(mainactivity.this,string.valueof(imagespath.length),toast.length_long).show(); imagespathlist.add(imagespath[i]); //toast.maketext(mainactivity.this,imagespathlist.tostring(),toast.length_long).show(); yourbitmap = bitmapfactory.decodefile(imagespath[i]); imageview imageview = new imageview(this); imageview.setimagebitmap(yourbitmap); imageview.setadjustviewbounds(true); //lnrimages.addview(imageview); uri uri = (uri.fromfile(new file(imagespath[i]))); filename = uri.getlastpathsegment(); //toast.maketext(mainactivity.this,filename,toast.length_long).show(); uri selectedimage = data.getdata(); encodedimage= bitmaptobase64(yourbitmap); //toast.maketext(mainactivity.this,encodedimage,toast.length_long).show(); mystringlist.add(filename); mystringarray = mystringlist.toarray(); lv.setadapter(null); toast.maketext(mainactivity.this,(string)mystringarray[i],toast.length_long).show(); arrayadapter = new arrayadapter<string>( this, android.r.layout.simple_list_item_1, mystringlist ); lv.setadapter(arrayadapter); arrayadapter.notifydatasetchanged(); } } } }
now problem is:
1) if select 1 single image it's showing me toast filename not adding listview
2)if select 2 images adding list view normal
3) if select more 2 appending old list(ie..adding newly selected images selected images) though have set adapter
'null'
4) selecting large number of images takes time consumption adding listview crashing
app due memory
.
so can suggest me best way of handling ?
thanks in advance!
there multiple problems in code. in java
reference, instead of creating adapter again , again, should set new list adapter , should call notifydatasetchanged
. example, imageadapter
should this
public class imageadapter extends baseadapter { private layoutinflater minflater; private arraylist<string> imageslist = new arraylist<>(); public void updateimageslist(arraylist<strinf> newimages) { if(newimages != null && newimages.size() > 0) { this.imageslist.clear(); this.imageslist.addall(newimages); } } }
and should create global adapter
variable using future list updates
and in onactivityresult
, should populate strings list in loop , after loop should update adapter list as
@override public void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (resultcode == result_ok) { if (requestcode == pick_image_multiple) { (int = 0; < imagespath.length; i++) { //toast.maketext(mainactivity.this,string.valueof(imagespath.length),toast.length_long).show(); imagespathlist.add(imagespath[i]); //toast.maketext(mainactivity.this,imagespathlist.tostring(),toast.length_long).show(); yourbitmap = bitmapfactory.decodefile(imagespath[i]); imageview imageview = new imageview(this); imageview.setimagebitmap(yourbitmap); imageview.setadjustviewbounds(true); //lnrimages.addview(imageview); uri uri = (uri.fromfile(new file(imagespath[i]))); filename = uri.getlastpathsegment(); //toast.maketext(mainactivity.this,filename,toast.length_long).show(); uri selectedimage = data.getdata(); encodedimage = bitmaptobase64(yourbitmap); //toast.maketext(mainactivity.this,encodedimage,toast.length_long).show(); mystringlist.add(filename); toast.maketext(mainactivity.this, (string) mystringarray[i], toast.length_long).show(); } arrayadapter.updateimages(mystringlist); arrayadapter.notifydatasetchanged(); } } }
apart above 2 changes, there great performance impact because you doing i/o operations on ui thread decoding bitmap files on main thread not approach cause outofmemoryerror it slow down application. should bitmap operations or displaying using universal image loader https://github.com/nostra13/android-universal-image-loader
hope helps.
Comments
Post a Comment