【问题标题】:Android - Design trouble - Should I use setTag to hold information for OnClick event?Android - 设计问题 - 我应该使用 setTag 来保存 OnClick 事件的信息吗?
【发布时间】:2015-10-06 04:54:56
【问题描述】:

作为 Android 课程的一部分,我正在做一个小项目。 该应用程序应该使用某些站点的 API 检索最受欢迎的电影,然后将它们显示在网格视图中(使用海报作为缩略图)。 当点击特定电影时,将启动一个新的活动来提供详细信息。

我已经走到这一步了:

  1. 使用网站的 API 获得了最受欢迎的电影海报图片 URL 列表。
  2. 实现了一个扩展 ArrayAdapter 的适配器,它接受 ArrayList 作为数据源并将图像从 URL 加载到 ImageView 项中。
  3. 使用适配器填充 GridView。
  4. 使用以下代码在 Gridview 上设置监听器:

s:

gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
    //do stuff according to position/view
}

点击电影时我需要传递给电影详细信息活动的信息可以在步骤 1 中获得(我刚刚从 json 中提取了海报 URL)。 为了能够在单击视图时提供信息,我需要(至少)还提取电影的 ID 并存储它。

看来我的选择是:

  1. 将 ID 存储在适配器中。然后,当点击发生时,使用 getItem(position) 获取 ID 并将其与意图一起发送。然后,下一个活动必须向服务器查询电影详细信息。

这意味着创建一个类:

static class MovieItem {
   int Id;
   string posterUrl;
}

并将适配器转换为使用ArrayList&lt;MovieItem&gt;

  1. 与选项 1 相同,但使用 setTag 存储电影的 Id。
  2. 与选项 1 相同,但获取所有必需的信息(标题、评级、情节等)并将其存储到 MovieItem。下一个活动不需要查询。
  3. 与选项 3 相同,但使用 setTag (MovieItem)。下一个活动不需要查询。

我是应用程序开发的新手,我正在努力以正确的方式完成工作,不胜感激。

编辑: 还想补充一点,如果我在适配器中存储了额外的电影信息,那是否不合适,因为这些信息与该类无关?

感谢您的麻烦! :)

【问题讨论】:

    标签: java android gridview


    【解决方案1】:

    当您第一次请求电影信息列表时,您可以将每部电影的详细信息存储在 HashMap&lt;String, HashMap&lt;String, String&gt;&gt; 之类的东西中,其中 String 是电影 ID,而 Map 是一组键/值对以获取详细信息信息。然后,当点击您的 onClick 时,您将使用该位置来确定点击了哪个电影海报。然后,您将检索所选电影的详细信息 HashMap,将其放入 Bundle,将其传递给新 Activity 的 Intent,然后在另一端检索它。所以代码看起来像这样:

    当您第一次检索电影列表时,您会执行以下操作:

    //You would put each set of movie data into a HashMap like this...
    HashMap<String, HashMap<String, String>> movies = new HashMap<>();
    
    HashMap<String, String> details = new HashMap<>();
    details.put("dateReleased", "7.12.2015");
    details.put("rating", "PG-13");
    details.put("title", "Cool Awesome Movie");
    movies.put("12345", details);
    
    //Then when an onClick comes in, you would get the set of 
    //details for the movie that was selected (based on position)
    HashMap<String, String> selectedDetails = movies.get("12345");
    
    //Put the retrieved HashMap of details into a Bundle
    Bundle bundle = new Bundle();
    bundle.putSerializable("movieDetails", selectedDetails);
    
    //Send the bundle over to the new Activity with the intent
    Intent intent = new Intent(this, YourDetailsActivity.class);
    intent.putExtras(bundle);
    startActivity(intent);
    

    然后,当新的 Activity 启动时,您将在 onCreate() 中从 Bundle 中检索详细信息:

     //Then in onCreate() of the new Activity...
     Bundle bundle = getIntent().getExtras();
     HashMap<String, String> movieDetails = (HashMap<String, String>) bundle.getSerializable("movieDetails");
     String dateReleased = movieDetails.get("dateReleased");
     String rating = movieDetails.get("rating");
     String title = movieDetails.get("title");
    

    【讨论】:

    • 感谢您的回答!这看起来确实是一个不错的选择,但我想知道如果我使用了 setTag 会不会是对它的滥用?
    • 还想补充一点,如果我在适配器中存储了额外的电影信息,那是否不合适,因为这些信息与该类无关?抱歉,如果我很麻烦,但我正在寻找答案,而不仅仅是“这样做”。谢谢你:)
    • 当您说要使用 setTag() 时,我假设您的意思是 ImageView 的 setTag()?您当然可以使用它来存储 id,然后按照您提到的意图传递它。但!这也意味着您必须发出两个 url 请求,而不是一个。如果您有少量数据(例如,大约 10 部电影的列表),我可能会选择一次下载所有数据,然后使用存储的数据创建详细活动。如果您喜欢 100 部电影,那么每次点击获取详细信息可能会更好。
    • 关于在 ArrayAdapter 中做所有这些事情的问题,这确实是您必须根据自己的喜好做出的决定。您当然可以在适配器本身内完成所有这些工作,但我会说大多数开发人员都希望将这些服务器请求放在他们自己的类中(我知道我会的)。通常最好的做法是让您的类和方法尽可能小且集中。在维护自己的代码和跟踪问题时,这始终是更好的选择。
    • 抱歉,如果之前不清楚,我的意思是 ImageView.setTag()。我不打算在适配器中执行服务器请求,而只是在设置/更新数据时存储附加信息。请求本身是在它之外完成的。至于您的解决方案,我刚刚意识到我无法使用位置来点击电影,因为外部 HashMap 的键是实际的电影 id,其中位置是索引。所以无论哪种方式,我都必须使用 setTag 或数组存储它并使用位置作为索引。无论如何,非常感谢你的帮助,我想我从现在开始就知道了
    猜你喜欢
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多