使用PropertyDrawer来实现ReorderableList条目高度可变


TestAsset.cs

1 [CreateAssetMenu(menuName = "My/Test Asset")]
2 public class TestAsset : ScriptableObject
3 {
4     public List list;
5 }

TestAssetItem.cs

1 [Serializable]
2 public class TestAssetItem
3 {
4     public int i;
5     public float f;
6     public string name;
7 }

TestAssetEditor.cs

 1 [CustomEditor(typeof(TestAsset), true)]
 2 public class TestAssetEditor : Editor
 3 {
 4     private ReorderableList _listView;
 5 
 6     public override void OnInspectorGUI()
 7     {
 8         serializedObject.Update();
 9         //base.OnInspectorGUI();
10         EditorGUI.BeginChangeCheck();
11         if (null == _listView)
12             _listView = CreateListView(serializedObject, serializedObject.FindProperty("list"));
13     
14         _listView.DoLayoutList();
15 
16         if (EditorGUI.EndChangeCheck())
17         {
18             var b1 = serializedObject.ApplyModifiedProperties();
19             var b2 = serializedObject.UpdateIfRequiredOrScript();
20             Debug.Log($"change: modify: {b1}, update: {b2}");
21         }
22     }
23     
24     private ReorderableList CreateListView(SerializedObject seriObj, SerializedProperty prop)
25     {
26         var listView = new ReorderableList(seriObj, prop, true, false, true, true);
27     
28         listView.headerHeight = 0;
29         listView.elementHeightCallback = (index) =>
30         {
31             var element = listView.serializedProperty.GetArrayElementAtIndex(index);
32             var h = EditorGUIUtility.singleLineHeight;
33             if (element.isExpanded)
34                 h += EditorGUI.GetPropertyHeight(element);
35             return h;
36         };
37     
38         listView.onAddCallback = (list) =>
39         {
40             list.serializedProperty.arraySize++;
41             list.index = list.serializedProperty.arraySize - 1;
42         
43             var newElement = list.serializedProperty.GetArrayElementAtIndex(list.index);
44             newElement.FindPropertyRelative("i").intValue = 0;
45             newElement.FindPropertyRelative("f").floatValue = 0;
46             newElement.FindPropertyRelative("name").stringValue = "";
47         };
48     
49         listView.drawElementCallback = (rect, index, active, focused) =>
50         {
51             var element = listView.serializedProperty.GetArrayElementAtIndex(index);
52             var posRect_label = new Rect(rect)
53             {
54                 x = rect.x + 10, //左边距
55                 height = EditorGUIUtility.singleLineHeight
56             };
57             element.isExpanded = EditorGUI.Foldout(posRect_label, element.isExpanded, $"{index}", true);
58             if (element.isExpanded)
59             {
60                 var posRect_prop = new Rect(rect)
61                 {
62                     x = rect.x + 10,
63                     y = rect.y + EditorGUIUtility.singleLineHeight,
64                     height = rect.height - EditorGUIUtility.singleLineHeight
65                 };
66                 EditorGUI.PropertyField(posRect_prop, element, true);
67             }
68         };
69     
70         return listView;
71     }
72 }

如果不加TestAssetItem的Drawer,将显示成下面这样,不过高度也是可变了

TestAssetItemDrawer.cs

 1 [CustomPropertyDrawer(typeof(TestAssetItem), true)]
 2 public class TestAssetItemDrawer : PropertyDrawer
 3 {
 4     float _propH = EditorGUIUtility.singleLineHeight;
 5     public override void OnGUI(Rect posRect, SerializedProperty property, GUIContent label)
 6     {
 7         var Space_Height = 2;
 8         
 9         var rect = posRect;
10         rect.height = EditorGUIUtility.singleLineHeight;
11         rect.width = posRect.width - 10; //右边距
12         
13         rect.y += Space_Height; //第1行
14         var sp_i = property.FindPropertyRelative("i");
15         EditorGUI.PropertyField(rect, sp_i);
16         
17         rect.y += EditorGUIUtility.singleLineHeight + Space_Height; //第2行
18         var sp_f = property.FindPropertyRelative("f");
19         EditorGUI.PropertyField(rect, sp_f);
20         
21         rect.y += EditorGUIUtility.singleLineHeight + Space_Height; //第3行
22         var sp_name = property.FindPropertyRelative("name");
23         EditorGUI.PropertyField(rect, sp_name);
24         
25         _propH = rect.y - posRect.y + EditorGUIUtility.singleLineHeight; //3行+3行space
26     }
27 
28     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
29     {
30         //return base.GetPropertyHeight(property, label);
31         return _propH;
32     }
33 }