-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Improve media displayed in widgets [BarcodeWidget + ArbitraryFileWidget] #6534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
@seadowg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely like the general direction of pulling out a view to specifically represent the answer here. I had in mind that we could go a bit further and have a generalized AnswerView
with a similar structure that where setAnswer
takes an IAnswerData
(I think the widget would handle the hidden appearance in that setup). That would get us something that's simple to then use in the hierarchy later.
@seadowg could you clarify your feedback because I'm not sure if I understand? |
I was thinking one |
a5e7c87
to
c976a03
Compare
That makes sense.
The view I factored out will be one that can be shared between the question layout and the hierarchy layout. As I rework other questions, I’ll likely introduce some form of abstraction. Later, when we work on the hierarchy view, we'll need to implement a factory to construct the appropriate view but that can wait for now. Let's maybe continue with other question types in this pull request to see how it goes, unless you have something against the current changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's maybe continue with other question types in this pull request to see how it goes, unless you have something against the current changes.
That sounds good! You're right that it makes more sense to introduce the generalization after 2 or 3 examples rather than trying to plan it ahead of time.
@grzesiek2010 I've been running into frustrations trying to add an arg to the Basically I think we need to get to a point where we can modify QuestionWidget(context, questionDetails, BearingWidgetAnswer()) That would let us easily modify |
45f1b3f
to
f704d6d
Compare
@seadowg
The current implementation adds the answers using XML, but this won’t be possible later in the summary view, where we’ll need to generate answers dynamically. So, it would probably make more sense to add that view programmatically in the widgets as well. Is that what you meant? Any other thoughts? |
Right it feels like we need to move to the views being added programmatically for this to work. So ideally class QuestionWidget<A>(private val widgetAnswerView: A) where A : View, A : WidgetAnswer { I think in Java we just need to use an abstract to combine the types: public abstract class WidgetAnswerView extends View implements WidgetAnswer {
} Then we'd be able to add that view into the layout for the |
d201a5e
to
e570264
Compare
@seadowg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grzesiek2010 I had been thinking we'd basically replace the onCreateAnswerView
implementation with the new WidgetAnswer
concept. Do you think that's another step or do you disagree?
@seadowg |
Just to expand on my earlier comment, I wanted to be more explicit about where I saw this eventually going. My thinking was that in the future (🔮) we'd end up switching away from an inheritance based model for widgets to a composition based one. The way I'd see that working is that we'd have a class QuestionWidget(context: Context, questionDetails: QuestionDetails, widgetAnswer: WidgetAnswer) Then when we're displaying a question we are always constructing a I was thinking a way to transition to that would be to have As an aside, there's been some back and forth about Compose. I think that this direction is exactly what we'd want to do if we were looking to build widgets with Composables (or similar frameworks like React/JSX): @Composable
fun QuestionWidget(questionDetails: QuestionDetails) {
BarcodeAnswer(
questionDetails: QuestionDetails,
onScanBarcode = {
// Launch barcode scanner
},
onLongPress = onLongPressListener
)
} Obviously we're pretty far off from that kind of thing as widgets hold state (which wouldn't work in a Compose setup), but I think shooting for that kind of structure makes sense. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@seadowg The structure I started building (to be used in the hierarchy as well) consists of |
I've had a bit of a think about it, and I agree. I'm jumping the gun a bit! Down the line, I'd really like to get to a place where How about we rename Thanks for back and forth on this with me! I'm liking the direction we're moving in. |
e570264
to
5da8d2c
Compare
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a first pass and some comments on some structural things
class ArbitraryFileWidget( | ||
context: Context, | ||
questionDetails: QuestionDetails, | ||
private val widgetAnswerView: WidgetAnswerView, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For right now is there any reason to have WidgetAnswerView
passed in like this? It seems like we'd only ever want ArbitraryFileWidget
to be using ArbitraryFileWidgetAnswerView
.
@@ -261,6 +262,8 @@ interface Builder { | |||
|
|||
void inject(FormHierarchyFragmentHostActivity formHierarchyFragmentHostActivity); | |||
|
|||
void inject(WidgetAnswerTextView widgetAnswerText); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to avoid using Dagger here. Could we add a setFontSize
to WidgetAnswerView
instead?
} | ||
|
||
override fun getAnswer(): IAnswerData? { | ||
val answer = widgetAnswerView.getAnswer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're here, it would be great to try and avoid propagating the pattern of storing state in the views themselves. Would we be able to remove getAnswer
from WidgetAnswerView
and just store the answer in a field in these widgets?
@@ -162,7 +162,7 @@ public void render() { | |||
* rendering the widget. It is also passed the size to be used for question text. | |||
*/ | |||
@SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract") | |||
protected View onCreateAnswerView(@NonNull Context context, @NonNull FormEntryPrompt prompt, int answerFontSize) { | |||
protected View onCreateWidgetView(@NonNull Context context, @NonNull FormEntryPrompt prompt, int answerFontSize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIDGETS.md
will need an update
Closes #6234
Why is this the best possible solution? Were any other approaches considered?
The structure of this pull request reflects the discussion below. It’s the first step toward creating shareable answer views that can be used across all question types and eventually in the summary view as well. The changes are introduced for
BarcodeWidget
,ArbitraryFileWidget
, andExArbitraryFileWidget
, but later other question types will be reworked in the same way.How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
The only visible change is that answers in the barcode question will now include an icon in addition to the text. This is something we plan to introduce later for other question types as well, since a shared style should be used across both the questions and the summary view.
Aside from that, this is purely a refactoring and shouldn't introduce any functional changes. However, we should still test the
BarcodeWidget
,ArbitraryFileWidget
, andExArbitraryFileWidget
to ensure that no regressions have been introduced.Do we need any specific form for testing your changes? If so, please attach one.
The
All question types
form is fine.Does this change require updates to documentation? If so, please file an issue here and include the link below.
No.
Before submitting this PR, please make sure you have:
./gradlew connectedAndroidTest
(or./gradlew testLab
) and confirmed all checks still passDateFormatsTest