代码
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace GameContent
{
public class TestReorderlist : EditorWindow
{
[MenuItem("GM/TestReorderlist")]
public static void ShowWindow()
{
GetWindow<TestReorderlist>("TestReorderlist");
}
//所有数据列表
private List<TestElementData> mTotalDataList = new List<TestElementData>() { };
//显示n个数据
private TestElementData[] mPartDataArray = new TestElementData[5];
//显示的列表组件
private ReorderableList mReorderableList;
private void OnEnable()
{
InitTestData();
mReorderableList = new ReorderableList(mPartDataArray , typeof(TestElementData));
mReorderableList.drawHeaderCallback = ReorderableList_DrawHeaderCallback;
mReorderableList.drawElementCallback = ReorderableList_DrawElementCallback;
mReorderableList.onAddCallback = ReorderableList_OnAddCallback;
mReorderableList.onRemoveCallback = ReorderableList_OnRemoveCallback;
mReorderableList.onReorderCallbackWithDetails = ReorderableList_OnReorderCallbackWithDetails;
}
private void ReorderableList_DrawHeaderCallback(Rect rect)
{
GUI.Label(rect , "Header");
}
private void ReorderableList_DrawElementCallback(Rect rect , int index , bool isActive , bool isFocused)
{
int dataIndex = (int)mSliderValue + index;
if(dataIndex >= mTotalDataList.Count || dataIndex < 0)
{
GUI.Label(rect , $"index={index} ; mSliderValue={mSliderValue} ; dataIndex={dataIndex} ; 索引超出范围");
}
else
{
TestElementData elementData = mTotalDataList[dataIndex];
GUI.Label(rect , $"index={index} ; mSliderValue={mSliderValue} ; dataIndex={dataIndex} ; name={elementData.Name}");
}
}
private void ReorderableList_OnAddCallback(ReorderableList list)
{
int dataIndex = (int)mSliderValue + mReorderableList.index;
if(dataIndex + 1 >= mTotalDataList.Count)
{
mTotalDataList.Add(new TestElementData()
{
Name = "AddName" + dataIndex ,
Value = "AddValue" + dataIndex
});
}
else
{
mTotalDataList.Insert(dataIndex + 1 , new TestElementData()
{
Name = "InsertName" + dataIndex ,
Value = "InsertValue" + dataIndex
});
}
}
private void ReorderableList_OnRemoveCallback(ReorderableList list)
{
int dataIndex = (int)mSliderValue + mReorderableList.index;
if(dataIndex >= 0 && dataIndex < mTotalDataList.Count)
{
mTotalDataList.RemoveAt(dataIndex);
}
}
private void ReorderableList_OnReorderCallbackWithDetails(ReorderableList list , int oldIndex , int newIndex)
{
int oldDataIndex = (int)mSliderValue + oldIndex;
int newDataIndex = (int)mSliderValue + newIndex;
if(oldDataIndex >= 0 && oldDataIndex < mTotalDataList.Count && newDataIndex >= 0 && newDataIndex < mTotalDataList.Count)
{
var tempData = mTotalDataList[oldDataIndex];
mTotalDataList[oldDataIndex] = mTotalDataList[newDataIndex];
mTotalDataList[newDataIndex] = tempData;
}
}
private float mSliderValue = 0;
private void OnGUI()
{
mReorderableList.list = mPartDataArray;
//绘制可拖拽列表
float reorderableListPosX = 0;
float reorderableListPosY = 0;
float reorderableListWidth = position.width - 20;
Rect reorderableListRect = new Rect(reorderableListPosX , reorderableListPosY , reorderableListWidth , 0);
mReorderableList.DoList(reorderableListRect);
//绘制列表的滚动条。使用mPartDataArray.Length作为滑块的大小,可以保障滑块到底部时的索引与数据索引一致。
Rect reorderableSliderRect = new Rect(reorderableListWidth , reorderableListPosY , 0 , mReorderableList.GetHeight());
int sliderMaxValue = mTotalDataList.Count > mPartDataArray.Length ? mTotalDataList.Count : mPartDataArray.Length;
mSliderValue = GUI.VerticalScrollbar(reorderableSliderRect , mSliderValue , mPartDataArray.Length , 0f , sliderMaxValue);
}
private void InitTestData()
{
mTotalDataList.Clear();
for(int i = 0 ; i < 50 ; i++)
{
mTotalDataList.Add(new TestElementData()
{
Name = "Name" + i ,
Value = "Value" + i
});
}
}
}
public class TestElementData
{
public string Name;
public string Value;
}
}
视频演示效果
此处为语雀卡片,点击链接查看
参考