java - GridView Rearange switch by drag and drop -
i have program creates grid , rearranges drag-and-droping, first of functional not way wanted it. must common rearrange this, drag object , when drop falls position moving rest forward until find empty space, want more simple; want objects switch 1 that's in position dropped it. code of adapter:
@suppresslint("wrongcall") public class draggridview extends viewgroup implements view.ontouchlistener, view.onclicklistener, view.onlongclicklistener { public static float childratio = .9f; protected int colcount, childsize, padding, dpi, scroll = 0; protected float lastdelta = 0; protected handler handler = new handler(); protected int dragged = -1, lastx = -1, lasty = -1, lasttarget = -1; protected boolean enabled = true, touching = false; public static int animt = 150; protected arraylist<integer> newpositions = new arraylist<integer>(); protected onrearrangelistener onrearrangelistener; protected onclicklistener secondaryonclicklistener; private onitemclicklistener onitemclicklistener; public interface onrearrangelistener { public abstract void onrearrange(int oldindex, int newindex); } public draggridview(context context, attributeset attrs) { super(context, attrs); setlisteners(); handler.removecallbacks(updatetask); handler.postattime(updatetask, systemclock.uptimemillis() + 500); setchildrendrawingorderenabled(true); displaymetrics metrics = new displaymetrics(); ((activity) context).getwindowmanager().getdefaultdisplay() .getmetrics(metrics); dpi = metrics.densitydpi; } protected void setlisteners() { setontouchlistener(this); super.setonclicklistener(this); setonlongclicklistener(this); } @override public void setonclicklistener(onclicklistener l) { secondaryonclicklistener = l; } protected runnable updatetask = new runnable() { public void run() { if (dragged != -1) { if (lasty < padding * 3 && scroll > 0) scroll -= 20; else if (lasty > getbottom() - gettop() - (padding * 3) && scroll < getmaxscroll()) scroll += 20; } else if (lastdelta != 0 && !touching) { scroll += lastdelta; lastdelta *= .9; if (math.abs(lastdelta) < .25) lastdelta = 0; } clampscroll(); onlayout(true, getleft(), gettop(), getright(), getbottom()); handler.postdelayed(this, 25); } }; @override public void addview(view child) { super.addview(child); newpositions.add(-1); }; @override public void removeviewat(int index) { super.removeviewat(index); newpositions.remove(index); }; @override protected void onlayout(boolean changed, int l, int t, int r, int b) { // compute width of view, in dp float w = (r - l) / (dpi / 160f); colcount = 2; int sub = 240; w -= 280; while (w > 0) { colcount++; w -= sub; sub += 40; } childsize = (r - l) / colcount; childsize = math.round(childsize * childratio); padding = ((r - l) - (childsize * colcount)) / (colcount + 1); (int = 0; < getchildcount(); i++) if (i != dragged) { point xy = getcoorfromindex(i); getchildat(i).layout(xy.x, xy.y, xy.x + childsize, xy.y + childsize); } } @override protected int getchilddrawingorder(int childcount, int i) { if (dragged == -1) return i; else if (i == childcount - 1) return dragged; else if (i >= dragged) return + 1; return i; } public int getindexfromcoor(int x, int y) { int col = getcolorrowfromcoor(x), row = getcolorrowfromcoor(y + scroll); if (col == -1 || row == -1) return -1; int index = row * colcount + col; if (index >= getchildcount()) return -1; return index; } protected int getcolorrowfromcoor(int coor) { coor -= padding; (int = 0; coor > 0; i++) { if (coor < childsize) return i; coor -= (childsize + padding); } return -1; } protected int gettargetfromcoor(int x, int y) { if (getcolorrowfromcoor(y + scroll) == -1) return -1; int leftpos = getindexfromcoor(x - (childsize / 4), y); int rightpos = getindexfromcoor(x + (childsize / 4), y); if (leftpos == -1 && rightpos == -1) return -1; if (leftpos == rightpos) return -1; int target = -1; if (rightpos > -1) target = rightpos; else if (leftpos > -1) target = leftpos + 1; if (dragged < target) return target - 1; return target; } protected point getcoorfromindex(int index) { int col = index % colcount; int row = index / colcount; return new point(padding + (childsize + padding) * col, padding + (childsize + padding) * row - scroll); } public int getindexof(view child) { (int = 0; < getchildcount(); i++) if (getchildat(i) == child) return i; return -1; } public void onclick(view view) { if (enabled) { if (secondaryonclicklistener != null) secondaryonclicklistener.onclick(view); if (onitemclicklistener != null && getlastindex() != -1) onitemclicklistener.onitemclick(null, getchildat(getlastindex()), getlastindex(), getlastindex() / colcount); } } public boolean onlongclick(view view) { if (!enabled) return false; int index = getlastindex(); if (index != -1) { dragged = index; animatedragged(); return true; } return false; } @suppresslint("wrongcall") public boolean ontouch(view view, motionevent event) { int action = event.getaction(); switch (action & motionevent.action_mask) { case motionevent.action_down: enabled = true; lastx = (int) event.getx(); lasty = (int) event.gety(); touching = true; break; case motionevent.action_move: int delta = lasty - (int) event.gety(); if (dragged != -1) { // change draw location of dragged visual int x = (int) event.getx(), y = (int) event.gety(); int l = x - (3 * childsize / 4), t = y - (3 * childsize / 4); getchildat(dragged).layout(l, t, l + (childsize * 3 / 2), t + (childsize * 3 / 2)); // check new target hover int target = gettargetfromcoor(x, y); if (lasttarget != target) { if (target != -1) { animategap(target); lasttarget = target; } } } else { scroll += delta; clampscroll(); if (math.abs(delta) > 2) enabled = false; onlayout(true, getleft(), gettop(), getright(), getbottom()); } lastx = (int) event.getx(); lasty = (int) event.gety(); lastdelta = delta; break; case motionevent.action_up: if (dragged != -1) { view v = getchildat(dragged); if (lasttarget != -1) reorderchildren(); else { point xy = getcoorfromindex(dragged); v.layout(xy.x, xy.y, xy.x + childsize, xy.y + childsize); } v.clearanimation(); if (v instanceof imageview) ((imageview) v).setalpha(255); lasttarget = -1; dragged = -1; } touching = false; break; } if (dragged != -1) return true; return false; } protected void animatedragged() { view v = getchildat(dragged); int x = getcoorfromindex(dragged).x + childsize / 2, y = getcoorfromindex(dragged).y + childsize / 2; int l = x - (3 * childsize / 4), t = y - (3 * childsize / 4); v.layout(l, t, l + (childsize * 3 / 2), t + (childsize * 3 / 2)); animationset animset = new animationset(true); scaleanimation scale = new scaleanimation(.667f, 1, .667f, 1, childsize * 3 / 4, childsize * 3 / 4); scale.setduration(animt); alphaanimation alpha = new alphaanimation(1, .5f); alpha.setduration(animt); animset.addanimation(scale); animset.addanimation(alpha); animset.setfillenabled(true); animset.setfillafter(true); v.clearanimation(); v.startanimation(animset); } protected void animategap(int target) { (int = 0; < getchildcount(); i++) { view v = getchildat(i); if (i == dragged) continue; int newpos = i; if (dragged < target && >= dragged + 1 && <= target) newpos--; else if (target < dragged && >= target && < dragged) newpos++; int oldpos = i; if (newpositions.get(i) != -1) oldpos = newpositions.get(i); if (oldpos == newpos) continue; point oldxy = getcoorfromindex(oldpos); point newxy = getcoorfromindex(newpos); point oldoffset = new point(oldxy.x - v.getleft(), oldxy.y - v.gettop()); point newoffset = new point(newxy.x - v.getleft(), newxy.y - v.gettop()); translateanimation translate = new translateanimation( animation.absolute, oldoffset.x, animation.absolute, newoffset.x, animation.absolute, oldoffset.y, animation.absolute, newoffset.y); translate.setduration(animt); translate.setfillenabled(true); translate.setfillafter(true); v.clearanimation(); v.startanimation(translate); newpositions.set(i, newpos); } } protected void reorderchildren() { if (onrearrangelistener != null) onrearrangelistener.onrearrange(dragged, lasttarget); arraylist<view> children = new arraylist<view>(); (int = 0; < getchildcount(); i++) { getchildat(i).clearanimation(); children.add(getchildat(i)); } removeallviews(); while (dragged != lasttarget) if (lasttarget == children.size()) { children.add(children.remove(dragged)); dragged = lasttarget; } else if (dragged < lasttarget) { collections.swap(children, dragged, dragged + 1); dragged++; } else if (dragged > lasttarget) { collections.swap(children, dragged, dragged - 1); dragged--; } (int = 0; < children.size(); i++) { newpositions.set(i, -1); addview(children.get(i)); } onlayout(true, getleft(), gettop(), getright(), getbottom()); } @suppresslint("wrongcall") public void scrolltotop() { scroll = 0; } public void scrolltobottom() { scroll = integer.max_value; clampscroll(); } protected void clampscroll() { int stretch = 3, overreach = getheight() / 2; int max = getmaxscroll(); max = math.max(max, 0); if (scroll < -overreach) { scroll = -overreach; lastdelta = 0; } else if (scroll > max + overreach) { scroll = max + overreach; lastdelta = 0; } else if (scroll < 0) { if (scroll >= -stretch) scroll = 0; else if (!touching) scroll -= scroll / stretch; } else if (scroll > max) { if (scroll <= max + stretch) scroll = max; else if (!touching) scroll += (max - scroll) / stretch; } } protected int getmaxscroll() { int rowcount = (int) math.ceil((double) getchildcount() / colcount), max = rowcount * childsize + (rowcount + 1) * padding - getheight(); return max; } public int getlastindex() { return getindexfromcoor(lastx, lasty); } public void setonrearrangelistener(onrearrangelistener l) { this.onrearrangelistener = l; } public void setonitemclicklistener(onitemclicklistener l) { this.onitemclicklistener = l; } }
the methods think have change animategap , reorderchildren, don't know how exactly.
Comments
Post a Comment