【问题标题】:changing a static variable at runtime在运行时更改静态变量
【发布时间】:2013-05-30 15:37:27
【问题描述】:

这是一个具体的问题,但我还是发布了它......

我无法在运行时更改静态变量。我的问题是我无法在运行时更改列表视图中的行数。它适用于下面的代码,但这个列表现在是静态的。如果用户想要添加或删除一项,此示例中的列表仍然有 5 行。

这些是与节中的项目有关的脚本行:

#include "pebble_os.h"
#include "pebble_app.h"
#include "pebble_fonts.h"
#include "settings.h"

static Window window;
static SimpleMenuLayer menu_layer;
static SimpleMenuSection menu_sections[1];
static SimpleMenuItem menu_section0_items[5];

[..]

void init_settings_window()

[..]

    menu_sections[0] = (SimpleMenuSection) {
        .title = "Things to buy...",
        .items = menu_section0_items,
        .num_items = ARRAY_LENGTH(menu_section0_items)
    };

API 参考中 SimpleMenuSection 的定义:

struct SimpleMenuSection
Data structure containing the information of a menu section.

Data Fields
const SimpleMenuItem *   items   Array of items in the section.
uint32_t     num_items   Number of items in the .items array.
const char *     title   Title of the section. Optional, leave NULL if unused.

【问题讨论】:

  • 我不明白,什么你想在运行时改变什么?
  • 我很难解释清楚,抱歉。但我解决了它(希望如此)。在静态 SimpleMenuItem menu_section0_items[5];我可以在一个部分中设置最大项目。在这一行 .items = menu_section0_items 我用一个 uint32_t 变量交换了 menu_section0_items。现在它起作用了。也许最好删除这个问题:(

标签: c pebble-watch


【解决方案1】:

更好的解决方案(我认为)是将所有MenuLayer 回调设置为函数,并在项目更改时调用menu_layer_reload_data()。如果行数在运行时会发生变化,尤其是如果您可能最终得到多个具有相同回调行为的部分或行,则为每个部分设置显式回调并不是最佳解决方案。另外,如果您有很多行和/或部分,您的代码可能会变得非常混乱。除非您要为每一行或每一节应用不同的回调,否则回调应该设置一次,在一个地方为所有行设置。

SimpleMenu 示例主要是为非动态菜单设计的。您应该查看来自demos/feature_menu_layer 的演示,而不是了解如何按预期拉出动态菜单。更好的解决方案 (IMO) 是为整个 MenuLayer 设置回调(而不是使用 SimpleMenuLayer

我会做更多这样的事情:

MenuLayer menu_layer;
uint16_t menu_get_num_sections_callback( MenuLayer *me, void *data )
{
    return 1; // for now, there is only ever 1 section
}

uint16_t menu_get_num_rows_callback(MenuLayer *me, uint16_t section_index, void *data)
{
    return my_var_that_holds_current_row_count;
}

int16_t menu_get_header_height_callback( MenuLayer *me, uint16_t section_index, void *data )
{
    return MENU_CELL_BASIC_HEADER_HEIGHT;
}

void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, uint16_t section_index, void *data)
{
    menu_cell_basic_header_draw( ctx, cell_layer, "Things to buy..." );
}

void menu_draw_row_callback( GContext* ctx, const Layer *cell_layer, MenuIndex *cell_index, void *data )
{
    switch( cell_index->row )
    {
        // Fill in row content here
    }
}

void window_load( Window *me )
{
    // ... other window code here
    // Set all the callbacks for the menu layer
    menu_layer_set_callbacks( &menu_layer, NULL, (MenuLayerCallbacks )
    {
        .get_num_sections = menu_get_num_sections_callback,
        .get_num_rows = menu_get_num_rows_callback,
        .get_header_height = menu_get_header_height_callback,
        .get_cell_height = menu_get_cell_height_callback,
        .draw_header = menu_draw_header_callback,
        .draw_row = menu_draw_row_callback,

    });
}

如果采用这种方法,刷新菜单所需要做的就是:

  1. 更新保存行数的变量
  2. 更新保存行/单元格内容的变量
  3. 致电menu_layer_reload_data( menu_layer )

SimpleMenuLayer 方法相比,此方法所需的设置更少,消除了在整个菜单中对相似/相同函数的重复调用(随着应用程序的增长而变得容易出错),使代码更易于阅读和理解,并且更内联了解其他 API/SDK 如何实现相同的目标。

我还认为 Pebble 的人们打算如何实现动态菜单,如果您将其与 feature_simple_menu_layer 示例进行比较,我想您会同意这是一个更清晰、更易于理解的实现动态菜单。

【讨论】:

    【解决方案2】:

    您可能需要在运行时使用可变长度数组来确定数组大小。可变长度数组是 c99 std 的一部分,可用于 gcc 编译器。

    【讨论】:

      猜你喜欢
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      • 2016-03-27
      相关资源
      最近更新 更多