Typical problems caused by custom android Dialog

Source: Internet
Author: User

Typical problems caused by custom android Dialog

I am still starting from my work! Recently, you need to add the voice control camera function (voice camera) to the camera. You need to achieve the following in settings:

Its "voice camera" menu function is described as follows:

(1) When you click the "voice camera" menu, the Dialog shown in is displayed. Click "photo"/"Eggplant" in the Dialog to automatically play the sound.

(2) When Dialog appears, you only need to click a region other than Dialog, And the Dialog will automatically disappear.

(3) When you click the green switch button on the rightmost side of the "voice camera" menu, the voice camera function is enabled/disabled.

The above implementation is actually a PreferenceActivity, so the newly added "voice camera" menu is added in this PreferenceActivity (CameraSettingActivity.

First, we need to solve how to create a self-defined Dialog: In the Activity, there is a method public Dialog onCreateDialog (int dialogId), with which we can create our own Dialog, call the public final void showDialog (int id) of the Activity to display the created Dialog. here, the Activity creates and displays different Dialog based on different dialogids, and dialogId is defined by yourself! In our CameraSettingActivity, the following definition is provided:

private static final int DIALOG_ID_VOICE_COMMAND_SHOW_TONES = 111;
Then, the onCreateDialog method of the Override parent activity is used to define its own Dialog, as shown in the following code:

    @Override    public Dialog onCreateDialog(int dialogId) {    if(dialogId == DIALOG_ID_VOICE_COMMAND_SHOW_TONES){    Dialog dialog = new Dialog(this, R.style.transparent_dialog_them); dialog.setContentView(R.layout.setting_switch_sublist_layout);VoiceManager voice_manager = ((CameraApp)CameraSettingActivity.this.getApplication()).getVoiceManager();SettingSwitchSublistLayout mVoiceSettingLayout =(SettingSwitchSublistLayout) dialog.findViewById(R.id.SettingSwitchSublistLayout_ID);mVoiceSettingLayout.initialize(voice_manager.getVoiceEntryValues());mVoiceSettingLayout.setSettingChangedListener(this);//dialog.getWindow().setCloseOnTouchOutside(true);View content =(View) dialog.getWindow().getDecorView().findViewById(com.android.internal.R.id.content);content.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {dismissDialog(DIALOG_ID_VOICE_COMMAND_SHOW_TONES);            }        });return dialog;}return super.onCreateDialog(dialogId);    }
The above code is explained step by step here:

(1)

Dialog dialog = new Dialog(this, R.style.transparent_dialog_them); 
The second parameter is R. style. transparent_dialog_them, which is a topic setting parameter. The background transparency must be set here, as shown in the following code:

    
Here, I set windowBackground to transparent and the NoActionBar and NoTitle modes! Of course, here windowBackground can be set as a transparent background! Do you see anything strange here? Why is the relationship between creating a Dialog and window/action? If you read the class implementation class implemented by dialog, you will find that creating a dialog is equivalent to creating a window, and we know that a window has attributes such as action and title! By learning activity, we also know that creating an activity actually creates a window. In fact, the display of an interface originates from a window! In addition to the display on the management interface, a window starts from all input events of the device!

(2)

dialog.setContentView(R.layout.setting_switch_sublist_layout);
This line of code is actually the configuration of the displayed dialog layout! The details are very simple!

(3)

View content =(View) dialog.getWindow().getDecorView().findViewById(com.android.internal.R.id.content);content.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {dismissDialog(DIALOG_ID_VOICE_COMMAND_SHOW_TONES);            }        });
These lines of code can be implemented. When a user clicks a region other than dialog, the dialog automatically disappears!

The above is about the creation of dialog! Do you think there is a problem?

Then, let's take a look at how to achieve CLICK: When you click the "voice camera" menu, the Dialog shown in is displayed, when you click the green switch button on the rightmost side of the "voice camera" menu, the voice camera function is enabled/disabled. let's look at the following code:

        SwitchPreference voicePref =(SwitchPreference) findPreference(getString(R.string.camera_setting_item_pref_voice_key));
voicePref.setLayoutResource(R.layout.xunhu_voice_preference);//xunhu_ali_preferenceString key = getString(R.string.camera_setting_item_pref_voice_key);boolean value = getPreferenceManager().getSharedPreferences().getBoolean(key, false);//Log.d("pre_carmera", "CameraSettingActivity : initDefaultSavePath mValue="+value);VoiceManager voice_manager = ((CameraApp)this.getApplication()).getVoiceManager();String mValue = voice_manager.getVoiceValue();
From the code above, we can clearly understand that what I actually use is the SwitchPreference that we usually use. I just defined his layout! The SwitchPreference method setLayoutResource can be used to configure its own layout! So the key to solving this problem lies in the use of this layout!

In fact, this layout is no different from the default SwitchPreference layout! The following code adds the android: onClick = "VoiceCommandClickListener" attribute to the parent view of the layout:

 
  
Finally, let's take a look at the definition of VoiceCommandClickListener:

public void VoiceCommandClickListener(View v) {        showDialog(DIALOG_ID_VOICE_COMMAND_SHOW_TONES);}
In fact, showDialog is called to display my own Dialog.


After that, we will soon find two questions: (1) When we click a region other than dialog, the dialog will automatically disappear. Is there a simple solution! (2) Can we use DialogFragment to replace the Dialog here?

Solve the following question first:

View the dialog. java can find that the creation of a dialog actually creates a window for the dialog. When you use the hierarchyviewer tool to view the window, you will find that the dialog actually occupies the entire screen, it's not just that there are so many display areas! Why! This is what you will soon find. When an activity is in dialog mode, you need to configure the topic of this activity as dieme mode: Theme. dialog. as I mentioned just now, the display of a Dialog and activity is both the origin and the window, so whether the Theme is set during the creation of the Dialog. dialog can solve the problem! The actual results are indeed the same as I inferred!

Modify the above Code as follows:

    @Override    public Dialog onCreateDialog(int dialogId) {    if(dialogId == DIALOG_ID_VOICE_COMMAND_SHOW_TONES){    Dialog dialog = new Dialog(this, R.style.transparent_dialog_them); dialog.setContentView(R.layout.setting_switch_sublist_layout);VoiceManager voice_manager = ((CameraApp)CameraSettingActivity.this.getApplication()).getVoiceManager();SettingSwitchSublistLayout mVoiceSettingLayout =(SettingSwitchSublistLayout) dialog.findViewById(R.id.SettingSwitchSublistLayout_ID);mVoiceSettingLayout.initialize(voice_manager.getVoiceEntryValues());mVoiceSettingLayout.setSettingChangedListener(this);dialog.getWindow().setCloseOnTouchOutside(true);/*View content =(View) dialog.getWindow().getDecorView().findViewById(com.android.internal.R.id.content);content.setOnClickListener(new OnClickListener() {                       @Override                       public void onClick(View v) {dismissDialog(DIALOG_ID_VOICE_COMMAND_SHOW_TONES);                       }        });               */dialog.setCanceledOnTouchOutside(true);return dialog;}return super.onCreateDialog(dialogId);    }
The above code I commented on the content. setOnClickListener and added the following line of code:
dialog.getWindow().setCloseOnTouchOutside(true);
You will find that when you click a region other than dialog, the dialog cannot disappear! Is the above line of code useless! Actually, as we said just now, this dialog actually occupies the entire screen! We set the background to completely transparent! Therefore, you cannot click a region other than the dialog region! Prove that the above line of code is available! You only need to modify the theme settings! Set R. style. transparent_dialog_them to Theme. Dialog: as follows:

    
It turns out that the parent of transparent_dialog_them is Theme. HWDroid. Ali. NoActionBar. Change it to Theme. HWDroid. Ali. Dialog. NoActionBar.
Let's look at the next question:
Open Activity. java to check the source code related to Dialog. The Dialog description is as follows:

     * @deprecated Use the new {@link DialogFragment} class with     * {@link FragmentManager} instead; this is also     * available on older platforms through the Android compatibility package.
As mentioned above, we do not recommend DialogFragment. We recommend that you use DialogFragment. If you look at the DialogFragment source code, you will know that DialogFragment is actually a Fragment. That is to say, we recommend setting up Fragment!

So everyone will Fragment and DialogFragment. In fact, DialogFragment encapsulates the Fragment of Dialog. Let's look at the code below to see how DialogFragment is implemented:

public void VoiceCommandClickListener(View v) {        //showDialog(DIALOG_ID_VOICE_COMMAND_SHOW_TONES); FragmentTransaction ft = getFragmentManager().beginTransaction(); VoiceCommandDialogFragment prev =(VoiceCommandDialogFragment) getFragmentManager().findFragmentByTag("voice_dialog"); if (prev != null) { ft.show(prev); }else{prev = VoiceCommandDialogFragment.newInstance();prev.show(ft, "voice_dialog"); }}
The code above shows the call when DialogFragment is displayed. Let's take a look at the custom DialogFragment: VoiceCommandDialogFragment

    private static final class VoiceCommandDialogFragment extends DialogFragment {//private static VoiceCommandDialogFragment f;//private static final Object mLock = new Object();private static class SingletonHolder {private static VoiceCommandDialogFragment f = new VoiceCommandDialogFragment();}/*               static VoiceCommandDialogFragment newInstance() {            if(null == f){synchronized (mLock){if(null == f){f = new VoiceCommandDialogFragment();}}             }                    return f;               }             */        public static VoiceCommandDialogFragment newInstance() {     /*        if(null == f){f = new VoiceCommandDialogFragment();        }            return f;            */            return SingletonHolder.f;        }                @Override        public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            // Pick a style based on the num.            int style = DialogFragment.STYLE_NO_TITLE, theme = R.style.transparent_dialog_them;            setStyle(style, theme);        }        @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container,                Bundle savedInstanceState) {            View v = inflater.inflate(R.layout.setting_switch_sublist_layout, container, false);VoiceManager voice_manager = ((CameraApp)getActivity().getApplication()).getVoiceManager();SettingSwitchSublistLayout mVoiceSettingLayout =(SettingSwitchSublistLayout) v.findViewById(R.id.SettingSwitchSublistLayout_ID);mVoiceSettingLayout.initialize(voice_manager.getVoiceEntryValues());mVoiceSettingLayout.setSettingChangedListener((CameraSettingActivity)getActivity());            return v;        }    }
Note the following three points for the above Code:

(1) The problem of DialogFragment needs to be created repeatedly. The Singleton mode is used here. Here I use an internal class to solve it;

(2) check whether the current FragmentManager contains the DialogFragment to be displayed;

(3) As above, the theme setting of the device must be set to dialog_them;

This is enough.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.