2012-03-30 3 views
0

Я хотел бы легко отображать всплывающие окна по всему всему приложению. Для этого в моем Utils классе я создал этот статический метод:Правильное закрытие пользовательского диалогового окна

public static Dialog showStyledPopup(Context context, String sHeader, String sMessage, 
      String sBtn0Text, View.OnClickListener onClick0, 
      String sBtn1Text, View.OnClickListener onClick1, 
      String sBtn2Text, View.OnClickListener onClick2) 
    { 
     Dialog dialog = new Dialog(context, R.style.dialog_style_no_bg); 
     dialog.setContentView(R.layout.popup); 
     dialog.setCancelable(false); 
     TextView txtHeader = (TextView)dialog.findViewById(R.id.txt_popup_header); 
     if (null == sHeader) 
     { 
      txtHeader.setVisibility(View.GONE); 
     } 
     else 
     { 
      txtHeader.setText(sHeader); 
      txtHeader.setTypeface(App.fontHeader); 
     } 
     TextView txtMessage = (TextView)dialog.findViewById(R.id.txt_popup_message); 
     txtMessage.setText(sMessage); 
     txtMessage.setTypeface(App.fontCommon); 
     Button btn0 = (Button)dialog.findViewById(R.id.btn_popup_0); 
     btn0.setVisibility(View.VISIBLE); 
     btn0.setText(sBtn0Text); 
     btn0.setTypeface(App.fontCommon); 
     btn0.setOnClickListener(onClick0); 
     if (null != onClick1) 
     { 
      Button btn1 = (Button)dialog.findViewById(R.id.btn_popup_1); 
      btn1.setVisibility(View.VISIBLE); 
      btn1.setText(sBtn1Text); 
      btn1.setTypeface(App.fontCommon); 
      btn1.setOnClickListener(onClick1); 
     } 
     if (null != onClick2) 
     { 
      Button btn2 = (Button)dialog.findViewById(R.id.btn_popup_2); 
      btn2.setVisibility(View.VISIBLE); 
      btn2.setText(sBtn2Text); 
      btn2.setTypeface(App.fontCommon); 
      btn2.setOnClickListener(onClick2); 
     } 
     dialog.show(); 
     return dialog; 
    } 

popup.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="250dp" 
    android:layout_height="170dp" 
    android:background="@drawable/dialog_250_170" 
    android:gravity="center_horizontal" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/txt_popup_header" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="15dp" 
     android:textColor="@android:color/black" 
     android:textSize="20dp" /> 

    <LinearLayout 
     android:id="@+id/group_popup_btns" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_alignParentBottom="true" 
     android:layout_marginBottom="10dp" 
     android:orientation="horizontal" 
     android:baselineAligned="false" > 

     <Button 
      android:id="@+id/btn_popup_0" 
      android:layout_width="60dp" 
      android:layout_height="40dp" 
      android:background="@drawable/btn_60_40" 
      android:textColor="@android:color/black" 
      android:textSize="20dp" /> 

     <Button 
      android:id="@+id/btn_popup_1" 
      android:layout_width="60dp" 
      android:layout_height="40dp" 
      android:layout_marginLeft="5dp" 
      android:background="@drawable/btn_60_40" 
      android:textColor="@android:color/black" 
      android:textSize="20dp" 
      android:visibility="gone" /> 

     <Button 
      android:id="@+id/btn_popup_2" 
      android:layout_width="60dp" 
      android:layout_height="40dp" 
      android:layout_marginLeft="5dp" 
      android:background="@drawable/btn_60_40" 
      android:textColor="@android:color/black" 
      android:textSize="20dp" 
      android:visibility="gone" /> 
    </LinearLayout> 
    <RelativeLayout 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_above="@id/group_popup_btns" 
     android:layout_below="@id/txt_popup_header" 
     android:layout_marginLeft="20dp" 
     android:layout_marginRight="20dp" > 
     <ScrollView 
      android:id="@+id/scroll_popup" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_centerVertical="true" 
      > 
      <LinearLayout 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:orientation="vertical" > 

       <TextView 
        android:id="@+id/txt_popup_message" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_margin="10dp" 
        android:textColor="@android:color/black" 
        android:textSize="18dp" /> 
      </LinearLayout> 
     </ScrollView> 
    </RelativeLayout> 
</RelativeLayout> 

в styles.xml:

<style name="dialog_style_no_bg" parent="@android:style/Theme.Dialog"> 
     <item name="android:windowNoTitle">true</item> 
     <item name="android:windowBackground">@android:color/transparent</item> 
    </style> 

Вызывающий, как предполагается, чтобы передать View.OnClickListeners. Чтобы иметь возможность закрыть диалог, вызывающий абонент должен иметь Dialog dialog поле, которое затем используется в OnClickListener, чтобы закрыть диалоговое окно, например:

this.dialog = Utils.showStyledPopup(this, null, getString(R.string.STR_ENABLE_SOUND_AND_MUSIC_Q), 
        getString(R.string.STR_YES), new View.OnClickListener() 
        { 
         @Override 
         public void onClick(View v) 
         { 
          doToggleSound(); 
          doToggleMusic(); 
          dialog.dismiss(); 
          dialog = null; 
         } 
        }, getString(R.string.STR_NO), new View.OnClickListener() 
        { 
         @Override 
         public void onClick(View v) 
         { 
          dialog.dismiss(); 
          dialog = null; 
         } 
        }); 

Проблема заключается в том, что по какой-то причине в редких случаях поле диалога становится сброс, пока всплывающее окно все еще отображается. Я не могу воспроизвести это, но получил несколько отчетов о сбоях из-за этого в поле.

Кто-нибудь пытался сделать то же самое?

Активность имеет ориентацию, ориентированную на ландшафт, поэтому onCreate никогда не должен называться промежуточным для сброса dialog переменной.

мне не нравится идея сохранения ссылки на диалог, но нет никакого способа использовать final переменные в этом случае, так как он получает значение после оно должно быть передано в OnClickListener.

Мой вопрос похож на Android close custom dialog, но проблема там также не решена, по крайней мере, так как я хочу ее (как 1 метод в Utils).

Я видел onCreate() называют на DellStreak устройства в странные времена, так что это может быть только некоторые устройства конкретный вопрос (PMP5080BRU)

+0

Зачем вам это делать, а не просто расширять класс диалога? – you786

ответ

1

Решение было бы объявить Dialog dialog как класс поле, объявить его в классе уровень.

EDIT
Попробуйте это решение. Поместите диалоговое окно как поле класса в класс Utils. Не возвращайте объект диалога из метода, а используйте его для инициализации диалоговой переменной. Использование метода getter (или попытка прямого доступа, если не рекомендуется) диалоговой переменной. Это своего рода грязное решение, но оно может сработать и для вас.

+0

PS: Проблема в другом вопросе была решена, апрашивающий использовал диалог, а не диалог для отклонения. – noob

+0

Я думаю, это именно то, что я делаю: this.dialog = ... это поле класса. Но проблема в том, что она иногда сбрасывается! – iseeall

+0

Так что же такое исключение? Если он сбрасывается, тогда он должен выбрасывать исключение NullPointerException. Также вам нужно сделать диалог не отмененным? – noob

Смежные вопросы