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: