【问题标题】:Using For-Each loop to create a TableView使用 For-Each 循环创建 TableView
【发布时间】:2023-03-18 00:03:01
【问题描述】:

我正在使用 Unity3D 资源为我的应用程序创建一个 TableView。但是,当我尝试在 for-each 循环中从一个对象移动到另一个对象时,它只显示响应中的最后一个对象。这就是我的意思:

这是我尝试创建单元格的代码(仅供参考,我使用 GameSparks 作为后端服务):

//Will be called by the TableView to know how many rows are in this table
public int GetNumberOfRowsForTableView (TableView tableView)
{
    return 10;
}

//Will be called by the TableView to know what is the height of each row
public float GetHeightForRowInTableView (TableView tableView, int row)
{
    return (m_cellPrefab.transform as RectTransform).rect.height;
}

//Will be called by the TableView when a cell needs to be created for display
public TableViewCell GetCellForRowInTableView (TableView tableView, int row)
{
    LeaderboardCell cell = tableView.GetReusableCell (m_cellPrefab.reuseIdentifier) as LeaderboardCell;

    if (cell == null) {
        cell = (LeaderboardCell)GameObject.Instantiate (m_cellPrefab);
        new GameSparks.Api.Requests.LeaderboardDataRequest ().SetLeaderboardShortCode ("High_Score_Leaderboard").SetEntryCount (100).Send ((response) => {
            if (!response.HasErrors) {
                resp = response;
                Debug.Log ("Found Leaderboard Data...");

            } else {
                Debug.Log ("Error Retrieving Leaderboard Data...");
            }
        });
    }

    foreach (GameSparks.Api.Responses.LeaderboardDataResponse._LeaderboardData entry in resp.Data) {
        int rank = (int)entry.Rank;
        //model.Rank =rank;
        string playerName = entry.UserName;
        cell.name = playerName;
        string score = entry.JSONData ["SCORE"].ToString ();
        cell.SetScore(score);
        //string fbid = entry.ExternalIds.GetString("FB").ToString();
        //model.facebookId = fbid;
        Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
    }
    return cell;
}

【问题讨论】:

    标签: c# android ios unity3d tableview


    【解决方案1】:

    您首先实例化单元格变量,然后对您的 resp.Data 执行 for 循环。问题是,您只需遍历所有数据,每次迭代都设置名称并设置分数。每次迭代时,您都会覆盖这些值,然后在最后,当循环结束时,您返回单元格的最后一个版本。 根据您在 GetCellForRowInTableView 方法上方的评论,您不应该真正循环在那里,因为该方法应该为每个项目调用一次。因此,你想要做的而不是循环是这样的:

    public TableViewCell GetCellForRowInTableView (TableView tableView, int row)
    {
        LeaderboardCell cell = tableView.GetReusableCell (m_cellPrefab.reuseIdentifier) as LeaderboardCell;
    
        if (cell == null) {
            cell = (LeaderboardCell)GameObject.Instantiate (m_cellPrefab);
            new GameSparks.Api.Requests.LeaderboardDataRequest ().SetLeaderboardShortCode ("High_Score_Leaderboard").SetEntryCount (100).Send ((response) => {
                if (!response.HasErrors) {
                    resp = response;
                    Debug.Log ("Found Leaderboard Data...");
    
                } else {
                    Debug.Log ("Error Retrieving Leaderboard Data...");
                }
            });
        }
    
        var entry = resp.Data[row];
            int rank = (int)entry.Rank;
            //model.Rank =rank;
            string playerName = entry.UserName;
            cell.name = playerName;
            string score = entry.JSONData ["SCORE"].ToString ();
            cell.SetScore(score);
            //string fbid = entry.ExternalIds.GetString("FB").ToString();
            //model.facebookId = fbid;
            Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
    
        return cell;
    }
    

    【讨论】:

    • 这个解决方案的问题是从GameSparks服务器返回的数据由于某种原因无法被索引,无论如何我可以通过将数据转换为JSON来应用这个解决方案吗?
    • 如何使用 linq 和方法 ElementAt (msdn.microsoft.com/en-us/library/bb299233(v=vs.100).aspx) - 如果您可以使用 foreach 循环枚举您的响应,那么这应该也可以。然后你将拥有 resp.ElementAt(row) 而不是 resp.Data[row]。
    【解决方案2】:

    您的问题是 foreach 循环的经典问题。基本上,系统用集合中的新索引项覆盖当前引用。因此,尽管您将值存储在局部变量中,但您的条目引用被覆盖,然后所有值最终都指向同一个条目对象。

    解决方案是创建一个本地条目引用:

       foreach (GameSparks.Api.Responses.LeaderboardDataResponse._LeaderboardData entry in resp.Data) {
            var localEntry = entry; // New line
            int rank = (int)localEntry.Rank; // entry is replaced with local
            string playerName = localEntry.UserName; 
            cell.name = playerName;
            string score = localEntry.JSONData ["SCORE"].ToString (); line 
            cell.SetScore(score);
            Debug.Log ("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
        }
    

    编辑:我看到你在循环之外返回单元格,所以即使循环修复了一个问题,你在其他地方还有另一个问题。

    在每个循环中,您正在填充单元格数据。但是在每个循环中,您都在覆盖单元格数据。最后,您返回最后一个值。 您可以返回一个单元格数组并使用该数组创建项目,或者将一个项目数组传递给该方法,因此对于循环的每次迭代,您还可以设置匹配项目的值(使用索引)。

    【讨论】:

    • 我尝试使用此解决方案,但是出现了同样的问题,我还尝试通过将 return cell; 放入 for-each 循环中来解决它
    猜你喜欢
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    相关资源
    最近更新 更多