COMP 1601 2022W Assignment 4 Solutions 1. [2] If you change the first line of MainActivity.kt to be "package not.a.real.package", what breaks? Why? Explain briefly. A: Any reference to R breaks because R is defined for the package specified in AndroidManifest.xml (in the package attribute of manifest). R is the data structure used to represent resources such as layouts and drawable items. (Note that it also breaks the reference to MainActivity in SplashScreen.kt, as class references are relative to the current package unless you say the whole name, e.g. carleton.comp1601.picviewer2.MainActivity::class.java in line 15 of SplashScreen.kt.) 2. [2] If you don't make the changes in AndroidManifest.xml and just use the default one that you get when you make an empty activity app, what functionality will break? Why? A: If you use the default AndroidManifest.xml, MainActivity will start (so we'll see the picture displayed along with the text entry boxes) but we won't see the startup splash screen. This happens because AndroidManifest.xml specifies the class that receives the launch intent (android.intent.category.LAUNCHER), the one that starts the app from the Android app launcher. This must be changed for SplashScreen to be started on launch. 3. [2] If you switch the simulator to use a dark theme, can that affect the layout of the app, other than changing the colors? Why? (Note: this answer depends on what files you edited when setting up PicViewer2.) A: We added two lines to themes.xml to remove the app titlebar (the one that would otherwise say PicViewer2). There are two theme.xml files, one in app/src/main/res/values, the other in app/src/main/res/values-night. The first is for day mode, the other is for night mode. So if you switch to night mode but you only changed the day mode theme.xml, then you'll get the default behavior and see the app title bar, changing the app layout. 4. [4] How could you change the layout so that the X and Y fields are on the left of the screen and the scale and rotation are on the right? (1 point for the positioning of each value.) * The X and scale should be on the same horizontal line, as should be the Y and rotation fields. The X and Y fields should be vertically aligned, as should the rotation and scale fields. * Both the Y and rotation fields should be close to the bottom edge of the screen (except for a small margin). * Make sure your layout uses no absolute units except, where necessary, for small offsets from the edges of the screen. A: Below is the layout for all of the widgets except for mypic, which can remain the same. There are multiple other ways to do this layout; the key factors are that xlabel and ylabel should be anchored to the start of parent (left side), x and y's ends should be anchored to the start of their labels, and y/ylabel should be anchored to the bottom. 5. [2] Would eliminating the picParamWatcher class and instead putting its code into MainActivity significantly increase the number of lines of code in the program? Explain briefly. A: It would significantly increase the amount of code in the program because you'd need to duplicate the code of picParamWatcher four times, one for each field, so that could add almost 150 lines. (picParamWatcher is 48 lines, and so adding it inline would add three extra versions.) See last year's Tutorial 8 for a version of this that had more code duplication. 6. [2] Would eliminating the dragView class and instead putting its code into MainActivity significantly increase the number of lines of code in the program? Explain briefly. A: Eliminating the dragView class would not significantly increase the number of lines of code as there is only one instance of a dragView object, the one created on line 30. Thus we'd only have to move the code, we wouldn't need to duplicate it. 7. [2] When in the program's execution is dragView's picDragged true? When is it false? Explain in terms of high level program functionality, not precise lines of code. A: picDragged is true when the image has been moved by the user using a drag gesture but the x and y input fields (X and Y PicParamWatcher instances)) do not have the new position. When picDragged is false, X.value and Y.value are the same p.x and p.y. (picDragged is set to true in DragView and set to false in update). 8. [2] The image retains its position, rotation, and zoom values when the device is rotated. Is this because the instances of PicParamWatcher are being preserved? Or are they being destroyed and re-created when the device is rotated? Explain, giving empirical evidence in support of your answer. A: The PicParamWatcher instances are being destroyed and recreated, with their included EditText's automatically preserving their values. We can confirm this by adding a field to the object that is declared as being false and then set to true in the constructor. 9. [2] Why does PicParamWatcher need valueChanged? Explain how the program behaves when this variable is removed along with the code that references it and how the valueChanged-assocated code changes this behaviour. A: PicParamWatcher needs valueChanged because the refresh method calls setText, and setText implicitly calls afterTextChanged (because setText causes the text of widget to change) and afterTextChanged normally calls update, which then calls refresh. We thus get a circular set of updates that causes the app to crash. valueChanged breaks this loop by making sure that afterTextChanged doesn't call update if it was implicitly invoked by refresh. 10. [5 Extra credit] Implement PicViewer2 (as presented in Tutorial 9) as a SwiftUI program, explaining how your program captures the basic look and functionality of the Android program. Compare the two implementations explaining key design differences. (Your SwiftUI program doesn't have to be completely identical. In particular you don't need to make the title screen. It should be reasonably close, however.) A: