public void Init(int dayIndex, int width, int height, float cardPadding, UIEventListener.VoidDelegate onClickDelegate, int carouselLength = -1, bool clearOnRepopulate = true, bool verticalMode = false, bool allowRecommending = false) { _verticalMode = verticalMode; _allowRecommending = allowRecommending; _clearOnRepopulate = clearOnRepopulate; _onClickDelegate = onClickDelegate; if (!_isConfigured) { Configure(); } _carouselLength = carouselLength > 0 ? carouselLength : _carouselLength; _carouselLengthMax = _carouselLength; DayIndex = dayIndex; ScrollView.movement = _verticalMode ? UIScrollView.Movement.Vertical : UIScrollView.Movement.Horizontal; ScrollView.onDragStarted -= OnScrollViewDragStarted; ScrollView.onDragStarted += OnScrollViewDragStarted; ScrollView.onDragFinished -= OnScrollViewDragFinished; ScrollView.onDragFinished += OnScrollViewDragFinished; ScrollView.panel.SetRect(0, 0, width, height); ScrollView.panel.depth = 1; if (!_verticalMode) { // Fix issue where dragging isn't 1:1 ScrollView.dragEffect = UIScrollView.DragEffect.None; } else { // Don't center for vertical lists CenterOnChild.enabled = false; } ScrollView.panel.clipping = _verticalMode ? UIDrawCall.Clipping.SoftClip : UIDrawCall.Clipping.None; _cardPadding = cardPadding; _onCardClickedDelegate = onClickDelegate; if (null == _carouselCards) { _carouselCards = new List <IActivityViewModelBase>(); } if (_carouselCards.Count == 0) { //CreateCards(_carouselLengthMax); if (!_verticalMode) { CenterOnChild.Recenter(); CenterOnChild.enabled = false; //We handle centering so don't do it yourself, CenterOnChild. } else { CreateCards(_carouselLengthMax); ScrollView.ResetPosition(); } } }
/** * @des:更新Content SizeDelta */ private void setUpdateContentSize() { //多加1行,是为了防止最后一列展示不出来 int lineCount = Mathf.CeilToInt((float)dataCount / maxPerLine); switch (arrangement) { case Arrangement.Horizontal: content.sizeDelta = new Vector2(cellWidth * lineCount + cellWidthSpace * (lineCount - 1), content.sizeDelta.y); break; case Arrangement.Vertical: content.sizeDelta = new Vector2(content.sizeDelta.x, cellHeight * lineCount + cellHeightSpace * (lineCount - 1)); break; } CenterOnChild centerOnChild = scrollRect.GetComponent <CenterOnChild>(); if (null != centerOnChild) { if (arrangement == Arrangement.Horizontal) { centerOnChild.Init(content.sizeDelta.x); } else { centerOnChild.Init(content.sizeDelta.y); } } }
public void OnScrollViewDragStarted() { dragStartPosition = ScrollView.transform.position; dragStartTime = Time.time; if (_verticalMode) { _prevCenterTarget = CenterOnChild.DetermineCenterTarget(); CenterCardIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == _prevCenterTarget); } }
public void OnScrollViewDragFinished() { dragEndPosition = ScrollView.transform.position; Transform newCenterTarget = null; if (!_verticalMode) { Vector2 drag = dragEndPosition - dragStartPosition; dragStartPosition = dragEndPosition = Vector3.zero; float sqrDragDistance = Vector3.SqrMagnitude(drag); if (sqrDragDistance > dragDistanceThreshold * dragDistanceThreshold || sqrDragDistance / ((Time.time - dragStartTime) / 1.5) > dragDistanceThreshold * dragDistanceThreshold) { // We dragged far enough: try centering on the next card in this direction. if (null == CenterOnChild.centeredObject) { newCenterTarget = CenterOnChild.DetermineCenterTarget(); } else { float dot = Vector3.Dot(drag, Vector3.right); int newIndex = (int)(CenterCardIndex - Mathf.Sign(dot)); if (newIndex >= 0 && newIndex < _carouselCards.Count) { newCenterTarget = (_carouselCards[newIndex] as MonoBehaviour).transform; } else { newCenterTarget = CenterOnChild.centeredObject.transform; } } } } if (null == newCenterTarget) { // Try recentering on centered object, if it exists if (_verticalMode) { newCenterTarget = CenterOnChild.DetermineCenterTarget(); } else { if (null != CenterOnChild.centeredObject) { CenterOnChild.Recenter(); } else { Debug.LogError("CardCarousel: centered on null"); } return; } } DateListItem dli = newCenterTarget.GetComponent <DateListItem>(); Transform nearestToDateLabel = null; int newTargetIndex = -1; if (null != dli) { // Make sure we still recycle the cards if we center on a date label // Find the nearest card in the direction we came from Vector3 deltaScroll = dli.transform.localPosition - _prevCenterTarget.transform.localPosition; RaycastHit[] hits = Physics.RaycastAll(dli.transform.position, -deltaScroll); if (null != hits && hits.Length > 0) { // Pull out only cards, so no date labels List <RaycastHit> hitList = hits.ToList().FindAll(x => null == x.collider.gameObject.GetComponent <DateListItem>()); // Sort by closest hitList.Sort((a, b) => a.distance.CompareTo(b.distance)); // Grab the first (closest) Transform closest = hitList[0].collider.transform; if (null == closest) { return; } Debug.LogWarning("Found " + closest.name); newTargetIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == closest); } } else if (!_verticalMode) { CenterOnChild.CenterOn(newCenterTarget); } if (newTargetIndex < 0) { newTargetIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == newCenterTarget); } if (0 > newTargetIndex) { return; } if (_verticalMode) { _prevCenterTarget = newCenterTarget; } int halfCarouselLength = _carouselLength / 2; int numCardsToMove = newTargetIndex - halfCarouselLength; CenterCardIndex = newTargetIndex; if (0 == numCardsToMove) { return; } // Slide the visible indices over an equal amount. // Clamp the number of cards moved if it would push us out of bounds. int oldMin = VisibleCardIndexMin; VisibleCardIndexMin = Mathf.Clamp(VisibleCardIndexMin + numCardsToMove, 0, _cardCache.Count - _carouselLength); int diff = VisibleCardIndexMin - oldMin; numCardsToMove = diff; VisibleCardIndexMax = Mathf.Clamp(VisibleCardIndexMax + numCardsToMove, _carouselLength - 1, _cardCache.Count - 1); int positiveEdge = numCardsToMove < 0 ? 0 : _carouselCards.Count; int negativeEdge = numCardsToMove < 0 ? _carouselCards.Count : 0; int negativeIndex = negativeEdge - (negativeEdge == _carouselLength ? 1 : 0); int positiveIndex = positiveEdge - (positiveEdge == _carouselLength ? 1 : 0); for (int i = 0; i < Mathf.Abs(numCardsToMove); i++) { IActivityViewModelBase movedCard = _carouselCards[negativeIndex]; IActivityViewModelBase edgeCard = _carouselCards[positiveIndex]; DateTime lastDate = DateTime.MinValue; if (_verticalMode) { lastDate = (edgeCard as ActivityTableCellViewModel).data.dateTime.Date; } int indexToPopulate = (numCardsToMove > 0 ? VisibleCardIndexMax - (numCardsToMove - 1 - i) : VisibleCardIndexMin + (Mathf.Abs(numCardsToMove) - 1 - i)); movedCard.Clear(); movedCard.Populate(_cardCache[indexToPopulate], _onCardClickedDelegate, _allowRecommending); DateTime newDate = _cardCache[indexToPopulate].dateTime.Date; Vector3 newPosition = (edgeCard as MonoBehaviour).transform.localPosition; if (_verticalMode) { float singleCardOffset = ((edgeCard as MonoBehaviour).GetComponent <Collider>() as BoxCollider).size.y + _cardPadding; newPosition.y -= (numCardsToMove > 0 ? 1 : -1) * singleCardOffset; if (lastDate != newDate) { // If we're moving positive, it's the newDate. Else it's lastDate. DateTime dateToShow = (numCardsToMove > 0 ? newDate : lastDate); Vector3 dateListItemPosition = newPosition; newPosition.y -= (numCardsToMove > 0 ? 1 : -1) * singleCardOffset; // Check if there's already a date label for this date. DateListItem[] dateLabels = ScrollView.transform.GetComponentsInChildren <DateListItem>(); var dateLabel = dateLabels.ToList().Find(x => x.dateTime.Date == dateToShow); if (dateLabel == null) { // Now at the singleCardOffset position, spawn a date label. GameObject dateListItemPrefab = (GameObject)Resources.Load(_cardPrefabPath + "DateListItem"); GameObject dateListItem = NGUITools.AddChild(ScrollView.gameObject, dateListItemPrefab); DateListItem dliScript = dateListItem.GetComponent <DateListItem>(); UIDragScrollView dateDragScrollView = dateListItem.AddComponent <UIDragScrollView>(); dateDragScrollView.scrollView = ScrollView; // Still respect relative dates DateTime now = DateTime.Now; DateTime yesterday = DateTime.Now.AddDays(-1); DateTime tomorrow = DateTime.Now.AddDays(1); if (dateToShow.Date == now.Date) { dliScript.dayLabel.text = "TODAY"; } else if (dateToShow.Date == yesterday.Date) { dliScript.dayLabel.text = "YESTERDAY"; } else if (dateToShow.Date == tomorrow.Date) { dliScript.dayLabel.text = "TOMORROW"; } else { dliScript.dayLabel.text = dateToShow.DayOfWeek.ToString().ToUpper(); } dliScript.dateLabel.text = dateToShow.ToString("M"); dliScript.dateTime = dateToShow.Date; dateListItem.gameObject.transform.localPosition = dateListItemPosition; } } } else { newPosition.x += (numCardsToMove > 0 ? 1 : -1) * (((edgeCard as MonoBehaviour).GetComponent <Collider>() as BoxCollider).size.x + _cardPadding); } (movedCard as MonoBehaviour).transform.localPosition = newPosition; _carouselCards.Insert(positiveEdge, movedCard); _carouselCards.RemoveAt(negativeEdge); } if (null != dli) { return; } CenterCardIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == newCenterTarget); }