使用泛型简单封装NGUI的ScrollView实现滑动列表
懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了。。也是懒的,有时都懒的写博客。。
最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):
1、首先分析共性方面的东西:
逻辑上,都有个基础Item类及对应的管理类ItemManager
显示上,都是显示某个基本对象ViewItem,并且都需要管理者UIScrollView(封装为ViewManager)
2、根据初步的分析结果,进行抽象,这里直接使用泛型处理:
(这里直接使用了原有的Json插件及部分项目中需求的设计:int类型的key)
1)先说下逻辑层(基础)
A.首先是Item类:
存储单个基础的各种信息,此处未使用struct,因为不引用的情况下会导致后期对item的很多更新管理、状态改变造成不便。设计如下:
using UnityEngine;
using LitJson;
public abstract class Item
{
public int ID;
public Item()
{
}
public abstract void Init(JsonData _data);
}
B.其次是对应的管理类ItemManager:
using UnityEngine;
using LitJson;
using System;
using System.Collections.Generic;
public abstract class ItemManager<T> where T : Item, new()
{
public IList<T> ItemLst = new List<T>();
public T GetItemByID(int _id)
{
for(int i = 0; i < ItemLst.Count; i++)
{
if(ItemLst[i].ID == _id)
{
return ItemLst[i];
}
}
return null;
}
public virtual void Init(JsonData _jsonData, Action<IList<T>> _callback = null)
{
ItemLst.Clear(); //刷新
if(_jsonData == null || _jsonData.Equals(""))
{
}
else
{
for(int i = 0; i < _jsonData.Count; i++)
{
JsonData tJson = _jsonData[i];
T tItem = new T();
tItem.Init(tJson);
ItemLst.Add(tItem);
}
if(_callback != null) //回调
{
_callback(ItemLst);
}
}
}
}
2)其次再来说一下显示层View
A.首先单个的ViewItem单元,负责自身的初始化、显示、交互(继承时,各自去实现、管理)等:
using UnityEngine;
using System.Collections;
public abstract class ViewItem<T> : MonoBehaviour where T : Item
{
protected T item;
public virtual void Init(T _item)
{
item = _item;
}
}
B.对应的是显示的控制:
using UnityEngine;
using System.Collections.Generic;
public abstract class ViewManager<T, V> : MonoBehaviour
where T : Item
where V : ViewItem<T>
{
[SerializeField]
protected UIScrollView scrollView;
[SerializeField]
protected UIGrid uiGridObj;
private GameObject father;
[SerializeField]
private V viewItemPrefab;
void Start()
{
father = uiGridObj.gameObject;
}
public void RefreshShow()
{
scrollView.gameObject.SetActive(false);
scrollView.gameObject.SetActive(true);
uiGridObj.repositionNow = true;
}
public virtual void ShowInfo(IList<T> _lst)
{
foreach(var item in cacheMap)
{
item.Value.gameObject.SetActive(false);
}
for(int i = 0; i < _lst.Count; i++)
{
var item = _lst[i];
if(!cacheMap.ContainsKey(item.ID))
{
GameObject tItem = NGUITools.AddChild(father, viewItemPrefab.gameObject);
V tViewItem = tItem.GetComponent<V>();
tViewItem.Init(item);
cacheMap.Add(item.ID, tViewItem);
}
else
{
cacheMap[item.ID].Init(item);
}
cacheMap[item.ID].gameObject.SetActive(true);
uiGridObj.AddChild(cacheMap[item.ID].transform);
cacheMap[item.ID].transform.localScale = Vector3.one;
}
RefreshShow();
}
protected void deleteItem(int _id)
{
foreach(var kv in cacheMap)
{
if(kv.Key == _id)
{
kv.Value.gameObject.SetActive(false);
break;
}
}
uiGridObj.repositionNow = true;
}
protected Dictionary<int, V> cacheMap = new Dictionary<int, V>();
}
因为在使用NGUI的Grid布局时CellSnap的方式(不明白是自己使用的方式存在错误还是本身的问题?还望有经验的朋友指教一下),需要自己进行计算实现,这样我们需要自己重写ShowInfo方法,比如:
using UnityEngine;
using System.Collections.Generic;
public class CellViewManager : ViewManager<IconInfo, IconViewItem>
{
public static CellViewManager m_pIns = null;
void Awake()
{
m_pIns = this;
scrollviewPanel = scrollView.GetComponent<NGUIPanel>();
}
private NGUIPanel scrollviewPanel;
public override void ShowMailInfo(IList<IconInfo> _lst)
{
base.ShowMailInfo(_lst);
if(uiGridObj.arrangement == UIGrid.Arrangement.CellSnap)
{
int tX = 0;
int tY = 0;
foreach(var item in cacheMap)
{
if(item.Value.gameObject.activeSelf)
{
float tWidth = uiGridObj.cellWidth * tX;
if(tWidth + uiGridObj.cellWidth / 2 > scrollviewPanel.width)
{
tWidth = 0;
tX = 1;
tY--;
}
else
{
tX++;
}
item.Value.transform.localPosition = new Vector3(tWidth, tY * uiGridObj.cellHeight, 0);
}
}
RefreshShow();
}
}
}
这里计算边界是根据ViewItem的widget在中心计算的!
这样,就实现了最终偷懒的目的!
使用泛型简单封装NGUI的ScrollView实现滑动列表的更多相关文章
- .Net Core应用RabbitMQ,及简单封装
首先,还是万分感谢大家能够抽空来阅读我的文章,万分感谢.今天我带来的是.Net Core中应用RabbitMQ,和简单封装.因为昨天的文章里说了今天要写,所以今天一定要写出来.小编翻阅了很多资料,想要 ...
- 孟老板 BaseAdapter封装 (一) 简单封装
BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- FMDB简单封装和使用
工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...
- Android--Retrofit+RxJava的简单封装(三)
1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...
- okhttp3 get post 简单封装
最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...
- python网页请求urllib2模块简单封装代码
这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...
- 对pymysql的简单封装
#coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...
- iOS开发——UI篇OC篇&UITableView简单封装
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
随机推荐
- Python深入学习笔记(一)
写在前面的话 从08年接触Python到现在,断断续续地使用,到如今Python已经成为日常事物处理.科研实验,甚至工程项目的主力语言,主要因为其敏捷性和快速实现的能力.虽然看了一些Python的教程 ...
- shell编程的一些例子5
1.here文档 here文档允许我们调用一个交互式程序:可以从脚本程序中输出大量的文本,从而不必echo每行 例子1: #!/bin/bash cat<<!DATA! This is a ...
- Instruments --- 内存泄露
虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露, ...
- 二分法查找(Binary Search)
--摘要:二分法的介绍已经很多了,但并不直观,因此此文诞生,希望批评指正. 二分查找是在有序数组中查找一个元素的算法,通过比较目标元素与数组中间元素来查找,如果目标值是中间元素则将返回中间元素位置. ...
- [转]HTTP Error 400. The request hostname is invalid.
一般看到网站提示Bad Request(Invalid Hostname)错误我们都会说是iis,apache出问题了,iis出现这种问题解决办法大概是:IIS> 默认网站> > 属 ...
- bzoj 3160: 万径人踪灭 manachar + FFT
3160: 万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 133 Solved: 80[Submit][Status][Discuss] ...
- BZOJ 1044
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1393 Solved: 497[Submit][Statu ...
- ALV 行列 颜色
1)颜色含义 1:海蓝:2:浅清:3:黄色:4:浅蓝:5:青色:6:红色:7:橙色.(1)首位为主颜色:(2)次位为辅助颜色:(3)末位为0时,表示首位数字表为表格的底色:末位为1时,则表示以1为底色 ...
- jquery之ajaxfileupload异步上传插件
点我下载工程代码由于项目需求,在处理文件上传时需要使用到文件的异步上传.这里使用Jquery Ajax File Uploader这个组件下载地址:http://www.phpletter.com/d ...
- Github上更新自己Fork的代码
一.前提本文的前提是你已经在github上fork了别人的分支,并且弄好了跟github的ssh连接.相关配置详情参考:https://help.github.com二.详细操作 检出自己在githu ...