어떻게 CocosCreator 에서 List 를 만 듭 니까?
cocos 는 List 구성 요소 가 없 기 때문에 스스로 써 야 합 니 다.cocos 의 example 프로젝트 에서 assets/case/02 찾기ui/05_listView 의 demo 를 개조 합 니 다.
가상 목록 을 작성 합 니 다.수직 레이아웃,수평 레이아웃,격자 레이아웃 과 Padding 의 List 가 있 습 니 다.
데모 주소:https://files-cdn.cnblogs.com/files/gamedaybyday/cocos2.3.4_ListViewDemo_Grid.7z
cocos 의 원래 레이 아웃 은 목록 을 만 들 고 100 개의 데이터 가 있 으 면 100 개의 인 스 턴 스(왼쪽 그림)가 있 습 니 다.
가상 목록 은 보 이 는 인 스 턴 스 만 존재 합 니 다.미 끄 러 질 때 반복 적 으로 사용 합 니 다.(오른쪽 그림
List 사용법
사용 방법 은 ScrollView 에 List 구성 요 소 를 추가 하면 됩 니 다.
List 의 item 목록 항목 을 content 아래 에 직접 놓 고 oList 구성 요 소 를 할당 합 니 다.item 은 item Render 에서 계승 할 대상 을 추가 하여 데이터 새로 고침 에 사용 해 야 합 니 다.
코드 에서 List 에 데 이 터 를 설정 합 니 다.
//
let rankData = [];
for(let i=0;i<100;i++){
rankData.push({rank:i, name:" "});
}
this.rankList.setData(rankData);
소스 코드
// Learn TypeScript:
// - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
import ItemRender from "./ItemRender"
const { ccclass, property } = cc._decorator;
/** */
export enum ListType {
/** */
Horizontal = 1,
/** */
Vertical = 2,
/** */
Grid = 3
}
/** */
export enum StartAxisType {
/** */
Horizontal = 1,
/** */
Vertical = 2,
}
/**
*
* cocos_example listView
* @author chenkai 2020.7.8
* @example
* 1. cocos ScrollView , List, List
*
*/
@ccclass
export default class List extends cc.Component {
//==================== =========================
/** */
@property({ type: cc.Node, tooltip: " " })
public itemRender: cc.Node = null;
/** */
@property({ type: cc.Enum(ListType), tooltip: " " })
public type: ListType = ListType.Vertical;
/** */
@property({ type: cc.Enum(StartAxisType), tooltip: " ", visible() { return this.type == ListType.Grid } })
public startAxis: StartAxisType = StartAxisType.Horizontal;
/** X */
@property({ type: cc.Integer, tooltip: " X ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
public spaceX: number = 0;
/** Y */
@property({ type: cc.Integer, tooltip: " Y ", visible() { return this.type == ListType.Vertical || this.type == ListType.Grid } })
public spaceY: number = 0;
/** */
@property({ type: cc.Integer, tooltip: " ", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
public padding_top: number = 0;
/** */
@property({ type: cc.Integer, tooltip: " ", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
public padding_buttom: number = 0;
/** */
@property({ type: cc.Integer, tooltip: " ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
public padding_left: number = 0;
@property(cc.Integer)
public _padding: number = 0;
/** */
@property({ type: cc.Integer, tooltip: " ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
public padding_right: number = 0;
//====================== ===============================
/** */
public scrollView: cc.ScrollView = null;
/**scrollView */
private content: cc.Node = null;
//======================== ===========================
/** */
private itemDataList: Array<any> = [];
/** */
private spawnCount: number = 0;
/** */
private itemList: Array<cc.Node> = [];
/**item */
private itemHeight: number = 0;
/**item */
private itemWidth: number = 0;
/** */
private itemPool: Array<cc.Node> = [];
//======================= ==========================
/** scrollView , item , scrollVIew.height/2 + item.heigt/2 + space, item scrollView */
private halfScrollView: number = 0;
/** content X , content X , */
private lastContentPosX: number = 0;
/** content Y , content Y , */
private lastContentPosY: number = 0;
/** */
private gridRow: number = 0;
/** */
private gridCol: number = 0;
/** , s */
private updateTimer: number = 0;
/** , s */
private updateInterval: number = 0.1;
/** */
private bScrolling: boolean = false;
/** */
private updateFun: Function = function () { };
onLoad() {
this.itemHeight = this.itemRender.height;
this.itemWidth = this.itemRender.width;
this.scrollView = this.node.getComponent(cc.ScrollView);
this.content = this.scrollView.content;
this.content.anchorX = 0;
this.content.anchorY = 1;
this.content.removeAllChildren();
this.scrollView.node.on("scrolling", this.onScrolling, this);
}
/**
* ( , , )
* @param itemDataList item
*/
public setData(itemDataList: Array<any>) {
this.itemDataList = itemDataList.slice();
this.updateContent();
}
/** */
private countListParam() {
let dataLen = this.itemDataList.length;
if (this.type == ListType.Vertical) {
this.scrollView.horizontal = false;
this.scrollView.vertical = true;
this.content.width = this.content.parent.width;
this.content.height = dataLen * this.itemHeight + (dataLen - 1) * this.spaceY + this.padding_top + this.padding_buttom;
this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) + 2; // item , scrollView item 2
this.halfScrollView = this.scrollView.node.height / 2 + this.itemHeight / 2 + this.spaceY; // bufferZone,item
this.updateFun = this.updateV;
} else if (this.type == ListType.Horizontal) {
this.scrollView.horizontal = true;
this.scrollView.vertical = false;
this.content.width = dataLen * this.itemWidth + (dataLen - 1) * this.spaceX + this.padding_left + this.padding_right;
this.content.height = this.content.parent.height;
this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth + this.spaceX)) + 2;
this.halfScrollView = this.scrollView.node.width / 2 + this.itemWidth / 2 + this.spaceX;
this.updateFun = this.udpateH;
} else if (this.type == ListType.Grid) {
if (this.startAxis == StartAxisType.Vertical) {
this.scrollView.horizontal = false;
this.scrollView.vertical = true;
this.content.width = this.content.parent.width;
// left right , item, left right 0,
if (this.padding_left + this.padding_right + this.itemWidth + this.spaceX > this.content.width) {
this.padding_left = 0;
this.padding_right = 0;
console.error("padding_left padding_right ");
}
this.gridCol = Math.floor((this.content.width - this.padding_left - this.padding_right) / (this.itemWidth + this.spaceX));
this.gridRow = Math.ceil(dataLen / this.gridCol);
this.content.height = this.gridRow * this.itemHeight + (this.gridRow - 1) * this.spaceY + this.padding_top + this.padding_buttom;
this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) * this.gridCol + this.gridCol * 2;
this.halfScrollView = this.scrollView.node.height / 2 + this.itemHeight / 2 + this.spaceY;
this.updateFun = this.updateGrid_V;
} else if (this.startAxis == StartAxisType.Horizontal) {
this.scrollView.horizontal = true;
this.scrollView.vertical = false;
//
this.content.height = this.content.parent.height;
// left right , item, left right 0,
if (this.padding_top + this.padding_buttom + this.itemHeight + this.spaceY > this.content.height) {
this.padding_top = 0;
this.padding_buttom = 0;
console.error("padding_top padding_buttom ");
}
this.gridRow = Math.floor((this.content.height - this.padding_top - this.padding_buttom) / (this.itemHeight + this.spaceY));
this.gridCol = Math.ceil(dataLen / this.gridRow);
this.content.width = this.gridCol * this.itemWidth + (this.gridCol - 1) * this.spaceX + this.padding_left + this.padding_right;
this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth + this.spaceX)) * this.gridRow + this.gridRow * 2;
this.halfScrollView = this.scrollView.node.width / 2 + this.itemWidth / 2 + this.spaceX;
this.updateFun = this.updateGrid_H;
}
}
}
/**
*
* @param startIndex 0
* @param offset scrollView
*/
private createList(startIndex: number, offset: cc.Vec2) {
// > , , scrollView
if (this.itemDataList.length > this.spawnCount && (startIndex + this.spawnCount - 1) >= this.itemDataList.length) {
startIndex = this.itemDataList.length - this.spawnCount;
offset = this.scrollView.getMaxScrollOffset();
// <= ,
} else if (this.itemDataList.length <= this.spawnCount) {
startIndex = 0;
}
for (let i = 0; i < this.spawnCount; i++) {
let item: cc.Node;
// , item
if (i + startIndex < this.itemDataList.length) {
if (this.itemList[i] == null) {
item = this.getItem();
this.itemList.push(item);
item.parent = this.content;
} else {
item = this.itemList[i];
}
// , item
} else {
//item >
if (this.itemList.length > (this.itemDataList.length - startIndex)) {
item = this.itemList.pop();
item.removeFromParent();
this.itemPool.push(item);
}
continue;
}
let itemRender: ItemRender = item.getComponent(ItemRender);
itemRender.itemIndex = i + startIndex;
itemRender.data = this.itemDataList[i + startIndex];
itemRender.dataChanged();
if (this.type == ListType.Vertical) {
// content X 0, item x content.with/2 , Y 1, item y content 0 。 item.y= -item.height/2 , content 。
item.setPosition(this.content.width / 2, -item.height * (0.5 + i + startIndex) - this.spaceY * (i + startIndex) - this.padding_top);
} else if (this.type == ListType.Horizontal) {
item.setPosition(item.width * (0.5 + i + startIndex) + this.spaceX * (i + startIndex) + this.padding_left, -this.content.height / 2);
} else if (this.type == ListType.Grid) {
if (this.startAxis == StartAxisType.Vertical) {
var row = Math.floor((i + startIndex) / this.gridCol);
var col = (i + startIndex) % this.gridCol;
item.setPosition(item.width * (0.5 + col) + this.spaceX * col + this.padding_left, -item.height * (0.5 + row) - this.spaceY * row - this.padding_top);
item.opacity = 255;
} else if (this.startAxis == StartAxisType.Horizontal) {
var row = (i + startIndex) % this.gridRow;
var col = Math.floor((i + startIndex) / this.gridRow);
item.setPosition(item.width * (0.5 + col) + this.spaceX * col + this.padding_left, -item.height * (0.5 + row) - this.spaceY * row - this.padding_top);
item.opacity = 255;
}
}
}
this.scrollView.scrollToOffset(offset);
}
/** */
private getItem() {
if (this.itemPool.length == 0) {
return cc.instantiate(this.itemRender);
} else {
return this.itemPool.pop();
}
}
update(dt) {
if (this.bScrolling == false) {
return;
}
this.updateTimer += dt;
if (this.updateTimer < this.updateInterval) {
return;
}
this.updateTimer = 0;
this.bScrolling = false;
this.updateFun();
}
onScrolling() {
this.bScrolling = true;
}
/** */
private updateV() {
let items = this.itemList;
let item;
let bufferZone = this.halfScrollView;
let isUp = this.scrollView.content.y > this.lastContentPosY;
let offset = (this.itemHeight + this.spaceY) * items.length;
for (let i = 0; i < items.length; i++) {
item = items[i];
let viewPos = this.getPositionInView(item);
if (isUp) {
//item , scrollView , item ,item content
if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex + items.length;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.y = item.y - offset;
}
} else {
//item , scrollView , item ,item content
if (viewPos.y < -bufferZone && item.y + offset + this.padding_top < 0) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex - items.length;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.y = item.y + offset;
}
}
}
this.lastContentPosY = this.scrollView.content.y;
}
/** */
private udpateH() {
let items = this.itemList;
let item;
let bufferZone = this.halfScrollView;
let isRight = this.scrollView.content.x > this.lastContentPosX;
let offset = (this.itemWidth + this.spaceX) * items.length;
for (let i = 0; i < items.length; i++) {
item = items[i];
let viewPos = this.getPositionInView(item);
if (isRight) {
//item , scrollView , item ,item content
if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex - items.length;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.x = item.x - offset;
}
} else {
//item , scrollView , item ,item content
if (viewPos.x < -bufferZone && item.x + offset + this.padding_right < this.content.width) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex + items.length;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.x = item.x + offset;
}
}
}
this.lastContentPosX = this.scrollView.content.x;
}
/** */
private updateGrid_V() {
let items = this.itemList;
let item: cc.Node;
let bufferZone = this.halfScrollView;
let isUp = this.scrollView.content.y > this.lastContentPosY;
let offset = (this.itemHeight + this.spaceY) * (this.spawnCount / this.gridCol);
for (let i = 0; i < items.length; i++) {
item = items[i];
let viewPos = this.getPositionInView(item);
if (isUp) {
//item , scrollView , item ,item content
if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex + (this.spawnCount / this.gridCol) * this.gridCol;
if (this.itemDataList[itemIndex] != null) {
item.y = item.y - offset;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.opacity = 255;
} else {
item.y = item.y - offset;
itemRender.itemIndex = itemIndex;
item.opacity = 0;
}
}
} else {//item , scrollView , item ,item content
if (viewPos.y < -bufferZone && item.y + offset + this.padding_top < 0) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridCol) * this.gridCol;
if (this.itemDataList[itemIndex] != null) {
item.y = item.y + offset;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.opacity = 255;
} else {
item.y = item.y + offset;
itemRender.itemIndex = itemIndex;
item.opacity = 0;
}
}
}
}
this.lastContentPosY = this.scrollView.content.y;
}
/** */
private updateGrid_H() {
let items = this.itemList;
let item;
let bufferZone = this.halfScrollView;
let isRight = this.scrollView.content.x > this.lastContentPosX;
let offset = (this.itemWidth + this.spaceX) * (this.spawnCount / this.gridRow);
for (let i = 0; i < items.length; i++) {
item = items[i];
let viewPos = this.getPositionInView(item);
if (isRight) {
//item , scrollView , item ,item content
if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridRow) * this.gridRow;
if (this.itemDataList[itemIndex] != null) {
item.x = item.x - offset;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.opacity = 255;
} else {
item.x = item.x - offset;
itemRender.itemIndex = itemIndex;
item.opacity = 0;
}
}
} else {
//item , scrollView , item ,item content
if (viewPos.x < -bufferZone && item.x + offset + this.padding_right < this.content.width) {
let itemRender: ItemRender = item.getComponent(ItemRender);
let itemIndex = itemRender.itemIndex + (this.spawnCount / this.gridRow) * this.gridRow;
if (this.itemDataList[itemIndex] != null) {
item.x = item.x + offset;
itemRender.itemIndex = itemIndex;
itemRender.data = this.itemDataList[itemIndex];
itemRender.dataChanged();
item.opacity = 255;
} else {
item.x = item.x + offset;
itemRender.itemIndex = itemIndex;
item.opacity = 0;
}
}
}
}
this.lastContentPosX = this.scrollView.content.x;
}
/** item scrollView */
private getPositionInView(item) {
let worldPos = item.parent.convertToWorldSpaceAR(item.position);
let viewPos = this.scrollView.node.convertToNodeSpaceAR(worldPos);
return viewPos;
}
/** */
public getListData() {
return this.itemDataList;
}
/**
*
* @param data
*/
public addItem(data: any) {
this.itemDataList.push(data);
this.updateContent();
}
/**
*
* @param index ,0 1
* @param data
*/
public addItemAt(index: number, data: any) {
if (this.itemDataList[index] != null || this.itemDataList.length == index) {
this.itemDataList.splice(index, 1, data);
this.updateContent();
}
}
/**
*
* @param index ,0 1
*/
public deleteItem(index: number) {
if (this.itemDataList[index] != null) {
this.itemDataList.splice(index, 1);
this.updateContent();
}
}
/**
*
* @param index ,0 1
* @param data
*/
public changeItem(index: number, data: any) {
if (this.itemDataList[index] != null) {
this.itemDataList[index] = data;
this.updateContent();
}
}
/** Item */
private updateContent() {
// 0
if (this.itemList.length == 0) {
this.countListParam();
this.createList(0, new cc.Vec2(0, 0));
// 0 , item
} else {
if (this.type == ListType.Vertical) {
this.itemList.sort((a: any, b: any) => {
return b.y - a.y;
});
} else if (this.type == ListType.Horizontal) {
this.itemList.sort((a: any, b: any) => {
return a.x - b.x;
});
} else if (this.type == ListType.Grid) {
if (this.startAxis == StartAxisType.Vertical) {
this.itemList.sort((a: any, b: any) => {
return a.x - b.x;
});
this.itemList.sort((a: any, b: any) => {
return b.y - a.y;
});
} else if (this.startAxis == StartAxisType.Horizontal) {
this.itemList.sort((a: any, b: any) => {
return b.y - a.y;
});
this.itemList.sort((a: any, b: any) => {
return a.x - b.x;
});
}
}
this.countListParam();
// item
var startIndex = this.itemList[0].getComponent(ItemRender).itemIndex;
if (this.type == ListType.Grid && this.startAxis == StartAxisType.Vertical) {
startIndex += (startIndex + this.spawnCount) % this.gridCol;
} else if (this.type == ListType.Grid && this.startAxis == StartAxisType.Horizontal) {
startIndex += (startIndex + this.spawnCount) % this.gridRow;
}
//getScrollOffset() scrollToOffset() x
var offset: cc.Vec2 = this.scrollView.getScrollOffset();
offset.x = - offset.x;
this.createList(startIndex, offset);
}
}
/** */
public onDestroy() {
//
let len = this.itemList.length;
for (let i = 0; i < len; i++) {
if (cc.isValid(this.itemList[i], true)) {
this.itemList[i].destroy();
}
}
this.itemList.length = 0;
//
len = this.itemPool.length;
for (let i = 0; i < len; i++) {
if (cc.isValid(this.itemPool[i], true)) {
this.itemPool[i].destroy();
}
}
this.itemPool.length = 0;
//
this.itemDataList.length = 0;
}
}
이상 은 CocosCreator 에서 List 를 만 드 는 방법 에 대한 상세 한 내용 입 니 다.CocosCreator List 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[TIL]04.17SwiftUI 에서 UIView를 추가하기. UIViewRepresentable를 따르는 struct를 만들어서 SwiftUI에서 바로 사용하면 됩니다. 이 struct는 반드시 두 가지 메소드를 구현해야 합니다. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.