You’re about to define a MuseumObject class for your MetMuseum app. In this demo, I’m using Android Studio and writing in Kotlin. To get started, open the starter project for this lesson in Android Studio.
It has a MuseumObject class that you’ll fill in and a showImage() method stub.
There’s a commented-out MuseumObjectComposable function that showImage() will use to display the art object’s image and some other information on the app’s screen.
First, declare the properties of the MuseumObject class. You’ll do this inside the primary constructor of the MuseumObject class.
Enter the following code:
class MuseumObject(
val objectID: Int,
val title: String,
val objectURL: String,
val primaryImageSmall: String,
val creditLine: String,
val isPublicDomain: Boolean
)
Constructors are simply used to create objects. Each instance of MuseumObject will have values for these properties. As you develop your app, you might need to add more properties, but these are enough for now. These properties are declared with the val keyword, which makes them read-only or final if you’re coming from Java. This means you can’t update their values down the line. If you want to do that, then use the var keyword.
The MuseumObject class now has all the properties that MuseumObjectComposable uses, so go ahead and uncomment it. And also, uncomment the WebViewComposable, which you’ll use later on.
To add the imports, click on the individual error and then hit “Option” and “Return” key. Do these for the rest of the missing imports.
A class definition is just a template for objects. It doesn’t do anything on its own. You have to instantiate an object, that is, initialize it with parameter values just like you did in the previous lesson.
Or you could pass it in as a parameter and then your app can use the properties of each object.
And each object can call showImage() since it’s also a member of the MuseumObject class.
Now, you need to instantiate two objects — one in the public domain and the other not in the public domain. Copy and paste the code from the transcript below this video:
val obj_pd =
MuseumObject(
objectID = 436535,
title = "Wheat Field with Cypresses",
objectURL = "https://www.metmuseum.org/art/collection/search/436535",
primaryImageSmall = "https://images.metmuseum.org/CRDImages/ep/original/DT1567.jpg",
creditLine = "Purchase, The Annenberg Foundation Gift, 1993",
isPublicDomain = true
)
val obj =
MuseumObject(
objectID = 13061,
title = "Cypress and Poppies",
objectURL = "https://www.metmuseum.org/art/collection/search/13061",
primaryImageSmall = "",
creditLine = "Gift of Iola Stetson Haverstick, 1982",
isPublicDomain = false
)
You’ve created two instances of the MuseumObject type, each representing different art objects. These instances are initialized with specific property values, which you’ll use when working with the data of these art objects.
Lets implement the showImage() method.
Go ahead and update it to the following:
@SuppressLint("ComposableNaming")
@Composable
fun showImage() {
return if (isPublicDomain) {
MuseumObjectComposable(obj = this)
} else {
WebViewComposable(url = objectURL)
}
}
The showImage method returns a MuseumObjectComposable if isPublicDomain is set to true, otherwise, it returns a WebViewComposable, which just loads up a URL in an in-app browser.
Do note that you also added two annotations. @Composable annotation is added because only a composable function can return a composable, so this annotation makes showImage a composable function. Also, composable function names must start with an uppercase letter, but you want showImage to retain its casing, so you ignore the lint warning with the @SuppressLint annotation. These are Android-related concepts, but they’re mentioned here so you understand what’s going on.
Finally, each object can call showImage().
First, show the public domain image. Scroll down to the main activity class and call it inside setContent like so:
obj_pd.showImage()
Run the app.
obj_pd is in the public domain, so showImage() sets the view to MuseumObjectComposable.
Now, comment out the line obj_pd.showImage() and add this one:
obj.showImage()
Run the app again.
This time, obj isn’t in the public domain, so showImage() loads its web page in an in-app browser.
Comment out obj.showImage() and uncomment obj_pd.showImage().
You learned from the previous lesson that classes are reference types. Now, see them in action.
First, change title to be variable:
var title: String,
Then, scroll down and add these lines before the call to obj_pd.showImage() in the main activity:
val obj2 = obj_pd
obj2.title = "Sunflowers"
Run the app.
MuseumObject is a class, which is a reference type. MuseumObjectComposable displays the title Sunflowers because obj2 is the same object as obj_pd. Changing obj2.title changes obj_pd.title because obj2 now points to the memory location of obj_pd.
Note:
MuseumObjectis a class, so changingobject2’stitleworks even if you declare it as a constant class object using thevalkeyword. This is because the constant value is its location in memory, not its contents.
Sometimes, you want to hide some of your object’s properties to be visible only within the class. This prevents “outside” code from using or modifying these values.
For example, set isPublicDomain to be private:
private val isPublicDomain: Boolean
Making this property private doesn’t prevent showImage() from using it because they’re both contained in the same class.
But try typing this outside the class:
obj2.isPublicDomain
The first thing you’ll notice is isPublicDomain doesn’t show up in the auto-completion suggestions. There’s also an error and if you hover over it, it says:
Cannot access ‘isPublicDomain’: it is private in ‘MuseumObject’
Undo this addition.
That ends this demo. Continue with the lesson for a summary.