Android Dragging Custom ListView -
i'm trying implement google example (https://www.youtube.com/watch?v=_bzivjmgh-q), custom object.
almost ok, items in listview doesn't change position
could explain missed in code?
mainactivity: @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_list_view); arraylist<product> prodarray = new arraylist<product>(); for(int = 0; < cheeses.scheesestrings.length; ++i) { prodarray.add(new product(cheeses.scheesestrings[i],r.drawable.ic_launcher)); } stablearrayadapter adapter = new stablearrayadapter(this, r.layout.text_view, prodarray); dynamiclistview listview = (dynamiclistview) findviewbyid(r.id.listview); listview.setcheeselist(prodarray); listview.setadapter(adapter); listview.setchoicemode(listview.choice_mode_single); }
adapter:
package com.example.android.listviewdragginganimation; public class stablearrayadapter extends arrayadapter<product> { final int invalid_id = -1; layoutinflater linflater; arraylist<product> prodarray = new arraylist<product>(); public stablearrayadapter(context context, int textviewresourceid, list<product> objects) { super(context, textviewresourceid, objects); linflater = (layoutinflater) context .getsystemservice(context.layout_inflater_service); (int = 0; < objects.size(); ++i) { prodarray.add(objects.get(i)); } } // пункт списка @override public view getview(int position, view convertview, viewgroup parent) { // используем созданные, но не используемые view view view = convertview; if (view == null) { view = linflater.inflate(r.layout.item, parent, false); } product p = getproduct(position); final int pos = position; final string name = p.prodname; ((textview) view.findviewbyid(r.id.tvdescr)).settext(p.prodname); ((imageview) view.findviewbyid(r.id.ivimage)).setimageresource(p.prodimage); return view; } // товар по позиции product getproduct(int position) { return ((product) getitem(position)); } @override public product getitem(int position) { return prodarray.get(position); } @override public long getitemid(int position) { if (position < 0 || position >= prodarray.size()) { return invalid_id; } return position; } @override public boolean hasstableids() { return true; } }
listviewanimation:
package com.example.android.listviewdragginganimation; import java.util.arraylist; public class dynamiclistview extends listview { private final int smooth_scroll_amount_at_edge = 15; private final int move_duration = 150; private final int line_thickness = 15; public arraylist<string> mcheeselist; public arraylist<product> prod; private int mlasteventy = -1; private int mdowny = -1; private int mdownx = -1; private int mtotaloffset = 0; private boolean mcellismobile = false; private boolean mismobilescrolling = false; private int msmoothscrollamountatedge = 0; private final int invalid_id = -1; private long maboveitemid = invalid_id; private long mmobileitemid = invalid_id; private long mbelowitemid = invalid_id; private bitmapdrawable mhovercell; private rect mhovercellcurrentbounds; private rect mhovercelloriginalbounds; private final int invalid_pointer_id = -1; private int mactivepointerid = invalid_pointer_id; private boolean miswaitingforscrollfinish = false; private int mscrollstate = onscrolllistener.scroll_state_idle; public dynamiclistview(context context) { super(context); init(context); } public dynamiclistview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); init(context); } public dynamiclistview(context context, attributeset attrs) { super(context, attrs); init(context); } public void init(context context) { setonitemlongclicklistener(monitemlongclicklistener); setonscrolllistener(mscrolllistener); displaymetrics metrics = context.getresources().getdisplaymetrics(); msmoothscrollamountatedge = (int)(smooth_scroll_amount_at_edge / metrics.density); } private onitemlongclicklistener monitemlongclicklistener = new onitemlongclicklistener() { public boolean onitemlongclick(adapterview<?> arg0, view arg1, int pos, long id) { mtotaloffset = 0; int position = pointtoposition(mdownx, mdowny); int itemnum = position - getfirstvisibleposition(); view selectedview = getchildat(itemnum); mmobileitemid = getadapter().getitemid(position); mhovercell = getandaddhoverview(selectedview); selectedview.setvisibility(invisible); mcellismobile = true; updateneighborviewsforid(mmobileitemid); return true; } }; private bitmapdrawable getandaddhoverview(view v) { int w = v.getwidth(); int h = v.getheight(); int top = v.gettop(); int left = v.getleft(); bitmap b = getbitmapwithborder(v); bitmapdrawable drawable = new bitmapdrawable(getresources(), b); mhovercelloriginalbounds = new rect(left, top, left + w, top + h); mhovercellcurrentbounds = new rect(mhovercelloriginalbounds); drawable.setbounds(mhovercellcurrentbounds); return drawable; } /** draws black border on screenshot of view passed in. */ private bitmap getbitmapwithborder(view v) { bitmap bitmap = getbitmapfromview(v); canvas can = new canvas(bitmap); rect rect = new rect(0, 0, bitmap.getwidth(), bitmap.getheight()); paint paint = new paint(); paint.setstyle(paint.style.stroke); paint.setstrokewidth(line_thickness); paint.setcolor(color.black); can.drawbitmap(bitmap, 0, 0, null); can.drawrect(rect, paint); return bitmap; } /** returns bitmap showing screenshot of view passed in. */ private bitmap getbitmapfromview(view v) { bitmap bitmap = bitmap.createbitmap(v.getwidth(), v.getheight(), bitmap.config.argb_8888); canvas canvas = new canvas (bitmap); v.draw(canvas); return bitmap; } private void updateneighborviewsforid(long itemid) { int position = getpositionforid(itemid); stablearrayadapter adapter = ((stablearrayadapter)getadapter()); maboveitemid = adapter.getitemid(position - 1); mbelowitemid = adapter.getitemid(position + 1); } /** retrieves view in list corresponding itemid */ public view getviewforid (long itemid) { int firstvisibleposition = getfirstvisibleposition(); stablearrayadapter adapter = ((stablearrayadapter)getadapter()); for(int = 0; < getchildcount(); i++) { view v = getchildat(i); int position = firstvisibleposition + i; long id = adapter.getitemid(position); if (id == itemid) { return v; } } return null; } /** retrieves position in list corresponding itemid */ public int getpositionforid (long itemid) { view v = getviewforid(itemid); if (v == null) { return -1; } else { return getpositionforview(v); } } @override protected void dispatchdraw(canvas canvas) { super.dispatchdraw(canvas); if (mhovercell != null) { mhovercell.draw(canvas); } } @override public boolean ontouchevent (motionevent event) { switch (event.getaction() & motionevent.action_mask) { case motionevent.action_down: mdownx = (int)event.getx(); mdowny = (int)event.gety(); mactivepointerid = event.getpointerid(0); break; case motionevent.action_move: if (mactivepointerid == invalid_pointer_id) { break; } int pointerindex = event.findpointerindex(mactivepointerid); mlasteventy = (int) event.gety(pointerindex); int deltay = mlasteventy - mdowny; if (mcellismobile) { mhovercellcurrentbounds.offsetto(mhovercelloriginalbounds.left, mhovercelloriginalbounds.top + deltay + mtotaloffset); mhovercell.setbounds(mhovercellcurrentbounds); invalidate(); handlecellswitch(); mismobilescrolling = false; handlemobilecellscroll(); return false; } break; case motionevent.action_up: toucheventsended(); break; case motionevent.action_cancel: toucheventscancelled(); break; case motionevent.action_pointer_up: /* if multitouch event took place , original touch dictating * movement of hover cell has ended, dragging event * ends , hover cell animated corresponding position * in listview. */ pointerindex = (event.getaction() & motionevent.action_pointer_index_mask) >> motionevent.action_pointer_index_shift; final int pointerid = event.getpointerid(pointerindex); if (pointerid == mactivepointerid) { toucheventsended(); } break; default: break; } return super.ontouchevent(event); } private void handlecellswitch() { final int deltay = mlasteventy - mdowny; int deltaytotal = mhovercelloriginalbounds.top + mtotaloffset + deltay; view belowview = getviewforid(mbelowitemid); view mobileview = getviewforid(mmobileitemid); view aboveview = getviewforid(maboveitemid); boolean isbelow = (belowview != null) && (deltaytotal > belowview.gettop()); boolean isabove = (aboveview != null) && (deltaytotal < aboveview.gettop()); if (isbelow || isabove) { final long switchitemid = isbelow ? mbelowitemid : maboveitemid; view switchview = isbelow ? belowview : aboveview; final int originalitem = getpositionforview(mobileview); if (switchview == null) { updateneighborviewsforid(mmobileitemid); return; } //swapelements(mcheeselist, originalitem, getpositionforview(switchview)); swapelements(prod, originalitem, getpositionforid(switchitemid)); ((baseadapter) getadapter()).notifydatasetchanged(); mdowny = mlasteventy; final int switchviewstarttop = switchview.gettop(); mobileview.setvisibility(view.visible); switchview.setvisibility(view.invisible); updateneighborviewsforid(mmobileitemid); final viewtreeobserver observer = getviewtreeobserver(); observer.addonpredrawlistener(new viewtreeobserver.onpredrawlistener() { public boolean onpredraw() { observer.removeonpredrawlistener(this); view switchview = getviewforid(switchitemid); mtotaloffset += deltay; int switchviewnewtop = switchview.gettop(); int delta = switchviewstarttop - switchviewnewtop; switchview.settranslationy(delta); objectanimator animator = objectanimator.offloat(switchview, view.translation_y, 0); animator.setduration(move_duration); animator.start(); return true; } }); } } private void swapelements(arraylist arraylist, int indexone, int indextwo) { object temp = arraylist.get(indexone); arraylist.set(indexone, arraylist.get(indextwo)); arraylist.set(indextwo, temp); } private void toucheventsended () { final view mobileview = getviewforid(mmobileitemid); if (mcellismobile|| miswaitingforscrollfinish) { mcellismobile = false; miswaitingforscrollfinish = false; mismobilescrolling = false; mactivepointerid = invalid_pointer_id; if (mscrollstate != onscrolllistener.scroll_state_idle) { miswaitingforscrollfinish = true; return; } mhovercellcurrentbounds.offsetto(mhovercelloriginalbounds.left, mobileview.gettop()); objectanimator hoverviewanimator = objectanimator.ofobject(mhovercell, "bounds", sboundevaluator, mhovercellcurrentbounds); hoverviewanimator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator valueanimator) { invalidate(); } }); hoverviewanimator.addlistener(new animatorlisteneradapter() { @override public void onanimationstart(animator animation) { setenabled(false); } @override public void onanimationend(animator animation) { maboveitemid = invalid_id; mmobileitemid = invalid_id; mbelowitemid = invalid_id; mobileview.setvisibility(visible); mhovercell = null; setenabled(true); invalidate(); } }); hoverviewanimator.start(); } else { toucheventscancelled(); } } private void toucheventscancelled () { view mobileview = getviewforid(mmobileitemid); if (mcellismobile) { maboveitemid = invalid_id; mmobileitemid = invalid_id; mbelowitemid = invalid_id; mobileview.setvisibility(visible); mhovercell = null; invalidate(); } mcellismobile = false; mismobilescrolling = false; mactivepointerid = invalid_pointer_id; } private final static typeevaluator<rect> sboundevaluator = new typeevaluator<rect>() { public rect evaluate(float fraction, rect startvalue, rect endvalue) { return new rect(interpolate(startvalue.left, endvalue.left, fraction), interpolate(startvalue.top, endvalue.top, fraction), interpolate(startvalue.right, endvalue.right, fraction), interpolate(startvalue.bottom, endvalue.bottom, fraction)); } public int interpolate(int start, int end, float fraction) { return (int)(start + fraction * (end - start)); } }; private void handlemobilecellscroll() { mismobilescrolling = handlemobilecellscroll(mhovercellcurrentbounds); } public boolean handlemobilecellscroll(rect r) { int offset = computeverticalscrolloffset(); int height = getheight(); int extent = computeverticalscrollextent(); int range = computeverticalscrollrange(); int hoverviewtop = r.top; int hoverheight = r.height(); if (hoverviewtop <= 0 && offset > 0) { smoothscrollby(-msmoothscrollamountatedge, 0); return true; } if (hoverviewtop + hoverheight >= height && (offset + extent) < range) { smoothscrollby(msmoothscrollamountatedge, 0); return true; } return false; } public void setcheeselist(arraylist<product> cheeselist) { prod = cheeselist; } private onscrolllistener mscrolllistener = new onscrolllistener () { private int mpreviousfirstvisibleitem = -1; private int mpreviousvisibleitemcount = -1; private int mcurrentfirstvisibleitem; private int mcurrentvisibleitemcount; private int mcurrentscrollstate; public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { mcurrentfirstvisibleitem = firstvisibleitem; mcurrentvisibleitemcount = visibleitemcount; mpreviousfirstvisibleitem = (mpreviousfirstvisibleitem == -1) ? mcurrentfirstvisibleitem : mpreviousfirstvisibleitem; mpreviousvisibleitemcount = (mpreviousvisibleitemcount == -1) ? mcurrentvisibleitemcount : mpreviousvisibleitemcount; checkandhandlefirstvisiblecellchange(); checkandhandlelastvisiblecellchange(); mpreviousfirstvisibleitem = mcurrentfirstvisibleitem; mpreviousvisibleitemcount = mcurrentvisibleitemcount; } @override public void onscrollstatechanged(abslistview view, int scrollstate) { mcurrentscrollstate = scrollstate; mscrollstate = scrollstate; isscrollcompleted(); } private void isscrollcompleted() { if (mcurrentvisibleitemcount > 0 && mcurrentscrollstate == scroll_state_idle) { if (mcellismobile && mismobilescrolling) { handlemobilecellscroll(); } else if (miswaitingforscrollfinish) { toucheventsended(); } } } public void checkandhandlefirstvisiblecellchange() { if (mcurrentfirstvisibleitem != mpreviousfirstvisibleitem) { if (mcellismobile && mmobileitemid != invalid_id) { updateneighborviewsforid(mmobileitemid); handlecellswitch(); } } } public void checkandhandlelastvisiblecellchange() { int currentlastvisibleitem = mcurrentfirstvisibleitem + mcurrentvisibleitemcount; int previouslastvisibleitem = mpreviousfirstvisibleitem + mpreviousvisibleitemcount; if (currentlastvisibleitem != previouslastvisibleitem) { if (mcellismobile && mmobileitemid != invalid_id) { updateneighborviewsforid(mmobileitemid); handlecellswitch(); } } } }; }
thx in advance!
problem solved in way: i've sent custom object adapter , build view custom object.
Comments
Post a Comment