ディレクトリ
1はじめに
私たちは、多くの場合、正常な発達におけるデータ処理のカテゴリのリストに遭遇します!非常に大きな数、可能な限り、そのような選手の代表的なリストは、何百ものがあるかもしれません!私たちは、そのすべてを一度に想定し、それが崩壊を解決することがありアプリの作成につながります!ここでは、問題と一緒に分析します。
2、問題分析
実際、我々は十分な携帯電話のメモリに、これらのアイテムの寝台の子ノードに項目リードの多数を私達の時間のパフォーマンスを無駄にし、カトンのクラッシュになります。私たちが作成すると、各メンバーのための特別なアイテムを作成する必要はありません、あなただけの、一般的に、この数はあまりないときにすることができ、かつ複数で覆われた目に見える部分を作成する必要があります!それは次のとおりです。
高さ=コンテンツ/商品高さ+ 1の数の実際の作成
その上にデータを更新しながら、私たちはこれらのアイテムの位置を移動するときには、ローリングで、することができます。まあ分析を行って、我々は、コードを持っています
図3に示すように、コードセクション
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
namespace Tools.UI
{
public class UIScrollControl : MonoBehaviour
{
#region property
//======控制组件
/// <summary>
/// 滑动框体 - UI组件
/// </summary>
private ScrollRect scroll_rect;
/// <summary>
/// 滑动条
/// </summary>
public Scrollbar scroll_bar;
//======逻辑数据
/// <summary>
/// 滑动子对象 - 列表
/// </summary>
private List<ScrollChild> all_child_list = new List<ScrollChild>();
/// <summary>
/// 总数目
/// </summary>
private int total_count;
/// <summary>
/// 当前下标
/// </summary>
private int cur_index;
/// <summary>
/// 内容位置
/// </summary>
private float start_content_pos;
/// <summary>
/// 滑动框高度
/// </summary>
private float rect_high;
/// <summary>
/// 起始滑动项位置
/// </summary>
private Vector2 start_scrollChild_pos;
/// <summary>
/// content初始大小
/// </summary>
private Vector2 start_content_size;
/// <summary>
/// 是否开始标识
/// </summary>
private bool is_start = false;
#endregion
#region 外部调用
/// <summary>
/// 打开控制
/// </summary>
/// <param name="_temp_obj"></param>
/// <param name="_total_count"></param>
/// <param name="_rect_high"></param>
/// <param name="_action"></param>
public void OpenControl(GameObject _temp_obj, int _total_count, float _rect_high,
System.Action<int, GameObject> _action = null)
{
if (is_start == false)
{
scroll_rect = transform.GetComponent<ScrollRect>();
if (scroll_rect == null || scroll_rect.content == null)
{
Debug.LogError("ScrollRect组件错误");
return;
}
start_content_size = scroll_rect.content.sizeDelta;
}
Clear();
float _show_area_high = start_content_size.y;
Vector2 _startPos = Vector2.zero;
float _heigh = Mathf.Max(_total_count * _rect_high, start_content_size.y);
_startPos = new Vector3(0, (start_content_size.y - _heigh) / 2, 0);
scroll_rect.content.sizeDelta = new Vector2(start_content_size.x, _heigh);
scroll_rect.content.localPosition = _startPos;
OpenControl(_temp_obj, _total_count, _rect_high, _show_area_high, new Vector2(0, (_heigh - _rect_high) / 2), _action);
}
/// <summary>
/// 打开控制
/// </summary>
/// <param name="_temp_obj"></param>
/// <param name="_total_count"></param>
/// <param name="_rect_high"></param>
/// <param name="_show_area_high"></param>
/// <param name="_startPos"></param>
/// <param name="_action"></param>
private void OpenControl(GameObject _temp_obj, int _total_count, float _rect_high, float _show_area_high, Vector2 _startPos,
System.Action<int, GameObject> _action = null)
{
//检查参数是否合法
if(_temp_obj == null)
{
Debug.LogError("参数有误,_temp_obj == null");
return;
}
if(_total_count <= 0 || _rect_high <= 0 || _show_area_high <= 0)
{
if (scroll_bar != null)
{
scroll_bar.gameObject.SetActive(false);
}
// Debug.LogError(string.Format("参数有误,_totall_count:{0} _rect_high:{1} _show_area_high:{2}",_total_count, _rect_high, _show_area_high));
return;
}
scroll_rect = transform.GetComponent<ScrollRect>();
if (scroll_rect == null || scroll_rect.content == null)
{
Debug.LogError("ScrollRect组件错误");
return;
}
//产生对象
int _n = Mathf.CeilToInt(_show_area_high / _rect_high) + 1;
int _new_count = Mathf.Min(_n, _total_count);
for (int i = 0; i < _new_count; i++)
{
GameObject _obj;
//if (0 == i)
//{
// if (_temp_obj)
// {
// _temp_obj.gameObject.SetActive(true);
// }
// _obj = _temp_obj;
//}
//else
//{
_obj = GameObject.Instantiate(_temp_obj);
//}
_obj.SetActive(true);
_obj.name = string.Format("cell_{0}", i + 1);
_obj.transform.SetParent(scroll_rect.content.transform);
_obj.transform.localRotation = Quaternion.identity;
_obj.transform.localScale = Vector3.one;
all_child_list.Add(new ScrollChild(_obj, _action));
}
//设置参数
total_count = _total_count;
rect_high = _rect_high;
cur_index = 0;
start_scrollChild_pos = _startPos;
if (scroll_bar != null)
{
scroll_bar.gameObject.SetActive(total_count > _n);
}
//刷新布局
RefreshLayout();
scroll_rect.onValueChanged.AddListener(OnScrollRect);
start_content_pos = scroll_rect.content.anchoredPosition.y;
if (scroll_bar != null)
{
if (scroll_bar.gameObject.activeSelf)
{
scroll_bar.onValueChanged.AddListener(OnScrollBar);
}
else
{
scroll_bar.onValueChanged.RemoveAllListeners() ;
}
}
//改变标识
is_start = true;
}
/// <summary>
/// 移除一个
/// </summary>
public void RemoveOneChild(int _index)
{
total_count--;
if (total_count <= all_child_list.Count)
{
cur_index = 0;
ScrollChild child = all_child_list[all_child_list.Count - 1];
Destroy(child.Go);
all_child_list.Remove(child);
}
else
{
if (cur_index >= total_count - all_child_list.Count)
{
cur_index = total_count - all_child_list.Count - 1;
}
}
float _heigh = Mathf.Max(total_count * rect_high, start_content_size.y);
scroll_rect.content.sizeDelta = new Vector2(start_content_size.x,_heigh);
start_content_pos = (start_content_size.y - _heigh) / 2;
start_scrollChild_pos = new Vector2(0, (_heigh - rect_high) / 2);
RefreshLayout();
}
/// <summary>
/// 引导相关
/// </summary>
/// <param name="_index"></param>
/// <returns></returns>
public GameObject GuideGetObj(int _index)
{
if (_index - cur_index < 0 || _index - cur_index >= all_child_list.Count)
{
return null;
}
ScrollChild _child = all_child_list[_index - cur_index];
return _child.Go;
}
/// <summary>
/// 用来给外部调用的
/// </summary>
public void RefreshLayoutUI()
{
RefreshLayout();
}
/// <summary>
/// 刷新单独的一个item
/// </summary>
/// <param name="index"></param>
public void RefreshIndex(int index)
{
int i = index - cur_index;
if (i < 0 || i >= all_child_list.Count)
{
return;
}
ScrollChild _child = all_child_list[i];
Vector2 _pos = start_scrollChild_pos;
_pos.y -= index * rect_high;
_child.Refresh(index, _pos);
}
/// <summary>
/// 滑动面板移动到index去
/// </summary>
public void MoveToIndex(int index)
{
float _heigh = Mathf.Max(total_count * rect_high, start_content_size.y);
scroll_rect.content.localPosition = new Vector3(0, (start_content_size.y - index * _heigh) / 2, 0);
RefreshLayout();
}
#endregion
#region 逻辑处理
/// <summary>
/// 刷新
/// </summary>
private void RefreshLayout()
{
for (int i = 0; i < all_child_list.Count; i++)
{
ScrollChild _child = all_child_list[i];
int _index = cur_index + i;
Vector2 _pos = start_scrollChild_pos;
_pos.y -= _index * rect_high;
_child.Refresh(_index, _pos);
}
}
#endregion
#region 滑动事件
/// <summary>
/// 滑动框体 - 滑动事件
/// </summary>
/// <param name="_offset"></param>
private void OnScrollRect(Vector2 _offset)
{
if (scroll_bar != null)
{
if (is_scroll_bar)
{
is_scroll_bar = false;
return;
}
is_scroll_rect = true;
is_scroll_bar = false;
scroll_bar.value = 1 - _offset.y;
}
//是否发生变化
float _move_value = scroll_rect.content.anchoredPosition.y - start_content_pos;
int _index = (int)(_move_value / rect_high);
_index = Mathf.Clamp(_index, 0, total_count - all_child_list.Count);
if (_index == cur_index)
{
return;
}
cur_index = _index;
//刷新布局
RefreshLayout();
}
/// <summary>
/// 滑动的是滑动框
/// </summary>
private bool is_scroll_rect = false;
private bool is_scroll_bar = false;
/// <summary>
/// 滑动条滑动的时候执行
/// </summary>
/// <param name="_offset"></param>
private void OnScrollBar(float _value)
{
if (is_scroll_rect)
{
is_scroll_rect = false;
return;
}
is_scroll_bar = true;
is_scroll_rect = false;
scroll_rect.content.localPosition = new Vector3(scroll_rect.content.localPosition.x, start_content_pos + _value * (total_count * rect_high - start_content_size.y),0);
//是否发生变化
float _move_value = scroll_rect.content.anchoredPosition.y - start_content_pos;
int _index = (int)(_move_value / rect_high);
_index = Mathf.Clamp(_index, 0, total_count - all_child_list.Count);
if (_index == cur_index)
{
return;
}
cur_index = _index;
//刷新布局
RefreshLayout();
}
/// <summary>
/// 清理数据
/// </summary>
private void Clear()
{
for (int i = 0; i < all_child_list.Count; i++)
{
all_child_list[i].Clear();
Destroy(all_child_list[i].Go);
}
all_child_list.Clear();
if (scroll_bar != null)
{
scroll_bar.value = 0;
}
}
#endregion
#region 内嵌类
/// <summary>
/// 被滑动的子物体
/// </summary>
public class ScrollChild
{
/// <summary>
/// 对象
/// </summary>
private GameObject go;
public GameObject Go { get { return go; } }
/// <summary>
/// 刷新回调
/// </summary>
private System.Action<int, GameObject> refresh_callBack;
private RectTransform rect_tr;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="_go"></param>
/// <param name="_action"></param>
public ScrollChild(GameObject _go, System.Action<int, GameObject> _action)
{
go = _go;
rect_tr = _go.GetComponent<RectTransform>();
refresh_callBack = _action;
}
/// <summary>
/// 刷新
/// </summary>
/// <param name="_index"></param>
/// <param name="_pos"></param>
public void Refresh(int _index, Vector2 _pos)
{
rect_tr.anchoredPosition = _pos;
rect_tr.localPosition = new Vector3(rect_tr.localPosition.x, rect_tr.localPosition.y, 0);
if (refresh_callBack != null)
{
refresh_callBack(_index, go);
}
}
public void Clear()
{
refresh_callBack = null;
}
}
#endregion
}
}
コードは、より詳細なコメントですので、私はここでは説明しません。
図4に示すように、例えば、使用
4.1、シーンを設定します
我々が構築された図のシナリオ
。スクロールビューUIScrollControlコンテンツは、図のアンカーとして調整する必要が、スクリプトの前にハングアップする必要があり、以下に示すように、ビューポートのアンカーが提供されます。
4.2試験
私達はちょうどスクロールリストでこのぶら下げように、それの外部コールの一部を呼び出し、使用する必要があります。以下のような:
using System.Collections;
using System.Collections.Generic;
using Tools.UI;
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour {
public UIScrollControl scroll_rect;
private List<string> strList = new List<string>() { "春秋","战国","五代", "十国", "夏金", "唐", "宋", "元" };
// Use this for initialization
void Start () {
GameObject item = transform.Find("Item").gameObject;
scroll_rect.OpenControl(item, strList.Count, 100, init);
}
private void init(int index,GameObject obj)
{
Text txt = obj.transform.FindChild("Text").GetComponent<Text>();
txt.text = strList[index];
}
// Update is called once per frame
void Update () {
}
}
4.3、の効果を示します
示すように、結果を使用して:
私たちはここを参照してください唯一の4つの項目を作成しました。
5、デモダウンロード
靴はどこに理解することができない場合は、上記のプレゼンテーションデモをダウンロードするデモは、2つの縦方向と横方向を含むコードを最適化しながら、。
6.おわりに
エンド
不備も期待している場合さて、ここで今日のシェアは、あなたが時間に私を修正し、為替を議論すること自由に感じ!!!
友人のように、Bangdingは、親指アップ、コメントしてください!私の執筆のあなた確かに無尽蔵のパワー!