430 likes | 619 Views
Cosc 5/4730. Dialogs and preferences 2.3.3 and below 3.0 and above (fragment). dialogs. Dialogs. So most of this is depreciated in API 13 +, but it is encapsulated in a fragment, plus if you are writing from below API 13 (honeycomb) it’s worth knowing. Dialog.
E N D
Cosc 5/4730 Dialogs and preferences 2.3.3 and below 3.0 and above (fragment)
Dialogs • So most of this is depreciated in API 13+, but it is encapsulated in a fragment, plus if you are writing from below API 13 (honeycomb) it’s worth knowing.
Dialog • A dialog is always created and displayed as a part of an Activity. • You should normally create dialogs from within your Activity's onCreateDialog(int) callback method
Dialog • Using the createDialog() method • All dialog creation is done there. • Only called the first time specfic dialog is created. • Use the onPrepareDialog(int, Dialog) • Every time the dialog is called, you can modify it • In you activity: • showDialog(DIALOG_PAUSED_ID); • Where is the ID is the dialog you want to display.
Creating a Dialog • There are several dialogs you can create • AlertDialog, which can have up to 3 buttons • ProgressDialog • DatePickerDialog and TimePickerDialog • Custom dailog, which you create the layout.
AlertDialog • Use the AlertDialog.Builder to create the dialog • You can have up to three buttons, “positive”, “negative” and cancel • To create the following Dialog • Set the positive and negative, and disable cancel.
AlertDialog (2) • Code: with two listeners, one for each button. AlertDialog.Builderbuilder = new AlertDialog.Builder(this); builder.setMessage("Winner!") .setCancelable(false) .setPositiveButton("Next Level", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); //next(); } }) .setNegativeButton("Quit", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }); dialog = builder.create();
AlertDialog(3) • Instead of buttons, you can have it as radio buttons (and more then just three); • Use Builder.setSignleChoiceItems • Where we send a CharSequence[] of items. • final String[] items = {"Remove Walls", "Add Walls", "Add/Remove Objects", "Add/Remove Score"};
AlertDialog (4) • code: final String[] items = {"Remove Walls", "Add Walls", "Add/Remove Objects", "Add/Remove Score"}; AlertDialog.Builderbuilder = new AlertDialog.Builder(this); builder.setTitle("Choose Type:"); builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { dialog.dismiss(); if (item == 0) { //remove walls } } }); dialog = builder.create();
Custom Dialogs • You need to create a layout xml file for the dialog • Then dialog.setContentView(R.layout.youlayout) • Using dialog.findViewByID(R.id.X) to access each widget to set images and/or listeners as necessary • dialog.setTitle(“your title”); • Now it’s ready to be shown.
Examples • The previous examples are all shown in dialogs233Activity in the DialogDemo
DialogFragments • The showDialog is depreicated in API 13+ • Links and discussion of dialogfragmentvsalertdiags: http://stackoverflow.com/questions/13765127/dialogfragment-advantages-over-alertdialog • Basically, I’m just going to show how it works. • What it comes down to is that you are creating custom dialogs. • But we can still use the alertdialog creators in the dialogfragment as well.
DialogFragment • Basically a fragment and everything that we have already done. • Or you implement onCreateDialog(Bundle) • Instead of (or in addition to ) onCreateView • DialogFragments can be added to a framelayout just like fragments OR we can show it like a dialog. • All the demos are going to show it, instead putting in the framelayout, since you already saw how to do it.
EditNameDialogFrag example • Looking at the code, it is a DialogFragment (using support library or without is the same) • Create a callback as we have done before • In onCreateView • Inflate the layout, return the view. • Just like we have done before. • The change is in the FragmentDialogActivity. FragmentManagerfm = getSupportFragmentManager(); EditNameDialogFrageditNameDialog = new EditNameDialogFrag(); editNameDialog.show(fm, "fragment_edit_name"); Show function, causes the dialogFragment to popup on the screen.
EditNameDialogFragexample (2) • So we have the dialog
EditNameDialogFragand keyboard • Changing the keyboard return button to done. • In the xml for the EditText <EditTextandroid:id="@+id/txt_your_name" … android:inputType="text" android:imeOptions="actionDone" /> • Changes keyboard • Setup in the listener if (EditorInfo.IME_ACTION_DONE == actionId) • We know when they done editing/typing. • A note, this doesn’t work correctly in the emulators, so I added done button to the example.
DialogFragment and AlertDialog • We can embed the alertDialogs into the FragmentDialog, so you can use the “default” dialogs as well. • Show in code DialFragActivity and AlertDialogFrag1 and myDialogFragment
DialogFragment with AlertDialog • Two pieces for the Dialog Fragment • newInstance • Creates a new dialogFragment, instead doing this in the Activity. • onCreateDialog • Creates the AlertDialog via the builder just like before. • The “hard part” is receiving the answer from the dialog • Create callbacks or call a method in the activity. • Google choose to call a method in the activity, which is what I’m showing in the example.
DialogFragment with AlertDialog (2) • In the fragment new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, intwhichButton) { ((DialFragActivity)getActivity()).doPositiveClick(); }} • In the Activity: public void doPositiveClick() { // Do stuff here. }
Example code • DialFragActivity • AlertDialogFrag1 • Cancel/Ok dialog • myDialogFragment • Implements the two dialog from the beginning of the lecture No/Yes, and a ListDialog • There is a doPositivieClick(), doNegativeClick(), and doItem(String) for these dialog • This really should be done correctly with callbacks.
DialogFragment References • http://developer.android.com/reference/android/app/DialogFragment.html • http://android-developers.blogspot.com/2012/05/using-dialogfragments.html • http://stackoverflow.com/questions/12912181/simplest-yes-no-dialog-fragment
Preferences • It’s normally a good idea to allow a user to setup some preferences for an application • Example: Username • It’s saved data between runs about how the application should run. • Android provides a preferenceActivity and PreferenceFragment to do this • Unlike everywhere else, preferences are not supported (currently) in the supportv4 library.
Preferences (2) • The bulk of the work is in the xml document • The preferenceActivity (and fragment) only provide a place to show the xml document.
Preferences activity • The activity itself is very easy. • Extend the prefrenceActivity and override the onCreate • The preferences are kept in xml document. • Use the addPreferenceFromResources to use the xml file.
Preferences activity (2) • Code: public class preferences extends PreferenceActivity{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); • This is depreciated in API 13+ in an activity, use a PreferenceFragment } }
PreferenceFragment • The code is basically the same, but in a fragment. public class PrefFrag extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } • A Note, there is no support.v4 version of this fragment • At the end of the lecture, I’ll show how to combine them for backward compatibility.
Preferences xml • You need to create an xml for the preferences • Preferences are kept be application sessions by default. • <PreferenceScreen …> • <PreferenceCategory…> • … in-line preference • </PreferenceCategory> • <PreferenceCategory …> • … </PreferenceCategory> • </PreferenceScreen>
CheckBoxPerference • On (true) or off (false) <CheckBoxPreference android:key="checkbox_preference“ • key used by application to find out the value. android:title="Check Box" android:summary="An example of a Check Box" /> • Also, you can also set a default value as well. • android:defaultValue=“false” Ie off by default
EditTextPreference <EditTextPreference android:key="edittext_preference" android:title="EditTextPreference“ android:defaultValue="" android:summary="Example of EditText Dialog" android:dialogTitle="Enter your Name" />
ListPreference • <ListPreference • android:entries="@array/entries_list_preference" • android:entryValues="@array/entryvalues_list_preference" • android:dialogTitle="list preference example“ • android:summary="List preference demo" • android:key="list_preference" • android:title="list perference" • />
Arrays and xml • In the values directory • created a file called “arrays.xml” <resources> <string-array name="entries_list_preference"> <item>Alpha Option 01</item> <item>Beta Option 02</item> item>Charlie Option 03</item> </string-array> <string-array name="entryvalues_list_preference"> <item>alpha</item> <item>beta</item> <item>charlie</item> </string-array> </resources>
Access the preference • In your java code, likely in onResume(…) • onResume is called when you app gets the screen back from the preferences screen! • Also called when the application starts. • code look something like this: SharedPreferencesprefs = PreferenceManager.getDefaultSharedPreferences (getBaseContext()); • Now you get the preferences with • abstract Map<String, ?> getAll() OR • getBoolean(key, defaultvalue), getInt(key,defvalue), getString(key, defaultvalue), …
preference example • prefs declared like on last slide booleanuseSensor = prefs.getBoolean(“sensorPref” , false); • get the sensorPref key, if not found, default is false. string text = prefs.getString(“textPref”, “”); string list = prefs.getString(“list_preference”,””); • Note, if you had set integer or floats as the entryValues, then you want to get them as getInt or getFloat.
Compatibility • Since there is no support.v4 fragment, you need to add a little extra code in the fragmentActivity public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { addPreferencesFromResource(R.xml.preferences); }else{ //api 13+ and some “magic here”. getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefFrag()).commit(); } • I don’t have any idea what android.R.id.content is, but there is no layout for a fragmentActivity.
Example code • The PreferenceDemo has the code from all in. • The myPreferenceActivity and PrefFrag show everything covered so far. • A note, the read of the preferences (in prefupdate method in mainactivity), this perferences are set in PrefupdateActivity • PrefupdateActivity and PrefupdateFrag show the next stuff.
Preferences android:summary • It maybe that instead of you want a the current value listed, instead of the descriptions as I have listed here. • You will need to implement a listener in PreferenceActivity called OnSharedPreferenceChangeListener • See the dialog example for how to implement the code.
Listener and Summary • Again much of the code is depreciated for the Activity (3.0+) and then works in the fragment. • The code shows it for compatibility. • The code has the if statements in activity when using the fragment • Otherwise the code is identical.
Code • Setup some variables in onCreate(…) // Get a reference to the preferences, so we can dynamically update the preference screen summary info. mEditTextPreference= (EditTextPreference)getPreferenceScreen().findPreference("textPref"); mListPreference = (ListPreference)getPreferenceScreen().findPreference("list_preference"); • Implement the OnSharedPreferenceChangeListener @Override public void onSharedPreferenceChanged(SharedPreferencessharedPreferences, String key) { if (key.equals("textPref")) { //where textPref is the key used in the xml. mEditTextPreference.setSummary( "Text is " + sharedPreferences.getString("textPref", "Default")); } else if (key.equals("list_prefrence")) { mListPreference.setSummary("Current value is " + sharedPreferences.getString(key, "Default")); } }
Code (2) • Setup to read and setup the summary fields in the onResume() and setup the listener. • Remove the listener in the onPause()
preferences xml. • Only covered a subset of the preferences xml, including some interfaces. • see http://developer.android.com/reference/android/preference/Preference.html for more information. • While out some what out of date, this is very helpful with for changing the android:summary • http://stackoverflow.com/questions/531427/how-do-i-display-the-current-value-of-an-android-preference-in-the-preference-su
References • http://developer.android.com/reference/android/preference/PreferenceActivity.html • http://developer.android.com/reference/android/preference/PreferenceFragment.html • http://stackoverflow.com/questions/7112706/preferencefragment-alternative-for-the-android-compatibility-api • http://android-er.blogspot.com/2012/07/example-of-using-preferencefragment.html • http://gmariotti.blogspot.com/2013/01/preferenceactivity-preferencefragment.html • http://www.cs.dartmouth.edu/~campbell/cs65/lecture12/lecture12.html