代码
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; }}
视频演示效果
此处为语雀卡片,点击链接查看
参考