很多时候策划想要一个列表横向拖拽并且实现图标放大缩小的效果,根据这个效果写了以下代码:
代码:
初始化需要的操作:
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();
}