public CollapseAnimationListener(AnimatedExpandableListAdapter adapter, int groupPosition, ExpandableListView listView, GroupInfo info, DummyView dummyView) { _adapter = adapter; _groupPosition = groupPosition; _listView = listView; _info = info; _dummyView = dummyView; }
public ExpandAnimationListener(AnimatedExpandableListAdapter adapter, int groupPosition, DummyView dummyView) { _adapter = adapter; _groupPosition = groupPosition; _dummyView = dummyView; }
/** * Override {@link #getChildView(int, int, boolean, View, ViewGroup)} instead. */ public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent) { GroupInfo info = GetGroupInfo(groupPosition); if (info.Animating) { // If this group is animating, return the a DummyView... if (convertView is DummyView == false) { convertView = new DummyView(parent.Context); convertView.LayoutParameters = new AbsListView.LayoutParams(AbsListView.LayoutParams.MatchParent, 0); } if (childPosition < info.FirstChildPosition) { // The reason why we do this is to support the collapse // this group when the group view is not visible but the // children of this group are. When notifyDataSetChanged // is called, the ExpandableListView tries to keep the // list position the same by saving the first visible item // and jumping back to that item after the views have been // refreshed. Now the problem is, if a group has 2 items // and the first visible item is the 2nd child of the group // and this group is collapsed, then the dummy view will be // used for the group. But now the group only has 1 item // which is the dummy view, thus when the ListView is trying // to restore the scroll position, it will try to jump to // the second item of the group. But this group no longer // has a second item, so it is forced to jump to the next // group. This will cause a very ugly visual glitch. So // the way that we counteract this is by creating as many // dummy views as we need to maintain the scroll position // of the ListView after notifyDataSetChanged has been // called. convertView.LayoutParameters.Height = 0; return(convertView); } ExpandableListView listview = (ExpandableListView)parent; DummyView dummyView = (DummyView)convertView; // Clear the views that the dummy view draws dummyView.ClearViews(); // Set the style of the divider dummyView.SetDivider(listview.Divider, parent.MeasuredWidth, listview.DividerHeight); // Make measure specs to measure child views int measureSpecW = View.MeasureSpec.MakeMeasureSpec(parent.Width, MeasureSpecMode.Exactly); int measureSpecH = View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified); int totalHeight = 0; int clipHeight = parent.Height; int len = GetRealChildrenCount(groupPosition); for (int i = info.FirstChildPosition; i < len; i++) { View childView = GetRealChildView(groupPosition, i, (i == len - 1), null, parent); AbsListView.LayoutParams p = (AbsListView.LayoutParams)childView.LayoutParameters; if (p == null) { p = (AbsListView.LayoutParams)GenerateDefaultLayoutParams(); childView.LayoutParameters = p; } int lpHeight = p.Height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = View.MeasureSpec.MakeMeasureSpec(lpHeight, MeasureSpecMode.Exactly); } else { childHeightSpec = measureSpecH; } childView.Measure(measureSpecW, childHeightSpec); totalHeight += childView.MeasuredHeight; if (totalHeight < clipHeight) { // we only need to draw enough views to fool the user... dummyView.AddFakeView(childView); } else { dummyView.AddFakeView(childView); // if this group has too many views, we don't want to // calculate the height of everything... just do a light // approximation and break int averageHeight = totalHeight / (i + 1); totalHeight += (len - i - 1) * averageHeight; break; } } Java.Lang.Object o; int state = (o = dummyView.Tag) == null ? STATE_IDLE : (Int16)o; if (info.Expanding && state != STATE_EXPANDING) { ExpandAnimation ani = new ExpandAnimation(dummyView, 0, totalHeight, info); ani.Duration = _parent.GetAnimationDuration(); ani.SetAnimationListener(new ExpandAnimationListener(this, groupPosition, dummyView)); dummyView.StartAnimation(ani); dummyView.Tag = STATE_EXPANDING; } else if (!info.Expanding && state != STATE_COLLAPSING) { if (info.DummyHeight == -1) { info.DummyHeight = totalHeight; } ExpandAnimation ani = new ExpandAnimation(dummyView, info.DummyHeight, 0, info); ani.Duration = _parent.GetAnimationDuration(); ani.SetAnimationListener(new CollapseAnimationListener(this, groupPosition, listview, info, dummyView)); dummyView.StartAnimation(ani); dummyView.Tag = STATE_COLLAPSING; } return(convertView); } else { return(GetRealChildView(groupPosition, childPosition, isLastChild, convertView, parent)); } }