стиль программирования с модальным диалогом

#android #coding-style

#Android #стиль кодирования

Вопрос:

в моем приложении для Android на каком-то мероприятии в activity я хочу запросить у пользователя имя (строку). Я знаю, как это сделать: вызвать ShowDialog, создать диалоговое окно в методе Activity.onCreateDialog (мне нужно указать строку для метки) и обработать результат одним щелчком мыши в диалоговом окне. Это работает нормально и к моему удовлетворению.
НО таким образом у меня есть три разных места, где эта простая задача распространяется по всему коду моей деятельности. Я бы гораздо больше предпочел сохранить этот код вместе, написать какой-нибудь код, подобный этому:

 string resu<
if (showSimpleEditDialog(idForLabelString, result)==DIALOG_OK)
{
    // do something with the result
}
  

или, может быть, с экземпляром класса

 SimpleEditDialog dlg = new SimpleEditDialog(idForLabelString);
if (dlg.showModal()==DIALOG_OK)
{
    string result = dgl.getResult();
    // do something with the result
}
  

(«idForLabelString» будет некоторым идентификатором ресурса для используемой метки, DIALOG_OK будет некоторой константой, возвращаемой, когда пользователь нажимает OK)
Я знаю, мне пришлось бы написать эти методы или этот класс. Но для лучшей читаемости моего кода я бы сделал это. Есть предложения?
Спасибо,

Герхард

Комментарии:

1. пожалуйста, воздержитесь от использования тегов в вашем названии — для этого они и предназначены.

Ответ №1:

«НО таким образом у меня есть три разных места, где эта простая задача распространяется по всему коду»

Так почему бы вам не создать метод для этой задачи? То, о чем вы говорите, звучит для меня как какой-то ActionListener. Это можно сделать на Java / Swing, но не на Android.

Но, если у вас есть три диалоговых окна, которые все должны выполнять одно и то же при нажатии «ДА», например, «НЕТ», вы могли бы определить ‘DialogInterface.OnClickListener()’ как глобальный внутренний класс (или во втором классе, который расширяет ‘OnClickListener’), а затем использовать его для всех диалоговых окон.

Ответ №2:

На самом деле проблема с модальными диалогами в основном связана с потоком программирования. Вы хотите сохранить вещи, которые принадлежат друг другу. Вы хотите отобразить диалоговое окно, которое возвращает «ok» или «cancel» и дополнительно, например, строку, которую пользователь ввел в один из диалоговых виджетов.

Я не хочу писать половину кода до строки, где мне нужен результат диалога в одном месте, а остальной код в другом месте, а именно OnClickListener диалогового окна.

В некоторых сценариях первое диалоговое окно может вызывать второе диалоговое окно, например, для указания цвета, которого нет в списке ListView первого диалогового окна.

Ваш код будет разбросан повсюду (в кнопке OnClickListener каждого диалогового окна), и его будет трудно читать или поддерживать.

Теперь, после написания некоторого неясного кода, подобного этому, я придумал следующее решение, которое, безусловно, соответствует руководствам по дизайну Android.

Вместо прямого отображения диалогового окна я создаю производный класс-обработчик, который обрабатывает сообщения.

Я отправляю ему первое сообщение, которое создает и показывает диалоговое окно. Он также перенаправляет обработчик в диалоговое окно, а diaolg в его методе onStop отправляет обработчику другое сообщение, указывающее на завершение диалога. Там вы можете изучить свойства диалогов, содержимое полей редактирования или то, было ли оно остановлено с помощью OK или CANCEL. Теперь в обработчике сообщений вся логика задачи находится в разных случаях значения arg1 сообщений.

Некоторые случаи могут быть пропущены (например, пользователь выбрал стандартный цвет и не нуждался в специальном диалоговом окне цвета).

Диалоги не зависят от сценария, из которого они вызываются, и в их коде отражается только их простая задача (выбор из списка, некоторые флажки и т.д.). Они могут быть повторно использованы из других сценариев.

Следуя своего рода шаблону, как использовать этот подход:

 public class DoSomethingWithDialogs extends Handler
{
Context context; // from which it was called
final static int stepBegin = 0;
final static int stepNext = 1;
final static int stepSomethingElse = 2;
final static int stepLast = 3;

protected DoSomethingWithDialogs(Context context)
{   
    this.context = context;
}

public static void start(Context context)
{   // this is the main (only) entry point from outside
    DoSomethingWithDialogs st = new DoSomethingWithDialogs(context);
    st.sendMessage(st.obtainMessage(0, stepBegin, 0));
}

@Override
public void handleMessage(Message msg)
{
    // step by step handling the task
    switch (msg.arg1)
    {
    case stepBegin:
    {
        SomeDlg somedlg = new SomeDlg(context, this, stepNext);
       // when the dialog closes, it sends a message to this with stepNext as arg1
        somedlg.show();
    }
        break;
    case stepNext:
    {   // this message was send by the dialog when it finished
        SomeDlg somedlg = (SomeDlg) msg.obj;
        if (msg.arg2 == Dialog.BUTTON_NEGATIVE)
        {
            // has been canceled, nothing to do
        } else
        {
            if (somedlg.someProperty)
            {

            } else
            {
                sendMessage(obtainMessage(0, stepSomethingElse, 0));
            }
        }
    }
        break;
    case stepSomethingElse:
        break;
    }
}
  

}