很多时候策划想要一个列表横向拖拽并且实现图标放大缩小的效果,根据这个效果写了以下代码:


组件情况
ScrollView配置
代码:
初始化需要的操作:

    private RectTransform _svRect = Sv_Games.GetComponent<RectTransform>();

        Sv_Games.OnDragCallback = FnOnStartDragCallback;
        Sv_Games.OnEndDragCallback = FnOnEndDragCallback;

其它相关代码:

    /// <summary>
    /// 初始化游戏入口位置大小
    /// </summary>
    private void FnInitGameEntry()
    {
        //初始化要在哪个位置
        _curSelectIndex = 0;
        //更新
        for (int i = 0, count = _gameEntryList.Count; i < count; i++)
        {
            var gameEntry = _gameEntryList[i];
            gameEntry.Rect.localPosition = new Vector3(i * _dis, 0, 0);
            if (i == _curSelectIndex)
            {
                gameEntry.Rect.localScale = Vector3.one;
            }
            else
            {
                gameEntry.Rect.localScale = new Vector3(0.8f, 0.8f, 0.8f);
            }
        }
        //更新位置
        Rt_Games.SetAnchorPosX(-(_curSelectIndex * _dis));
    }

    /// <summary>
    /// 更新Cell缩放
    /// </summary>
    private void FnUpdateCellScale()
    {
        for (int i = 0; i < _gameEntryList.Count; i++)
        {
            var gameEntry = _gameEntryList[i];
            if (i == _curSelectIndex)
            {
                gameEntry.Rect.DOScale(Vector3.one, 0.2f);
            }
            else
            {
                gameEntry.Rect.DOScale(new Vector3(0.8f, 0.8f, 0.8f), 0.2f);
            }
        }
    }

    /// <summary>
    /// 开始拖拽
    /// </summary>
    /// <param name="e"></param>
    private void FnOnStartDragCallback(PointerEventData e)
    {
        //移动部分
        float x = e.delta.x;

        int posX = (int)Mathf.Clamp(_svRect.anchoredPosition.x + x, -1050, 0);
        _svRect.anchoredPosition = new Vector2(posX, _svRect.anchoredPosition.y);

        //更新选中 (( 坐标 - ( 一半的间距 )) / 间距 ) - 1
        int index = -(int)Math.Floor((_svRect.anchoredPosition.x - (_dis / 2)) / _dis) - 1;
        int maxIndex = _gameEntryList.Count - 1;
        if (index < 0)
        {
            index = 0;
        }
        else if (index > maxIndex)
        {
            index = maxIndex;
        }

        _curSelectIndex = index;

        //更新Scale
        FnUpdateCellScale();
    }

    /// <summary>
    /// 结束拖拽
    /// </summary>
    /// <param name="obj"></param>
    private void FnOnEndDragCallback(PointerEventData e)
    {
        FnGameSelect(_curSelectIndex);
    }

    /// <summary>
    /// 移动到选择的位置 进行操作
    /// </summary>
    /// <param name="selectIndex"></param>
    private void FnGameSelect(int selectIndex)
    {
        _curSelectIndex = selectIndex;

        _gameEntryList.ForEach(gameEntry =>
        {
            if (selectIndex == gameEntry.Index)
            {
                gameEntry.Rect.localScale = Vector3.one;
                gameEntry.Btn.interactable = false;
            }
            else
            {
                gameEntry.Rect.localScale = Vector3.one * 0.8f;
                gameEntry.Btn.interactable = true;
            }
        });

        //移动到选中的位置
        Sv_Games.enabled = false;
        float x = -(selectIndex * _dis);
        _svRect.DOKill();
        _svRect.DOAnchorPosX(x, 0.2f).onComplete = () => {
            Sv_Games.enabled = true;
        };

        //刷新界面

    }


直接两个对象
拖拽对象所需接口:IBeginDragHandler IDragHandler IEndDragHandler
展示对象:Rt_Car

/// <summary>
/// 更新Cell缩放
/// </summary>
private void FnUpdateCellScale()
{
    for (int i = 0; i < mCarChangeCellPool.AllocatedLst.Count; i++)
    {
        var cell = mCarChangeCellPool.AllocatedLst[i];
        if (i == mCurrCarIndex)
        {
            cell.rectTransform.DOScale(Vector3.one, 0.2f);
        }
        else
        {
            cell.rectTransform.DOScale(new Vector3(0.8f, 0.8f, 0.8f), 0.2f);
        }
    }
}

/// <summary>
/// 移动到选中的位置
/// </summary>
private void FnSwitchCurrCell()
{
    float x = -(mCurrCarIndex * mDis);
    Rt_Car.DOAnchorPosX(x, 0.2f);
}

private void FnOnDragCallback(PointerEventData e)
{
    //移动部分
    float x = e.delta.x;
    Rt_Car.localPosition = new Vector3(Rt_Car.localPosition.x + x, Rt_Car.localPosition.y, Rt_Car.localPosition.z);

    //更新选中 (( 坐标 - ( 一半的间距 )) / 间距 ) - 1
    int index = -(int)Math.Floor((Rt_Car.localPosition.x - (mDis / 2)) / mDis) - 1;
    int maxIndex = mCarChangeCellPool.AllocatedLst.Count - 1;
    if (index < 0)
    {
        index = 0;
    }
    else if (index > maxIndex)
    {
        index = maxIndex;
    }
    mCurrCarIndex = index;

    //更新Scale
    FnUpdateCellScale();
}

private void FnOnOnEndDragCallback(PointerEventData obj)
{
    FnSwitchCurrCell();
}

最后修改:2024 年 05 月 16 日
如果觉得我的文章对你有用,请随意赞赏