Порадьте, як виправити помилку в droidScript?

💡 Усі статті, обговорення, новини про Mobile — в одному місці. Приєднуйтесь до Mobile спільноти!

Вітаю, спільното! Я працюю над власним проєктом (оболонкою в стилі Android 1.0 на DroidScript) і зіткнувся з дуже дивною проблемою.

Суть в тому, що при кліку на будь-яку іконку на робочому столі, спрацьовує обробник, але він завжди виводить мітку лише для останньої іконки в масиві («All apps»).

Я вже спробував кілька стандартних методів для вирішення цієї проблеми з областю видимості (closure), включаючи використання `Function.prototype.bind()` та створення окремих функцій в циклі, але результат не змінився.

Деталі:

— Фреймворк:DroidScript.

— Проблема: Обробник `SetOnTouch` завжди отримує дані лише від останньої іконки, створеної в циклі.

— Код:

[Тут вставте ваш код, який демонструє проблему. Це найважливіша частина!]// Глобальні константи для конфігурації сітки
const ICONS_PER_ROW = 4;
const ICON_MARGIN = 0.05; // Відступ між іконками у відсотках від ширини екрану
/**
 * Створює сітку робочого столу за допомогою Linear макетів.
 * Додає відступи та центрує іконки в рядах.
 * @param {object} mainLayout - Головний вертикальний макет, до якого додаються рядки.
 * @param {Array<object>} icons - Масив об'єктів-іконок.
 */
function createLinearGrid(mainLayout, icons) {
    let rowLayout;
    for (let i = 0; i < icons.length; i++) {
        // ВИПРАВЛЕНО: Створення константи всередині циклу 'for'
        // яка фіксує дані для цієї ітерації.
        const iconData = icons[i];
        if (i % ICONS_PER_ROW === 0) {
            rowLayout = app.CreateLayout("Linear", "Horizontal,FillX,Center");
            rowLayout.SetPadding(0, ICON_MARGIN, 0, ICON_MARGIN);
            mainLayout.AddChild(rowLayout);
        }
        let iconLayout = app.CreateLayout("Linear", "Vertical,Center");
        iconLayout.SetPadding(ICON_MARGIN, 0, ICON_MARGIN, 0);
        let icon = app.CreateImage(iconData.path, 0.15); 
        
        // ВИПРАВЛЕНО: Визначаємо обробник кліку безпосередньо тут.
        // Це створює унікальний "захищений" простір для iconData.
        icon.SetOnTouch(function() {
            handleIconClick(iconData.label);
        });
        
        let text = app.CreateText(iconData.label);
        text.SetTextSize(15);
        text.SetTextColor("#FFFFFF");
        iconLayout.AddChild(icon);
        iconLayout.AddChild(text);
        
        rowLayout.AddChild(iconLayout);
    }
}
/**
 * Кастомна функція-обробник кліків по іконках.
 * Тут ви можете реалізувати будь-яку логіку.
 * @param {string} label - Назва іконки.
 */
function handleIconClick(label) {
    app.ShowPopup("Натиснуто іконку: " + label);
}
// Функція, що виконується при старті додатку
function OnStart() {
    let mainLayout = app.CreateLayout("Linear", "Vertical,FillXY");
    mainLayout.SetBackColor("#333333");
    // ВИПРАВЛЕНО: Видалено властивість 'appName'
    let appIcons = [
        {label: "Phone", path: "Img/app_phone.png"},
        {label: "Contacts", path: "Img/app_contacts.png"},
        {label: "Maps", path: "Img/app_maps.png"},
        {label: "Browser", path: "Img/app_web_browser.png"},
        {label: "All apps", path: "Img/app_all_apps.png"},
    ];
    
    create
LinearGrid(mainLayout, appIcons);
    app.AddLayout(mainLayout);
}

Що вже зроблено:

— Спроби використовувати `bind(null, label)`.

— Створення анонімної функції `function() { handle(label) }` в циклі.

— Зберігання даних через `icon.SetData("label", ...)` і отримання їх через `source.GetData()`.

— Використання `icon.SetId()` та перевірка через `switch/case`.

Чи стикався хтось із вас з подібною поведінкою в DroidScript? Можливо, існує якийсь специфічний механізм для обробки подій, який я не врахував? Буду вдячний за будь-які ідеї, які допоможуть мені вирішити цю головоломку!

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі