From the course: Android Development Tips
Create a reusable dialog class - Android Tutorial
From the course: Android Development Tips
Create a reusable dialog class
- [Narrator] In Android apps, dialogs are used to communicate with the user and also sometimes to collect small amounts of information, but creating dialog classes and layouts takes some time. If you want to use them at all, it's a good idea to create reusable classes, that can be used multiple times in your apps. In this tip I'm going to share some code that I created for one of my apps that's saved me a lot of time. I had to collect little bits of text from the user in different contexts. The prompt might change, the value might change, but I wanted the dialog to always look the same, so I created a reusable Java class. I'll start by creating a layout file that defines my dialog's user interface. I'll go to my layout folder, under resources, and I'll create a new layout resource file. I'll name it dialog_edit_text. I won't worry about the Root element, because I'm going to go get the code from a gist on GitHub. Notice as I add files, I'm adding them to my GitHub repository. Now I'll go to a browser, and I'll navigate to "git.io/v9i07," and that takes me to this gist that's labeled "dialog_edit_text.xml." I'll select and copy all this code, and I'll go back to Android Studio. Then I'll paste it into place. Here's what my dialog will look like. There's a text view at the top that has the text "Prompt Text," and then there's an edit text component. Then there's a CANCEL and an OK button. This is all being laid out using a relative layout. If you prefer, you could use a constraint layout. Notice that each of these view objects has a unique ID, and I have an ignore attribute here for hard coded text, because I only have this text in here for development and testing. I'll be updating that text dynamically each time I use the dialog. Here are my buttons down here, and they don't have any onclick attributes or any other ways of reacting when the user clicks them. Next, I'll create my Java class. I'm going to put this in a new package that I'll name "Dialogs," and I'll name my new Java class "EditTextDialog." Once again I'll add this to Git, and I'm going to get rid of everything except for the package declaration. Then, once again, I'll go back to my browser, and this time I'll go get a gist that's at "git.io/v9i0w." This is named EditTextDialog.java. I'll select everything after the package declaration. You can see there's quite a bit of code involved here. I'll paste that into place. Now let's take a look at what this code is doing. First of all, this class extends DialogFragment. It has two fields named "PROMPT_KEY" and "VALUE_KEY. And there's a newInstance method that lets me pass in those two values. Those values are saved to a bundle, and then they're passed to a fragment using the setArguments method. The fragment is an instance of this class. This is a factory method that lets me customize this version of the dialog. Next, there's the implementation of the onAttach method. This is a fragment, and so each time it's loaded by its host activity, this method will be called. A context will be passed in. The context must implement an interface named "EditTextDialogListener," which is declared down at the bottom of this class. I'll get back to that in a moment. If the caller of this dialog does implement that interface, then I save the reference to that caller in the "mListener" field. If not, then I throw an exception. That means that this class hasn't been used correctly. Next is the onCreateView method. This is called automatically as the fragment manager sets up the fragment. This is where I'm laying out the dialog, displaying all the values that were passed in, and setting up the event handlers. If you prefer, you could change some of this code to use Butter Knife, and it would make the code more readable and maintainable. Now to the interface. This interface declares a single abstract method called onEditTextDialogOK, and it's only going to be called if the user clicks the YES or OK button on the dialog. In order to use this dialog class, the caller must implement that interface. I'll go back to my main activity, and I'll add an implements clause, and I'll pass in "EditTextDialogListener." That generates an error condition, so I'll use an intention action and choose "Implement Methods," and I'll choose that one method. Now this is a listener for that dialog. Now I'm ready to actually call the dialog. I'll do this work in my runCode method up here. I'll create an instance of the dialog. I'll set the type as "EditTextDialog." I'll just call it "Dialog," and I'll call the classes "newInstance" method. I'll pass in a string of "Enter your name." That will be the prompt, and then an empty string as the current value. Next, to display the message, I'll call "dialog.show," and I need to pass in an instance of the fragment manager. Now there's a couple of ways of doing this. You need to know whether you're using the native version of this class or the support version. I'll go back to "EditTextDialog," and scroll up to the top. Then I'll hold down Control or Command and float the cursor over it. I see that my dialog fragment is a member of the support library. It's not a member of the Core SDK. I'm going to pass in the results of a call to a method called "getSupportFragmentManager." If I were using the native version of the fragment, I would just call "getFragmentManager." Then I need to pass in a string that's called a tag. When you're working with fragments, tags can be used to get references to existing fragments. This tag can be anything. I'll just call it "dialog_tag," and these are usually set up as constants. I'll select Refactor, Extract, Constant, and I'll accept the default name, "DIALOG_TAG." That's now declared as a constant up at the top of my code. Finally, I'll add some code into my implementation of onEditTextDialogOK. I'll call my log method. I'll say, "'You entered a value of ' + newValue." Now all the pieces of the puzzle are put together. When the user clicks the button in the activity, that creates and shows the dialog. The user will then fill in the value in the dialog, touch the OK button, and that will call the listener method in the activity again and close the dialog. Now click the Run Code button, and there's my dialog. I'll enter my name and click OK, and I get "You entered a value of David." Now if I click the Run Code button again, I see the dialog again, but it doesn't remember the value I originally entered. Here's how you can do that. I'll cancel out of the dialog and come back to Android Studio. Up at the top of my class, I'll declare a string field, and I'll initialize it as an empty string. Then down here where I'm calling the dialog, instead of passing in a literal empty string, I'll pass in that field. Finally, I'll go down to my listener method, and I'll save the value that the user entered with "name_= newValue." Now each time the user calls the dialog and enters a value, I'm saving it persistently to the activities field. Right now, the lifetime of that value will only be for the current activity session. If the user rotates the device or otherwise changes the configuration, that value could be lost, but there are lots of ways of dealing with that. I'll run the application again and run the code again. I'll type my name and click OK. Then I'll run the code again, and this time the value is remembered. Now I can use this dialog wherever I want to in my application. I can change the prompt, and I can change the value that's being passed in depending on the context of how the dialog is being used. I now have some reasonable code that can be used multiple times throughout my Android app.
Contents
-
-
-
(Locked)
Communicate with Snackbar messages6m 15s
-
(Locked)
Manage view components with Butter Knife6m 41s
-
Create a reusable dialog class9m 22s
-
(Locked)
Convert a layout to ConstraintLayout7m 13s
-
(Locked)
Manage global data with singletons5m 37s
-
(Locked)
Convert image files to WEBP format6m 5s
-
(Locked)
Create an Espresso user interface test5m 18s
-
(Locked)
Create classes for Android with Kotlin5m 12s
-
(Locked)
Run background tasks in intent services8m 51s
-
(Locked)
Send broadcast messages with EventBus8m 44s
-
Handle events with Java 8 syntax5m 51s
-
(Locked)
Improve forms with design layouts7m 55s
-
(Locked)
Display draggable rows in a list of data8m 1s
-
(Locked)
Manage persistent data with Realm10m 23s
-
(Locked)
Play an audio file from assets8m 56s
-
(Locked)
Send an SMS message from an app7m 56s
-
(Locked)
Get a list of audio files on a device8m 32s
-
(Locked)
Play sounds with SoundPool8m 45s
-
(Locked)
Display the build date of an APK file6m 47s
-
(Locked)
Build Kotlin classes with properties7m 32s
-
(Locked)
Manage versioning with Gradle variables6m 8s
-
(Locked)
Use reporting tools from the Google Play Console4m 44s
-
Make web service calls with Retrofit10m 39s
-
(Locked)
Make asynchronous calls with Retrofit4m 6s
-
(Locked)
Send request parameters with Retrofit4m
-
(Locked)
Upgrade a project to Android Studio 3.04m 47s
-
(Locked)
Clean up calls to findViewById()2m 58s
-
(Locked)
Create adaptive launcher icons5m 47s
-
(Locked)
Use XML and downloadable fonts6m 40s
-
(Locked)
Explore a device's file system4m 55s
-
Profile an app's memory usage3m 52s
-
(Locked)
Manage an SQLite database with Room9m 17s
-
(Locked)
Manage background threads with Executors5m 32s
-
(Locked)
Track vital stats in a published app3m 4s
-
(Locked)
Inspect database files with DB Browser4m 41s
-
(Locked)
Execute tasks with JobScheduler7m 29s
-
(Locked)
Create Room entity classes in Kotlin8m 22s
-
(Locked)
Create Room DAO classes in Kotlin4m 13s
-
(Locked)
Upgrade to Android Studio 3.13m 22s
-
(Locked)
Convert a project to use Kotlin3m 20s
-
(Locked)
Handle events with Kotlin lambdas6m 13s
-
Manage menus with when3m 44s
-
(Locked)
Define global constants with Kotlin6m 12s
-
(Locked)
Use Kotlin data and enum classes5m 24s
-
(Locked)
Create inheritance hierarchies in Kotlin6m 8s
-
(Locked)
Manage data collections in Kotlin5m 45s
-
(Locked)
Sort data collections with Kotlin5m 33s
-
Filter data collections with Kotlin3m 52s
-
(Locked)
Create Kotlin extension functions2m 31s
-
Use support functions from Android KTX4m 30s
-
(Locked)
Use virtual devices with Google Play3m 50s
-
(Locked)