0

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

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

2 回答 2

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示例进行比较,我想您会同意这是一个更清晰、更易于理解的动态菜单实现。

于 2013-09-12T20:49:06.557 回答
0

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

于 2013-05-30T15:45:33.537 回答