0

これは特定の質問ですが、とにかく投稿します...

実行時に静的変数を変更できません。私の問題は、実行時にリスト ビューの行数を変更できないことです。以下のコードで動作しますが、このリストは現在静的です。ユーザーが 1 つの項目を追加または削除したい場合、この例のリストにはまだ 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.
4

2 に答える 2

1

より良い解決策 (私が思うに) は、すべてのMenuLayerコールバックを関数に設定しmenu_layer_reload_data()、項目が変更されたときに呼び出すことです。実行時に行数が変更される場合、特に同じコールバック動作を持つ複数のセクションまたは行になる可能性がある場合は、セクションごとに明示的なコールバックを設定することは最善の解決策ではありません。さらに、多くの行やセクションがある場合、コードがかなり厄介になる可能性があります。適用するコールバックが行またはセクションごとに異なる場合を除き、コールバックはすべての行に対して 1 か所で 1 回設定する必要があります。

この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 に答える