NGUI 學習筆記實戰之二——商城數據綁定(Ndata)


    上次筆記實現了游戲商城的UI界面,沒有實現動態數據綁定,所以是遠遠不夠的。今天采用NData來做一個商城。

  如果你之前沒看過,可以參考上一篇博客

   NGUI 學習筆記實戰——制作商城UI界面

  http://www.cnblogs.com/chongxin/p/3876575.html

一、NData介紹以及優點

        大體來說NData就是一個NGUI 的 MVVM 框架插件,如果你問我什么是MVVM,我也只能說類似於MVC,至於什么是MVC…………

     說道NData的優點,我們先來看這個,如果要寫商城邏輯,一般如下:

 

     

        這個邏輯很簡單,但是之前我實現是在OnMouse這類函數中進行判斷,然后直接與底層數據交互。這還沒什么,如果底層商城的商品種類增加,那么我還得在UI進行構造新的UI部件。

      最后,讓我無法容忍的就是,這些UI部件的顯示的數據我還要記住這些UI部件的路徑,一個個翻過去找,如果路徑復雜就很麻煩。剛開始還沒什么,時間一長就要吐了。

        這些用NData就可以很方便的解決,大體的解決思路就和上面那張圖差不多,他在UI和邏輯層中又多加了一層,類似於頁面邏輯模型,並且將頁面邏輯模型的數據和顯示UI上的部件綁定。做到了動態刷新。

        之后你對頁面所有的操作都可以通過對這個頁面模型交互來實現,做到了邏輯和UI分離的境界。

二、創建ViewModel模板

  可能你看的剛才雲里霧里,那么你可以省略剛才那段話,更多的時候領悟是在實踐中才發現。

  我們現在先編寫一個頁面模型,模板如下:

     

using UnityEngine;
 
public class $game$Ui : EZData.Context
{
 //TODO: add your dependency properties and collections here
 
	//綁定頁面上的屬性
	#region Property $name$
	private readonly EZData.Property<$type$> _private$name$Property 
									= new EZData.Property<$type$>();
	public EZData.Property<$type$> $name$Property 
									{ get { return _private$name$Property; } }
	public $type$ $name$
	{
	get    { return $name$Property.GetValue();    }
	set    { $name$Property.SetValue(value); }
	}
	#endregion
	
	//綁定頁面上的集合(比如商城每一行)
	#region Collection $name$
	private readonly EZData.Collection<$type$> _private$name$ 
									 = new EZData.Collection<$type$>(false);
	public EZData.Collection<$type$> $name$ 
									{ get { return _private$name$; } }
	#endregion

}
  
public class ViewModel : MonoBehaviour
{
         //NGUI UIRoot 編輯器中手動拖進
public NguiRootContext View; //這個代表頁面模型
   public $game$Ui Context; void Awake() { Context = new $game$Ui(); View.SetContext(Context); } }

    對於上面的模板,如果對其功能有所疑問的話,我建議你看一下NData 的基本教程 http://tools.artofbytes.com/ndata/tutorials/simple-tutorial,其實功能我在代碼注釋中已經寫的很明白了。

    這里有一個小插曲,看NData的官方教程是用Mono的類模板來創建 ,因為本人Win7下開發,裝了VS2010, 裝了之后卻用不了mono了,無語。

三、頁面邏輯編寫

        這里我們要實現的頁面功能如下:

     

          可以看到,我們這里的商城類似於表格,有多行3列,同時每一個UI部件也有自己屬性,設計頁面模型如下:

          UI部件的頁面模型

    public class CommodityItem : EZData.Context
    {
        #region Property ShopId
        #endregion

        #region Property Name
        #endregion

        #region Property Price
        #endregion

        //商品圖標
         #region Property Logo
        #endregion

        #region Property Describle
        #endregion
     }

     每行的頁面模型

public class CommodityPage<T> : EZData.Context 
    where T : EZData.Context
{  
    //列的集合
    #region Collection Page
    private readonly EZData.Collection<T> _privatePage = new EZData.Collection<T>(false);
    public EZData.Collection<T> Page { get { return _privatePage; } }
    #endregion
}

    整體的模型

public class Shop<T> : EZData.Context 
    where T : EZData.Context
{
    //行的集合
    #region Collection Table
    private readonly EZData.Collection<CommodityPage<T>> _privateTable = new EZData.Collection<CommodityPage<T>>(false);
    public EZData.Collection<CommodityPage<T>> Table { get { return _privateTable; } }
    #endregion

}

四、頁面模型進行數據填充

     一、先設計一個內存數據庫,填充每一個UI部件頁面模型的數據

 

   二、頁面模型進行引用填充,填充行列的數據

 

 

public class Shop<T> : EZData.Context 
    where T : EZData.Context
{
    //行的集合
    #region Collection Table
    private readonly EZData.Collection<CommodityPage<T>> _privateTable = new EZData.Collection<CommodityPage<T>>(false);
    public EZData.Collection<CommodityPage<T>> Table { get { return _privateTable; } }
    #endregion

    //頁面模型生成的時候 同時進行數據綁定
    public Shop(T[] Array,int PageNum)
    {
        Load(Array,PageNum);
    }

    //加載數據
    void Load(T[] Array, int PageNum)
    {
        //總共需要的數量
        int AllNum = Array.Length;

        //每一頁需要的數量
        int PageCount;

        //有多少頁
        if (AllNum == 0)
            PageCount = 0;
        else
            PageCount = ((AllNum % PageNum == 0) ? (AllNum / PageNum) : (AllNum / PageNum + 1));
        
		//總有多少行
        for (int i = 0; i < PageCount; i++)
       {
			//生成一行
            Table.Add(new CommodityPage<T>());
			
			//總有多少列
            for (int j = 0; j < PageNum && (i * PageNum + j) < AllNum; j++)
          {
	       Table.GetItem(i).Page.Add(Array[i * PageNum + j]);
          }
       }
    }
}

public class UIShopViewModel: MonoBehaviour
{
    public NguiRootContext View;
    
    public Shop<CommodityItem> Context;

    public ShopData myShopDate;

    void Awake()
    {
        Context = new Shop<CommodityItem>
        (myShopDate.CommodityItemArray,3);
        View.SetContext(Context);
    }
}

          三、數據綁定

       到了最重要的一步,進行數據綁定。剛才的頁面邏輯如果你跟下來的話就知道我們首先要設計一個UI部件 之后三個組成一行,然后多行組成一個界面

   如此,我們先綁定UI部件

      

        再綁定一行

  

          最后綁定整個頁面

   

   最后、動態生成

 

  測試一下:數據庫里面新加一條

   

    UI商城可以動態增加,完全代碼操作,動態刷新,只需要加一句話。

    整體的流程就是設計頁面模型,填充頁面模型數據,綁定頁面,方便快捷有保證,而且可以復用,之后類似的界面,只需要換掉最基本的UI頁面模型即可。哇咔咔!

   

 

  2014-9-3 記錄:  注意,商品部件也就是item 中的 圖片動態綁定是有問題的,不論用texturebind 還是spritebinding.最后只會出現一張圖片

  我建議自己根據NguiItemDataContext 得到對應的 行列index, 然后在viewmodel中找到對應的那個部件的圖片名稱,然后根據圖片名稱自己查找圖片賦值。

       Ndata基本上已經不更新了,而且bug很多,在做復雜業務邏輯的時候要注意。

 2014-9-4 問題解決

  NguiTextureBinding 本質是用uitexture 的 材質的圖片,而材質是只有一個的,除非你每個item用一個材質,如果你都用一個材質,那么所有item的圖片取決於你最后的那個材質所用的圖片,這樣也就解釋了為什么texturebind只會出現一張圖片。

  更新如下即可:

  

 

  2014-9-22日

  注意,在用grid 進行NguiItemsSourceBinding 使用Path 綁定的時候,NguiListItemTemplate的Template的gameobject root 最好是帶有碰撞器的,不然無法使用 **list.selecteditem

  

   2015-5-22 

    不建議使用NData,最好可以自己實現一套


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM