public CustomAnimateListener(Number State, int groupPosition, View dumyView, GroupInfo info, AnimatedExpandableListView listView, AnimatedExpandableListAdapter parent, Action onListViewAnimationEnd) { this._state = State; this._groupPostion = groupPosition; this._dummyView = dumyView; _listView = listView; _parent = parent; _info = info; OnListViewAnimationEnd = onListViewAnimationEnd; }
/** * Override {@link #getChildView(int, int, bool, View, ViewGroup)} instead. */ public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent) { try { GroupInfo info = getGroupInfo(groupPosition); info.ChildViewCallCount += 1;; 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(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); } AnimatedExpandableListView listView = (AnimatedExpandableListView)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 = MeasureSpec.MakeMeasureSpec(parent.Width, MeasureSpecMode.Exactly); int measureSpecH = 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); LayoutParams p = (LayoutParams)childView.LayoutParameters; if (p == null) { p = (AbsListView.LayoutParams)generateDefaultLayoutParams(); childView.LayoutParameters = p; } int lpHeight = p.Height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = 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; } } object o = dummyView.Tag; Java.Lang.Number state = o == null ? STATE_IDLE : (Java.Lang.Number)o; if (info.expanding && state != STATE_EXPANDING && info.ChildViewCallCount <= 1) //&& info.ChildViewCallCount<=1 { //new System.Threading.Thread(new System.Threading.ThreadStart(delegate //{ // _activity.RunOnUiThread(() => //{ ExpandAnimation ani = new ExpandAnimation(dummyView, 0, totalHeight, info, _activity, this); ani.Duration = this.parent.getAnimationDuration(); //ani.SetInterpolator(_activity, Android.Resource.Animation.LinearInterpolator); ani.Interpolator = new AccelerateDecelerateInterpolator(); ani.SetAnimationListener(new CustomAnimateListener(STATE_EXPANDING, groupPosition, dummyView, info, listView, this, listView.OnAnimationEnd)); //ani.FillAfter = false; dummyView.StartAnimation(ani); //ani.RepeatCount = Animation.StartOnFirstFrame; /*****************Another Animation Implementation***************** * ValueAnimator animator = ValueAnimator.OfInt(0, totalHeight); * animator.SetDuration(this.parent.getAnimationDuration()); * animator.SetInterpolator(new AccelerateDecelerateInterpolator()); * * animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) => * { * * * var value = (int)animator.AnimatedValue; * if (factor != value) * { * factor = value; * ViewGroup.LayoutParams layoutParams = dummyView.LayoutParameters; * layoutParams.Height = value; * dummyView.LayoutParameters = layoutParams; * Console.System.Diagnostics.Debug.WriteLine("Value: " + value.ToString()); * } * * }; * animator.AddListener(new CustomAnimateListener(STATE_EXPANDING, groupPosition, dummyView, info, listView, this)); * * ************************/ dummyView.Tag = STATE_EXPANDING; // }); //})).Start(); } else if (!info.expanding && state != STATE_COLLAPSING && info.ChildViewCallCount <= 1) //&& info.ChildViewCallCount<=1 { if (info.dummyHeight == -1) { info.dummyHeight = totalHeight; } //new System.Threading.Thread(new System.Threading.ThreadStart(delegate //{ // _activity.RunOnUiThread(() => //{ ExpandAnimation ani = new ExpandAnimation(dummyView, info.dummyHeight, 0, info, _activity, this); ani.Duration = this.parent.getAnimationDuration(); //ani.SetInterpolator(_activity, Android.Resource.Animation.AccelerateInterpolator); ani.Interpolator = new AccelerateDecelerateInterpolator(); ani.SetAnimationListener(new CustomAnimateListener(STATE_COLLAPSING, groupPosition, dummyView, info, listView, this, listView.OnAnimationEnd)); long i = ani.ComputeDurationHint(); dummyView.StartAnimation(ani); /**********************************Another animation implementation******************** * ValueAnimator animator = ValueAnimator.OfInt(totalHeight, 0); * animator.SetDuration(this.parent.getAnimationDuration()); * animator.SetInterpolator(new AccelerateDecelerateInterpolator()); * animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) => * { * var value = (int)animator.AnimatedValue; * if (factor != value) * { * factor = value; * ViewGroup.LayoutParams layoutParams = dummyView.LayoutParameters; * layoutParams.Height = value; * dummyView.LayoutParameters = layoutParams; * Console.System.Diagnostics.Debug.WriteLine("Value: " + value.ToString()); * } * }; * animator.AddListener(new CustomAnimateListener(STATE_COLLAPSING,groupPosition,dummyView,info,listView,this)); * animator.Start(); * ****************************************/ dummyView.Tag = STATE_COLLAPSING; // }); //})).Start(); } return(convertView); } else { info.ChildViewCallCount = 0; return(getRealChildView(groupPosition, childPosition, isLastChild, convertView, parent)); } } catch (System.Exception ex) { string s = ex.Message; CustomLogger.CustomLog("From Activity: " + BitopiSingelton.Instance.CurrentActivity + "\nMessage: " + ex.Message + "\nStack Trace: " + ex.StackTrace + "\n\n", "", BitopiSingelton.Instance.User != null ? BitopiSingelton.Instance.User.UserName : ""); return(null); } }
public void setParent(AnimatedExpandableListView parent) { this.parent = parent; }