Статьи

Как создавать Android-диалоги в режиме многократного использования

дроид-человек Создание диалогов — это очень распространенная потребность в вашем приложении, чтобы показать пользователю диалоговое окно для получения значения, будь то в мобильном, настольном или даже веб-приложении. Кроме того, значения могут варьироваться от чего-либо, например, простых результатов диалога OK-Cancel, до списка «проверяемых» значений или даже диапазона дат. У меня возникла необходимость создать диалоговое окно для Android для отображения отчетов в недавнем проекте приложения для Android. Хотя Java-API предлагает максимальную гибкость в создании элементов интерфейса диалога, нет готового метода, который можно было бы вызвать, чтобы получить, скажем, результат для сообщения-диалога, подобного этому:

1
result = MessageBox.Show();

Другие языки, такие как C # и VB, предоставляют такие методы для отображения модальных диалоговых окон, которые возвращают значения после ожидания модального диалога. Но, к сожалению, в Android нет понятия «модальный». Поток не может просто сидеть без дела в ожидании ввода, так как ресурсы слишком ценны для этого. Вместо этого существует концепция обратных вызовов, так что вместо того, чтобы ждать, пока диалоговое окно не вернется, метод вызывает ссылку на функцию, которую вы передали:

1
2
3
4
5
6
AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setTitle("Milk supply tracker");
builder.setMessage(message);
builder.setPositiveButton("Yes",listener);
builder.setNegativeButton("No",listener);
builder.create().show();

Здесь слушатель ссылается на функцию, которая будет вызываться при нажатии кнопки «Да» или «Нет». Это не только усложняет ваш код, но и очень затрудняет повторное использование кода для обработки различных ситуаций, таких как получение выбора из диапазона значений или получение диапазона даты / времени. Чтобы решить эту проблему, я создал отдельный класс Java под названием Dialog и добавил варианты методов ShowDialog () для обработки каждого типа диалога:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Dialog
{
    public static void ShowMessageDialog(Context context, String message)
    {
        ShowDialog(context,message,MessageBoxType.OKOnly,new String[]{},false, null,null);
    }
  
    public static void ShowMessageDialog(Context context, String message, MessageBoxType type , OnClickListener listener)
     {
         ShowDialog(context,message,type,new String[]{},false, listener,null);
     }
  
    public static void ShowListDialog(Context context, String message, String[] listItems, boolean isMultiChoice, OnClickListener listener)
     {
     if (isMultiChoice)
         ShowDialog(context, message, MessageBoxType.OkCancel , listItems, isMultiChoice, listener,null);
     else
         ShowDialog(context, message, MessageBoxType.OKOnly , listItems, isMultiChoice, null,listener);
     }
  
    public static void ShowDateDialog(Context context,String message,OnDateSetListener listener)
    {
        Calendar c=Calendar.getInstance();
        int y=c.get(Calendar.YEAR);
        int m=c.get(Calendar.MONTH);
        int d=c.get(Calendar.DAY_OF_MONTH);
  
        DatePickerDialog dlg=new DatePickerDialog(context, listener, y, m, d);
        dlg.setTitle(message);
        dlg.show();
    }
  
}

Как видите, ShowMessageDialog () принимает разные параметры в зависимости от того, требуется ли прослушиватель или нет. ShowListDialog (), с другой стороны, передает массив строк для создания диалога, отображающего список значений, из которых пользователь может выбирать. Параметр isMultiChoice указывает, требуется ли флажок для каждого значения в списке выбора. Все это на самом деле реализовано в закрытом методе ShowDialog (), тогда как ShowDateDialog () имеет собственную реализацию. Вот источник для ShowDialog ():

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
private static void ShowDialog(Context context, String message, MessageBoxType type , String[] listItems, boolean isMultiChoice, OnClickListener listener,OnClickListener selectedItemListener)
{
    AlertDialog.Builder builder=new AlertDialog.Builder(context);
  
    if (listItems.length>0 && isMultiChoice==false)
    {
        CheckedItems=new ArrayList();//won't be used in this case.
        builder.setTitle(message);
  
        builder.setItems(listItems, selectedItemListener);
    }
    else if (listItems.length>0 && isMultiChoice==true)
    {
        CheckedItems=new ArrayList();
        builder.setTitle(message);
  
        builder.setMultiChoiceItems(listItems, null, new OnMultiChoiceClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean checked)
            {
                if (checked)
                    CheckedItems.add(which);
                else
                {
                    if (CheckedItems.contains(which))
                        CheckedItems.remove(which);
                }
            }
        });
    }
    else
    {
        builder.setTitle("Milk supply tracker");
        builder.setMessage(message);
    }
  
    if (listItems.length==0 || isMultiChoice)
    {
        switch(type)
        {
        case OKOnly:
            builder.setPositiveButton("OK",listener);
            break;
        case OkCancel:
            builder.setPositiveButton("OK",listener);
            builder.setNegativeButton("Cancel",listener);
            break;
        case YesNo:
            builder.setPositiveButton("Yes",listener);
            builder.setNegativeButton("No",listener);
            break;
        }          
    }
  
    builder.create().show();
}

Надеюсь, этот класс должен удовлетворить все ваши потребности, связанные с отображением диалога в вашем приложении для Android. Вот рабочий пример того, как ShowListDialog () фактически вызывается с флажками:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
selItems=new String[]{"apples","oranges","grapes"};
Device.ShowListDialog(this,"Select a fruit" ,this.selItems, true, new DialogInterface.OnClickListener() {
  
        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            if (which==DialogInterface.BUTTON_POSITIVE)
            {
                for(int i:Device.CheckedItems)
                Dialog.ShowMessageDialog(ReportsActivity.this, "selected:" + selItems[i]);
            }
        }
    });
}