UIToolkit 기본 UI 개발 중
This commit is contained in:
225
Assets/Scripts/NHN/CLAUDE.md
Normal file
225
Assets/Scripts/NHN/CLAUDE.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# NHN 모듈 가이드
|
||||
|
||||
NHN은 uGUI 기반 **무한 스크롤(InfiniteScroll)** 컴포넌트 라이브러리입니다. 대량 데이터 목록을 효율적으로 렌더링하기 위해 아이템을 재활용(recycling)합니다.
|
||||
|
||||
> **참고**: 새 UI는 UI Toolkit의 `ListView`/`TreeView` 가상화 기능을 권장합니다. 이 모듈은 uGUI 기반 레거시 프로젝트용입니다.
|
||||
|
||||
---
|
||||
|
||||
## 파일 구조
|
||||
|
||||
```
|
||||
NHN/
|
||||
├── InfiniteScroll.cs # 메인 클래스 (partial)
|
||||
├── InfiniteScroll.ItemContainer.cs # 아이템 컨테이너 관리
|
||||
├── InfiniteScroll.ItemData.cs # 데이터 컨텍스트
|
||||
├── InfiniteScroll.Layout.cs # 레이아웃 계산
|
||||
├── InfiniteScroll.Scroll.cs # 스크롤 처리
|
||||
├── InfiniteScrollItem.cs # 아이템 베이스 클래스
|
||||
├── InfiniteScrollData.cs # 데이터 베이스 클래스
|
||||
├── ScrollLayout.cs # 레이아웃 설정
|
||||
├── ScrollMoveTo.cs # 스크롤 이동 유틸리티
|
||||
├── LayoutUpdater.cs # 레이아웃 업데이트
|
||||
├── DraggableRect.cs # 드래그 가능한 영역
|
||||
├── DragEventHandler.cs # 드래그 이벤트 처리
|
||||
└── ContentSizeSetter.cs # 콘텐츠 크기 설정
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 핵심 클래스
|
||||
|
||||
### InfiniteScroll
|
||||
|
||||
uGUI `ScrollRect` 기반의 무한 스크롤 컴포넌트입니다.
|
||||
|
||||
```csharp
|
||||
namespace Gpm.Ui
|
||||
{
|
||||
public partial class InfiniteScroll : MonoBehaviour
|
||||
{
|
||||
// 이벤트
|
||||
public ChangeValueEvent onChangeValue; // 스크롤 값 변경
|
||||
public ItemActiveEvent onChangeActiveItem; // 아이템 활성화 변경
|
||||
public StateChangeEvent onStartLine; // 시작점 도달
|
||||
public StateChangeEvent onEndLine; // 끝점 도달
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 기본 사용법
|
||||
|
||||
### 1. 데이터 삽입
|
||||
|
||||
```csharp
|
||||
// 단일 데이터 삽입
|
||||
InfiniteScrollData myData = new MyScrollData();
|
||||
infiniteScroll.InsertData(myData, immediately: true);
|
||||
|
||||
// 다중 데이터 삽입
|
||||
InfiniteScrollData[] dataArray = new InfiniteScrollData[100];
|
||||
infiniteScroll.InsertData(dataArray, immediately: true);
|
||||
|
||||
// 특정 인덱스에 삽입
|
||||
infiniteScroll.InsertData(myData, insertIndex: 0, immediately: true);
|
||||
```
|
||||
|
||||
### 2. 데이터 제거
|
||||
|
||||
```csharp
|
||||
// 데이터 객체로 제거
|
||||
infiniteScroll.RemoveData(dataToRemove, immediately: true);
|
||||
|
||||
// 인덱스로 제거
|
||||
infiniteScroll.RemoveData(dataIndex: 0, immediately: true);
|
||||
```
|
||||
|
||||
### 3. 데이터 초기화
|
||||
|
||||
```csharp
|
||||
// 데이터만 초기화 (아이템 객체 유지)
|
||||
infiniteScroll.ClearData(immediately: true);
|
||||
|
||||
// 완전 초기화 (아이템 객체도 제거)
|
||||
infiniteScroll.Clear();
|
||||
```
|
||||
|
||||
### 4. 데이터 업데이트
|
||||
|
||||
```csharp
|
||||
// 단일 데이터 업데이트
|
||||
InfiniteScrollData existingData = infiniteScroll.GetData(0);
|
||||
// ... 데이터 수정 ...
|
||||
infiniteScroll.UpdateData(existingData);
|
||||
|
||||
// 전체 새로고침
|
||||
infiniteScroll.UpdateAllData(immediately: true);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 이벤트 처리
|
||||
|
||||
```csharp
|
||||
// 스크롤 값 변경 (첫 번째/마지막 보이는 인덱스)
|
||||
infiniteScroll.onChangeValue.AddListener((first, last, isStart, isEnd) => {
|
||||
Debug.Log($"Visible: {first}~{last}, Start: {isStart}, End: {isEnd}");
|
||||
});
|
||||
|
||||
// 아이템 활성화 상태 변경
|
||||
infiniteScroll.onChangeActiveItem.AddListener((dataIndex, isActive) => {
|
||||
Debug.Log($"Item {dataIndex} is {(isActive ? "active" : "inactive")}");
|
||||
});
|
||||
|
||||
// 시작/끝 도달
|
||||
infiniteScroll.onStartLine.AddListener((isAtStart) => {
|
||||
if (isAtStart) LoadPreviousPage();
|
||||
});
|
||||
|
||||
infiniteScroll.onEndLine.AddListener((isAtEnd) => {
|
||||
if (isAtEnd) LoadNextPage();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 필터링
|
||||
|
||||
```csharp
|
||||
// 필터 설정
|
||||
infiniteScroll.SetFilter(data => {
|
||||
MyCustomData myData = data as MyCustomData;
|
||||
return myData.score > 50; // 점수 50 이상만 표시
|
||||
});
|
||||
|
||||
// 필터 적용 후 업데이트
|
||||
infiniteScroll.UpdateAllData(immediately: true);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 스크롤 제어
|
||||
|
||||
```csharp
|
||||
// 특정 아이템 위치로 이동
|
||||
float position = infiniteScroll.GetItemPosition(itemIndex: 10);
|
||||
|
||||
// 뷰포트/콘텐츠 크기
|
||||
float viewportSize = infiniteScroll.GetViewportSize();
|
||||
float contentSize = infiniteScroll.GetContentSize();
|
||||
float contentPos = infiniteScroll.GetContentPosition();
|
||||
|
||||
// 수동 새로고침
|
||||
infiniteScroll.RefreshScroll();
|
||||
infiniteScroll.ResizeScrollView();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 커스텀 데이터/아이템 구현
|
||||
|
||||
### 데이터 클래스
|
||||
|
||||
```csharp
|
||||
public class MyScrollData : InfiniteScrollData
|
||||
{
|
||||
public string title;
|
||||
public int score;
|
||||
public Sprite icon;
|
||||
}
|
||||
```
|
||||
|
||||
### 아이템 클래스
|
||||
|
||||
```csharp
|
||||
public class MyScrollItem : InfiniteScrollItem
|
||||
{
|
||||
[SerializeField] private Text titleText;
|
||||
[SerializeField] private Image iconImage;
|
||||
|
||||
public override void UpdateData(InfiniteScrollData scrollData)
|
||||
{
|
||||
base.UpdateData(scrollData);
|
||||
|
||||
if (scrollData is MyScrollData myData)
|
||||
{
|
||||
titleText.text = myData.title;
|
||||
iconImage.sprite = myData.icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 성능 최적화
|
||||
|
||||
| 항목 | 설명 |
|
||||
|------|------|
|
||||
| **아이템 재활용** | 화면에 보이는 아이템만 생성, 나머지는 풀에서 재활용 |
|
||||
| **즉시 업데이트** | `immediately: true`로 즉시 레이아웃 갱신 |
|
||||
| **필터링** | 서버 필터링 권장, 클라이언트 필터는 대량 데이터 시 주의 |
|
||||
| **아이템 프리팹** | 가볍게 유지, 복잡한 UI는 지연 로딩 고려 |
|
||||
|
||||
---
|
||||
|
||||
## UI Toolkit 마이그레이션
|
||||
|
||||
새 프로젝트에서는 UI Toolkit의 `ListView` 사용을 권장합니다:
|
||||
|
||||
```csharp
|
||||
// UI Toolkit ListView (권장)
|
||||
var listView = new ListView();
|
||||
listView.makeItem = () => new Label();
|
||||
listView.bindItem = (element, index) => {
|
||||
(element as Label).text = items[index].title;
|
||||
};
|
||||
listView.itemsSource = items;
|
||||
```
|
||||
|
||||
InfiniteScroll → ListView 마이그레이션 시:
|
||||
- `InfiniteScrollData` → 일반 데이터 클래스
|
||||
- `InfiniteScrollItem` → `makeItem`/`bindItem` 콜백
|
||||
- 이벤트 → ListView 이벤트 (`selectionChanged` 등)
|
||||
7
Assets/Scripts/NHN/CLAUDE.md.meta
Normal file
7
Assets/Scripts/NHN/CLAUDE.md.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50d860adeb4661b43bb0cf83be4c7f10
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user