列表选择器修改

This commit is contained in:
2025-10-30 23:54:43 +08:00
parent 7bcd6bf88d
commit 33b03719a1
3 changed files with 183 additions and 23 deletions

View File

@@ -21,10 +21,13 @@ namespace NBF
private int _columnsCount;
public ListSelector _selector;
private void OnInited()
{
Game.Input.OnUICanceled += OnUICanceled;
List.onClickItem.Add(OnClickListItem);
_selector = new ListSelector(List, typeof(ListTitleItem));
}
public override void Dispose()
@@ -37,49 +40,43 @@ namespace NBF
{
if (action == InputDef.UI.Right)
{
SetListSelected(List.selectedIndex + 1);
_selector.Right();
}
else if (action == InputDef.UI.Left)
{
SetListSelected(List.selectedIndex - 1);
_selector.Left();
}
else if (action == InputDef.UI.Up)
{
SetListSelected(List.selectedIndex - _columnsCount);
_selector.Up();
}
else if (action == InputDef.UI.Down)
{
if (List.selectedIndex < 0)
{
SetListSelected(0);
}
else
{
SetListSelected(List.selectedIndex + _columnsCount);
}
_selector.Down();
}
}
private void SetListSelected(int selectedIndex)
{
if (selectedIndex >= 0 && selectedIndex < _listData.Count)
{
var count = List.numChildren;
List.selectedIndex = selectedIndex;
List.ScrollToView(selectedIndex);
}
}
// private void SetListSelected(int selectedIndex)
// {
// if (selectedIndex >= 0 && selectedIndex < _listData.Count)
// {
// var count = List.numChildren;
// List.selectedIndex = selectedIndex;
// List.ScrollToView(selectedIndex);
// }
// }
public void SetListData(List<object> listData,
ListSelectionMode selectionMode = ListSelectionMode.Single)
{
List.selectedIndex = -1;
_listData.Clear();
foreach (var obj in listData)
{
_listData.Add(obj);
}
List.RemoveChildrenToPool();
List.defaultItem = ListTitleItem.URL;
List.itemProvider = GetListItemResource;
@@ -92,10 +89,11 @@ namespace NBF
}
catch (Exception e)
{
Log.Error(e);
Log.Error(e);
}
_columnsCount = 6;
_selector.Refresh();
}
void OnClickListItem(EventContext context)
@@ -136,6 +134,7 @@ namespace NBF
{
return BagItem.URL;
}
if (itemData is ClassifyListTitleData titleData)
{
return ListTitleItem.URL;

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
namespace NBF
{
public class ListSelector
{
private GList _list;
private readonly List<Type> _ignores = new List<Type>();
// private readonly List<GObject> _items = new List<GObject>();
private float itemWidth = 200f;
private float itemHeight = 180f;
public ListSelector(GList list, params Type[] ignores)
{
_list = list;
if (ignores != null && _ignores.Count > 0)
{
_ignores.AddRange(_ignores);
}
}
#region
public void Refresh()
{
var children = _list.GetChildren();
foreach (var item in children)
{
if (_ignores.Contains(item.GetType())) continue;
itemWidth = item.width;
itemHeight = item.height;
break;
}
}
#endregion
#region
public void Up()
{
Move(Vector2.up);
}
public void Down()
{
Move(Vector2.down);
}
public void Right()
{
Move(Vector2.right);
}
public void Left()
{
Move(Vector2.left);
}
public void Move(Vector2 direction)
{
if (_list.selectedIndex == -1)
{
// 首次选择第一个可选中项
SelectFirstSelectable();
return;
}
var currentPos = GetItemPosition(_list.selectedIndex);
var nearestIndex = FindNearestSelectableItem(currentPos, direction);
if (nearestIndex != -1)
{
SetSelection(nearestIndex);
}
}
#endregion
#region
private Vector2 GetItemPosition(int index)
{
var item = _list.GetChildAt(index);
return item.position;
}
private int FindNearestSelectableItem(Vector2 fromPos, Vector2 direction)
{
var bestIndex = -1;
var bestDistance = float.MaxValue;
for (var i = 0; i < _list.numItems; i++)
{
if (!IsSelectableItem(i)) continue;
var targetPos = GetItemPosition(i);
var diff = targetPos - fromPos;
// 检查方向匹配度
if (IsDirectionMatch(direction, diff))
{
var distance = Vector2.Distance(fromPos, targetPos);
if (distance < bestDistance && distance > 0.1f)
{
bestDistance = distance;
bestIndex = i;
}
}
}
return bestIndex;
}
private bool IsDirectionMatch(Vector2 direction, Vector2 diff)
{
if (direction == Vector2.up)
return diff.y < 0 && Mathf.Abs(diff.x) < itemWidth; // 修正向上应该是Y值更小
if (direction == Vector2.down)
return diff.y > 0 && Mathf.Abs(diff.x) < itemWidth; // 修正向下应该是Y值更大
if (direction == Vector2.left)
return diff.x < 0 && Mathf.Abs(diff.y) < itemHeight;
if (direction == Vector2.right)
return diff.x > 0 && Mathf.Abs(diff.y) < itemHeight;
return false;
}
private bool IsSelectableItem(int index)
{
var item = _list.GetChildAt(index);
return !_ignores.Contains(item.GetType());
}
private void SelectFirstSelectable()
{
for (var i = 0; i < _list.numItems; i++)
{
if (IsSelectableItem(i))
{
SetSelection(i);
break;
}
}
}
private void SetSelection(int index)
{
_list.selectedIndex = index;
// selection.position = items[index].position;
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 48f217b6f1dd4dc98d1b6e1c61f9ed65
timeCreated: 1761838465