1. 程式人生 > >Android 4.0設定Dialog點選螢幕不消失

Android 4.0設定Dialog點選螢幕不消失

業務的需求是變化莫測的,最近就遇到一個需求是——使用者只有點選Dialog的取消按鈕才會消失,點選螢幕的時候不消失。Android ICS對UI做了很大的變動,系統提倡使用DialogFragment,但是系統預設的操作習慣是點選螢幕Dialog會自動消失。

為了實現業務的需求,想過使用Dialog風格的Activity,但是做出來的效果和系統的UI效果不匹配,最終只有失敗告終。在黔驢技窮的時候,決定再仔細擼一下Android文件,終於在文件中發現了Dialog的setCanceledOnTouchOutside屬性,具體使用如下:

方法一:

public class MyAlertDialogFragment extends DialogFragment {

    public static MyAlertDialogFragment newInstance(int title) {
        MyAlertDialogFragment frag = new MyAlertDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        frag.setArguments(args);
        return frag;
    }

    @TargetApi(11)
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        
        AlertDialog dialog = new AlertDialog.Builder(getActivity())
        .setIcon(R.drawable.ic_launcher)
        
        .setTitle(title)
        .setPositiveButton(R.string.alert_dialog_ok,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    ((MainActivity)getActivity()).doPositiveClick();
                }
            }
        )
        .setNegativeButton(R.string.alert_dialog_cancel,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    ((MainActivity)getActivity()).doNegativeClick();
                }
            }
        )
        .create();
        dialog.setCanceledOnTouchOutside(false);// 設定點選螢幕Dialog不消失
        
        return dialog;
    }
}

方法二:

在oncreate()方法中設定Dialog點選螢幕不可取消,例項程式碼如下:

   @Override    
    public void onCreate(Bundle icicle)
    {
    	super.onCreate(icicle);
    	this.setCancelable(false);// 設定點選螢幕Dialog不消失
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        setStyle(style,theme);
    }

(提示:提醒大家一下在覆寫了onCreateDialog()方法後,就不能覆寫onCreateView()方法了)

說到這兒就給大家介紹一下建立DialogFragment的第二種方式吧,第一種方式上面已經敘述了,在此就不再敘述了,直接看第二種實現的具體方式,具體程式碼如下所示:

import android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class PromptDialogFragment 
extends DialogFragment 
implements View.OnClickListener
{
	private EditText et;

	public static PromptDialogFragment
	newInstance(String prompt)
	{
		PromptDialogFragment pdf = new PromptDialogFragment();
		Bundle bundle = new Bundle();
		bundle.putString("prompt",prompt);
		pdf.setArguments(bundle);
		
		return pdf;
	}

	@Override
	public void onAttach(Activity act) {
		// If the activity we're being attached to has
		// not implemented the OnDialogDoneListener
		// interface, the following line will throw a
		// ClassCastException. This is the earliest we
		// can test if we have a well-behaved activity.
		OnDialogDoneListener test = (OnDialogDoneListener)act;
		super.onAttach(act);
	}

    @Override    
    public void onCreate(Bundle icicle)
    {
    	super.onCreate(icicle);
    	this.setCancelable(true);
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        setStyle(style,theme);
    }
    //  覆寫onCreateView()方法,實現DialogFragment的佈局。注意不能同時覆寫 onCreateView()和onCreateDialog()方法
    public View onCreateView(LayoutInflater inflater,            
    		ViewGroup container, 
    		Bundle icicle)
    {
        View v = inflater.inflate(
        		R.layout.prompt_dialog, container, false);

        TextView tv = (TextView)v.findViewById(
        		                   R.id.promptmessage);
        tv.setText(getArguments().getString("prompt"));

        Button dismissBtn = (Button)v.findViewById(
        		                       R.id.btn_dismiss);
        dismissBtn.setOnClickListener(this);

        Button saveBtn = (Button)v.findViewById(
        		                    R.id.btn_save);
        saveBtn.setOnClickListener(this);

        Button helpBtn = (Button)v.findViewById(
                R.id.btn_help);
        helpBtn.setOnClickListener(this);

        et = (EditText)v.findViewById(R.id.inputtext);
        if(icicle != null)
            et.setText(icicle.getCharSequence("input"));
        return v;
    }

    @Override
    public void onSaveInstanceState(Bundle icicle) {
    	icicle.putCharSequence("input", et.getText());
    	super.onPause();
    }

    @Override
    public void onCancel(DialogInterface di) {
    	Log.v(MainActivity.LOGTAG, "in onCancel() of PDF");
    	super.onCancel(di);
    }

    @Override
    public void onDismiss(DialogInterface di) {
    	Log.v(MainActivity.LOGTAG, "in onDismiss() of PDF");
    	super.onDismiss(di);
    }

    public void onClick(View v) 
	{
		OnDialogDoneListener act = (OnDialogDoneListener)getActivity();
		if (v.getId() == R.id.btn_save)
		{
			TextView tv = (TextView)getView().findViewById(R.id.inputtext);
			act.onDialogDone(this.getTag(), false, tv.getText());
			dismiss();
			return;
		}
		if (v.getId() == R.id.btn_dismiss)
		{
			act.onDialogDone(this.getTag(), true, null);
			dismiss();
			return;
		}
		if (v.getId() == R.id.btn_help)
		{
			FragmentTransaction ft = getFragmentManager().beginTransaction();
		    ft.remove(this);

		    // in this case, we want to show the help text, but
		    // come back to the previous dialog when we're done
		    ft.addToBackStack(null);
		    //null represents no name for the back stack transaction

		    HelpDialogFragment hdf =
		    	    HelpDialogFragment.newInstance(R.string.help1);
		    hdf.show(ft, MainActivity.HELP_DIALOG_TAG);
		    return;
		}
	}
}

程式碼比較簡單,註釋已經寫明白了,相信大家都能看懂的! 

以上只是設定Dialog的一個小技巧以及建立DialogFragment的兩種建立方式,希望對大家有所幫助。