android - Gingerbread listview item animation issue -
i've looked issue nothing i've found matches situation.
my problem occurs onandroid 2.3.x (on 4.x works perfectly)
i have application custom list view. initialize listview follows
listadapter mlistadapter = new listadapter(getapplicationcontext(), this, ...); lvselector = (listview) findviewbyid(r.id.listview1); lvselector.setadapter(mlistadapter);
my listadapter follows:
public class listadapter extends baseadapter { static class holder { linearlayout layoutroot, layoutcolor; textview htext; animation anim = animationutils.loadanimation(mactivity, r.anim.anim_list_item); public holder() { layoutroot = new linearlayout(mcontext); layoutcolor = new linearlayout(mcontext); htext = new textview(mcontext); } public holder(holder holder) { this.layoutroot = holder.layoutroot; this.layoutcolor = holder.layoutcolor; this.htext = holder.htext; } } int mswap1, mswap2; animation manimation; public listadapter(context _context, activity _activity, filehandler _filehandler, string _strschemaname, list<string> _list, list<string> _solution) { mcontext = _context; mactivity = _activity; manimation = animationutils.loadanimation(mactivity, r.anim.anim_list_item); manimation.reset(); mswap1 = mswap2 = -1; /* ... */ @override public view getview(int position, view convertview, viewgroup parent) { final int fposition = position; view row = convertview; holder lholder = null; if (row==null) { layoutinflater inflater = mactivity.getlayoutinflater(); row = inflater.inflate(r.layout.layout_schema_element, parent, false); lholder = new holder(); lholder.layoutroot = (linearlayout) row.findviewbyid(r.id.elementlayoutroot); lholder.layoutcolor = (linearlayout) row.findviewbyid(r.id.elementlayoutcolor); lholder.htext = (textview) row.findviewbyid(r.id.textviewword); row.settag(lholder); } else { lholder = (holder)row.gettag(); } row.setonclicklistener(null); if (position==0 || position==mdatalist.size()-1) { lholder.layoutcolor.setbackgroundresource(r.drawable.bg_elem_fixed); lholder.layoutcolor.setonclicklistener(null); } else { lholder.layoutcolor.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { moveelement(fposition); } }); } lholder.htext.settext(mdatalist.get(position)); lholder.layoutroot.setbackgroundresource(0); mholder.set(position, lholder); return row; } } protected void moveelement(int _element) { if (mdatalist.get(_element).equals(msolution.get(_element))) return; if (mswap1==-1) { system.out.println("setting swap1=" + _element); mholder.get(_element).layoutroot.setbackgroundresource(r.drawable.bg_elem_selected_lite); mswap1 = _element; } else { if (mswap2==-1) { system.out.println("setting swap2=" + _element); mholder.get(_element).layoutroot.setbackgroundresource(r.drawable.bg_elem_selected_lite); mswap2 = _element; } } if (mswap1!=-1) { system.out.println("running animation on mswap1=" + mswap1); mholder.get(mswap1).layoutroot.clearanimation(); mholder.get(mswap1).layoutroot.startanimation(manimation); } /***** not work *****/ if (mswap2!=-1) { system.out.println("running animation on mswap2=" + mswap2); mholder.get(mswap2).layoutroot.clearanimation(); mholder.get(mswap2).layoutroot.startanimation(manimation); } if (mswap1!=-1 && mswap2!=-1) { mholder.get(mswap1).layoutroot.setbackgroundcolor(0); mholder.get(mswap2).layoutroot.setbackgroundcolor(0); if (mswap1==mswap2) { mswap1 = mswap2 = -1; return; } collections.swap(mdatalist, mswap1, mswap2); collections.swap(mholder, mswap1, mswap2); collections.swap(dataobjs, mswap1, mswap2); mswap1 = mswap2 = -1; notifydatasetchanged(); } }
}
everything works fine when perform collections.swap(list, mswap1, mswap2), elements correctly swapped.
first animation (mswap1) run fine; problem when second animation run (mswap2), executed on element in screen if mswap2 right (e.g.: mswap1=1 -> second element in list animated, mswap2=2 -> n-1 element , n-2 element in list animated n number of visible elemnts).
i've solved problem replacing animation calls
mholder.get(idx).layoutroot.clearanimation(); mholder.get(idx).layoutroot.startanimation(manimation);
with following method
private void animateitem(int _index, animation _animation) { if ( _index<mlvselector.getfirstvisibleposition() // selected item above first visible element || _index>mlvselector.getlastvisibleposition() // selected item below last visible element ) // element invisible -> no animation return; int newindex = _index; if ( android.os.build.version.sdk_int < android.os.build.version_codes.ice_cream_sandwich // before android 4.0 && mswap2>=0 // second selection && mswap1!=mswap2 // second selection differs first selection ) newindex = mlvselector.getfirstvisibleposition() + (mlvselector.getlastvisibleposition() - _index); mholder.get(newindex).layoutroot.clearanimation(); mholder.get(newindex).layoutroot.startanimation(_animation); }
adding animation argument method allows differentiate animation between elements (mswap1 , mswap2).
Comments
Post a Comment