Unity3D-UGUI无限滚动加载TableView列表
2016-09-09 17:44
961 查看
本站文章转载务必在明显处注明:[b]原文链接 http://blog.csdn.net/cjsen/article/details/52489191[/b]
前言
在UGUI中并没有自带类似cocos2d-x里的列表控件TableView,只能ScrollView这种的滚动条,下面就自定义一个TableView。
[b]正文
[/b]
[b][b]1,实现功能:列表中cell的重复利用,在列表滚动刷新中只改变cell的数据内容与位置
,并不会一直加载新的cell,cell的最大数量只在于覆盖可视界面的高度
[/b][/b]
2,实现思路:利用UGUI的ScrollView,根据列表的可视高度计算需要多少个cell,在void onValueChanged(Vector2 value)方法,计算列表的滚动位置距离,计算并刷新cell的位置和数据
3,下面是实现的主要源码,不一一解释,文章后面会放出完整工程控件代码和使用示例
[b][b]完整工程示例代码
[/b][/b]
前言
在UGUI中并没有自带类似cocos2d-x里的列表控件TableView,只能ScrollView这种的滚动条,下面就自定义一个TableView。
[b]正文
[/b]
[b][b]1,实现功能:列表中cell的重复利用,在列表滚动刷新中只改变cell的数据内容与位置
,并不会一直加载新的cell,cell的最大数量只在于覆盖可视界面的高度
[/b][/b]
2,实现思路:利用UGUI的ScrollView,根据列表的可视高度计算需要多少个cell,在void onValueChanged(Vector2 value)方法,计算列表的滚动位置距离,计算并刷新cell的位置和数据
3,下面是实现的主要源码,不一一解释,文章后面会放出完整工程控件代码和使用示例
<span style="font-family:Menlo;"><span style="color:#333333;">using UnityEngine</span><span style="color:#333333;">;</span> <span style="color:#333333;">using System</span><span style="color:#333333;">.</span><span style="color:#333333;">Collections</span><span style="color:#333333;">;</span></span> using UnityEngine.UI; using System.Collections.Generic; using UnityEngine.EventSystems; //列表排列方向 public enum TableDirection{ Horizontal, //水平 Vertical //直 } public class UITableView : MonoBehaviour,IBeginDragHandler,IEndDragHandler,IDragHandler { TableCellWithShowedDelegate m_pTableCellWithShowedDelegate = null;//设置委托 float m_fCellHight; //行的高度 int m_iCellTotalNum; //行的总数量 int m_iCellPortNum; //可视行的数量 Vector2 m_pTableViewSize; //列表的宽高 Vector2 m_pContentViewSize; //列表内容的宽高 GameObject m_pScrollView; //列表Scroll控件 RectTransform m_pContentView; //列表内容 List<UITableViewCell> m_pCellViewList = null;//可视的行存储队列 //初始化数据 void init(Vector2 rectPos,Vector2 rectSize,Transform parent,TableDirection dir){ m_pCellViewList = new List<UITableViewCell> (); GameObject _scrollViewPerfab = Resources.Load ("prefab/UITableView/ScrollView") as GameObject; m_pScrollView = GameObject.Instantiate (_scrollViewPerfab) as GameObject; m_pScrollView.transform.SetParent (parent); m_pScrollView.transform.localScale = _scrollViewPerfab.transform.localScale; m_pScrollView.transform.localPosition = rectPos; m_pScrollView.GetComponent<RectTransform> ().sizeDelta = rectSize;//new Vector2 (540.0f, 640.0f); m_pScrollView.GetComponent<ScrollRect>().onValueChanged.AddListener (onValueChanged); m_pContentView = m_pScrollView.GetComponent<ScrollRect> ().content; m_pTableViewSize = rectSize; } void onValueChanged(Vector2 value){ float _showStartY = m_pContentView.GetComponent<RectTransform> ().localPosition.y; float _showEndY = _showStartY + m_pTableViewSize.y; if (_showStartY < 0 || _showEndY > m_pContentViewSize.y) { return; } int _listCount = m_pCellViewList.Count; //先搜索列表上面有没有可显示的行 bool _bIsHaveCell = false; for(int i = 0; i < _listCount; i++){ UITableViewCell _cellItem = m_pCellViewList [i]; float _cellUpPosY = System.Math.Abs(_cellItem.transform.localPosition.y) - m_fCellHight * 0.5f; if(_cellUpPosY <= _showStartY ){ _bIsHaveCell = true; break; } } if (_bIsHaveCell == false) { //计算出要显示的是哪一行,更新行 float _fTopIndex = (_showStartY/m_fCellHight)-(int)(_showStartY/m_fCellHight); int _iTopIndex = (int)(_showStartY / m_fCellHight); int _showTopIndex = _fTopIndex == 0.0f ? _iTopIndex : _iTopIndex + 1; updateCellAtIndex (_showTopIndex-1); } else { //搜索列表下部分有没有可显示的行 bool _bBottomHaveCell = false; for(int i = 0; i < _listCount; i ++){ UITableViewCell _cellItem = m_pCellViewList[i]; float _cellDownPosY = System.Math.Abs (_cellItem.transform.localPosition.y) + m_fCellHight * 0.5f; if (_cellDownPosY >= _showEndY) { _bBottomHaveCell = true; break; } } if (_bBottomHaveCell == false) { //计算出要显示的是哪一行,更新行 float _fBottomIndex = (_showEndY/m_fCellHight)-(int)(_showEndY/m_fCellHight); int _iBottomIndex = (int)(_showEndY / m_fCellHight); int _showBottomIndex = _fBottomIndex == 0.0f ? _iBottomIndex : _iBottomIndex + 1; updateCellAtIndex (_showBottomIndex-1); } } } //按索引获取更新行 void updateCellAtIndex(int idx){ bool _isHaveDeq = isHaveDequeueCell (); if (_isHaveDeq == true) { UITableViewCell _cell = tableDequeueCellIndex (idx); if (m_pTableCellWithShowedDelegate != null) { m_pTableCellWithShowedDelegate(_cell, idx, true); } }else{ UITableViewCell _cell = createTableCell (idx); m_pCellViewList.Add (_cell); if (m_pTableCellWithShowedDelegate != null) { m_pTableCellWithShowedDelegate(_cell, idx, true); } } } void createCellItem(UITableViewCell tabelCell,int index, bool isNew){ GameObject _cell = null; if (isNew == true) { GameObject _cellPerfab = Resources.Load ("ListItemCell") as GameObject; _cell = GameObject.Instantiate (_cellPerfab) as GameObject; tabelCell.addViewCell (_cell); } else { _cell = tabelCell.getViewCell (); } } UITableViewCell createTableCell(int index){ UITableViewCell _tableCell = UITableViewCell.createTableCell (); _tableCell.transform.SetParent (m_pContentView.transform); _tableCell.transform.localScale = m_pContentView.transform.localScale; _tableCell.transform.localRotation = m_pContentView.transform.localRotation; _tableCell.transform.localPosition = new Vector2 (_tableCell.transform.localPosition.x,positionWithIndex(index)); return _tableCell; } float positionWithIndex(int index){ float _cellPosY = -(m_fCellHight * 0.5f + m_fCellHight * index); Debug.Log ("positionWithIndex:index="+index+" _cellPosY="+_cellPosY); return _cellPosY; } //检测当前列表的滚动的位置中 列表上是否有已生成但在隐藏位置的行 bool isHaveDequeueCell(){ bool _bIsHaveDeqCell = false; float _showStartY = m_pContentView.GetComponent<RectTransform> ().localPosition.y; float _showEndY = _showStartY + m_pTableViewSize.y; int _listCount = m_pCellViewList.Count; for(int i = 0; i < _listCount; i++){ UITableViewCell _cellItem = m_pCellViewList [i]; float _cellDownPosY = System.Math.Abs (_cellItem.transform.localPosition.y) + m_fCellHight * 0.5f; if (_cellDownPosY > _showEndY) { _bIsHaveDeqCell = true; break; } } return _bIsHaveDeqCell; } //根据要显示的行索引,找出一个隐藏的行 并重新设置位置为要显示的行的位置并返回 UITableViewCell tableDequeueCellIndex(int idx){ UITableViewCell _pTableViewCell = null; float _showStartY = m_pContentView.GetComponent<RectTransform> ().localPosition.y; float _showEndY = _showStartY + m_pTableViewSize.y; int _listCount = m_pCellViewList.Count; //检测当前列表的滚动的位置中 列表上面是否有已生成但在隐藏位置的行 bool _bTopIsHaveDeqCell = false; for(int i = 0; i < _listCount; i++){ UITableViewCell _cellItem = m_pCellViewList [i]; float _cellDownPosY = System.Math.Abs (_cellItem.transform.localPosition.y) - m_fCellHight * 0.5f; if (_cellDownPosY < _showEndY-m_fCellHight) { _bTopIsHaveDeqCell = true; break; } } int _iDequeueCellIndex = 0; if (_bTopIsHaveDeqCell == true) { //找出列表上面位置 处于隐藏位置的最顶的一行 for(int index = 1; index < _listCount; index++){ UITableViewCell _pHideCell = m_pCellViewList [_iDequeueCellIndex]; UITableViewCell _pTempCell = m_pCellViewList [index]; if (System.Math.Abs(_pTempCell.transform.localPosition.y) < System.Math.Abs(_pHideCell.transform.localPosition.y)){ _iDequeueCellIndex = index; } } } else { for (int i = 1; i < _listCount; i++) { UITableViewCell _pHideCell = m_pCellViewList [_iDequeueCellIndex]; UITableViewCell _pTempCell = m_pCellViewList [i]; if (System.Math.Abs (_pTempCell.transform.localPosition.y) < System.Math.Abs (_pHideCell.transform.localPosition.y)) { _iDequeueCellIndex = i; } } } float _cellPosY = -(m_fCellHight * 0.5f + m_fCellHight * idx); m_pCellViewList[_iDequeueCellIndex].transform.localPosition = new Vector2 (m_pCellViewList[idx].transform.localPosition.x,_cellPosY); _pTableViewCell = m_pCellViewList [_iDequeueCellIndex]; return _pTableViewCell; } //更新加载列表 public void reloadData(){ updateData (); float _showStartY = m_pContentView.GetComponent<RectTransform> ().localPosition.y; int _iFirstIndex = (int)(_showStartY / m_fCellHight); int _showFirstIndex = _iFirstIndex == 0.0f ? _iFirstIndex : _iFirstIndex + 1; for (int i = _showFirstIndex; i < _showFirstIndex+m_iCellPortNum; i++) { updateCellAtIndex (i); } } void updateData(){ //计算复用的cell的数量 float m_iPortNum = (m_pTableViewSize.y/m_fCellHight)-(int)(m_pTableViewSize.y/m_fCellHight);//取余 int m_iPortNum1 = (int)(m_pTableViewSize.y/m_fCellHight); m_iCellPortNum = m_iPortNum == 0.0f ? m_iPortNum1 : m_iPortNum1+1; if (m_iCellPortNum > m_iCellTotalNum) { m_iCellPortNum = m_iCellTotalNum; } m_pContentViewSize.x = m_pTableViewSize.x; m_pContentViewSize.y = m_iCellTotalNum * m_fCellHight; m_pContentView.GetComponent<RectTransform> ().sizeDelta = m_pContentViewSize; } public void OnDrag (PointerEventData eventData){ // Debug.Log ("开始拖动pressPosition="+eventData.pressPosition+"position="+eventData.position); } public void OnBeginDrag (PointerEventData eventData){ // Debug.Log ("开始拖动pressPosition="+eventData.pressPosition+"position="+eventData.position); } public void OnEndDrag (PointerEventData eventData){ // Debug.Log ("结束拖动pressPosition="+eventData.pressPosition+"position="+eventData.position); } //获取和设置行数量 public void setCellTotalNum(int num){ m_iCellTotalNum = num; } public float getCellTotalNum(){ return m_iCellTotalNum; } //获取和设置行的高度 public void setCellHight(float h){ m_fCellHight = h; } public float getCellHight(){ return m_fCellHight; } public void setTableCellWithShowedDelegate(TableCellWithShowedDelegate del){ m_pTableCellWithShowedDelegate = del; } public TableCellWithShowedDelegate getTableCellWithShowedDelegate(){ return m_pTableCellWithShowedDelegate; } // Use this for initialization void Start () { } //公共方法 public static UITableView createTable(Vector2 rectPos,Vector2 rectSize, Transform parent,TableDirection dir = TableDirection.Vertical){ GameObject _object = new GameObject (); UITableView _table = null; if (_object != null) { // _object.name = "UITableView"; _table = _object.AddComponent (typeof(UITableView)) as UITableView; _table.init (rectPos, rectSize, parent, dir); } else { Debug.Log ("出错了"); } return _table; } public delegate void TableCellWithShowedDelegate (UITableViewCell cell,int index, bool isNew); }
[b][b]完整工程示例代码
[/b][/b]
相关文章推荐
- (原创)自定义view(view的绘制过程)、无限轮播并触碰停止轮播的viewpage、水平和垂直滚动的TextView、仿QQ滑动删除、下拉刷新上拉加载view、毛玻璃效果、低版本水波纹、圆环头像图
- iOS实现无限循环滚动的TableView实战教程
- Unity系列——UGUI创建滑动列表tableview
- tableview 卡顿优化 加强 iOS 里的列表滚动时的顺畅感
- android WJYScorllTableView可上拉加载下拉刷新且可以左右滚动的listview
- TableView滚动时的懒加载
- iOS tableView下拉顶部视图放大 自动滚动 无限滚动 自动布局 在code4App和github上早就上传了代码,这边记录下
- iOS tableViewCell 在cell赋值、网络加载照片位置偏移大小错乱,做一个类似qq列表的tableview 更新3
- unity ugui ScrollView无限滚动
- IOS超级简单上下左右滚动TableView,仿同花顺自选列表
- 关于tableview的滚动后动态加载数据
- 如何提高tableView的滚动速度
- 关于SAP的TABLEVIEW编程的几个重要变量值的变化列表
- tableview滚动到某行 ios5貌似有了新的API 呵呵
- Tableview和PickerView重新加载数据
- ListView滚动加载(类似Android Market的列表)
- iphone 如何判断tableview滚动到最低端
- 关于SAP的TABLEVIEW编程的几个重要变量值的变化列表
- 利用DTGridView实现横向滚动的tableview
- Three20软件引擎之自定义TableView列表详解(二)