2012-03-30 6 views
0

アプリケーション全体にカスタムスタイルのポップアップを簡単に表示したいと思います。呼び出し側が渡すことになっているカスタムダイアログを正しく閉じる

<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> 

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:のstyles.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> 

は、そのために私のUtilsクラスで私はこの静的メソッドを作成しましたView.OnClickListeners。

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; 
         } 
        }); 

問題がまれに何らかの理由でダイアログフィールドが取得することです: ダイアログを閉じできるようにするには、呼び出し側は、例えば、ダイアログを閉じOnClickListenerに使用されているDialog dialogフィールドを、持っている必要がありますポップアップが表示されている間にリセットします。私はこれを再現することはできませんが、現場でこれが原因でいくつかのクラッシュレポートがあります。

誰かが同じことを試みましたか?

アクティビティは横向きに固定されているため、onCreateは、dialogの変数をリセットするために中間から呼び出されるべきではありません。

は、私は、ダイアログへの参照を格納する考えを好きではないが、それはそれはOnClickListenerに渡されるべき後の値を取得しますので、この場合にはfinal変数を使用する方法は、単に存在しません。

私の質問はAndroid close custom dialogに似ていますが、少なくとも私が望むように(Utilsでは1つの方法として)解決されていないという問題もあります。私はonCreate()を見てきました

は変なタイミングでDellStreakデバイス上に呼び出されて、これはほんの一部のデバイス固有の問題(PMP5080BRU)かもしれません

+0

なぜ、ダイアログクラスを拡張するのではなく、これを行うのですか? – you786

答えて

1

ソリューションは、クラスのフィールドとしてDialog dialogを宣言したクラスでそれを宣言するだろうレベル。

編集
この解決方法もお試しください。 Utilsクラスのクラスフィールドとしてダイアログを持ちます。ダイアログオブジェクトをメソッドから戻さず、ダイアログ変数を初期化するために使用します。ダイアログ変数のgetterメソッドを使用するか(または推奨されませんが、直接アクセスしてみてください)。これはちょっと汚い解決策ですが、それもあなたのために働くかもしれません。

+0

PS:別の問題の問題が解決しました。質問者はダイアログを消すためにダイアログの代わりにダイアログを使用していました。 – noob

+0

私はこれがまさに私がやっていることだと思います:this.dialog = ...はクラスフィールドです。しかし、問題はそれが時々リセットされることです! – iseeall

+0

例外は何ですか?それがリセットされた場合は、NullPointerExceptionをスローする必要があります。また、ダイアログをキャンセルできないようにする必要がありますか? – noob