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
Evaluate ViewBag Helper #118
Comments
Could you just use ViewBag.disable(firstName, middleName, lastName);
ViewBag.applyFont(customTypeface, firstName, middleName, lastName);
View[] nameFields = [firstName, middleName, lastName];
ViewBag.disable(nameFields);
ViewBag.applyFont(customTypeface, nameFields); public class ViewBag {
public static disable(View... views) {
for (View v : views) {
v.setEnabled(false);
}
}
public static applyFont(Typeface typeface, View... views) {
for (View v : views) {
v.setTypeface(typeface);
}
}
} Or is the big win the grouping in the same place as your injection? |
@swanson Yes but that has two major downsides that I can see: it requires an allocation of an |
Allocation - yup, no way around that I suppose. Enumerating the properties - true, but wouldn't the library handle all common view properties? If you want something custom, you write your own 3-line static method vs defining a custom |
I thought of another downside: It suffers from having to duplicate the list of views multiple times. When I add a Mr./Ms. selection view I have to update the list that's passed to enable/disable/etc. at every call site. The problem with common is that I can't really know what the common ones are. Some are obvious, but sprinkled throughout my codebase I have one-off batch applications of strange properties like color, translation, or playing an animation. By making the mechanism of applying the property to multiple views ( |
I don't follow the Mr./Mrs. example. @InjectView(R.id.title) EditText titleView;
@InjectView(R.id.first_name) EditText firstNameView;
@InjectView(R.id.middle_name) EditText middleNameView;
@InjectView(R.id.last_name) EditText lastNameView;
private View[] nameFields;
public void onCreate(Bundle b) {
super.onCreate(b);
nameFields = [titleView, firstNameView, middleNameView, lastNameView];
}
public void someThingHappened() {
ViewBag.disable(nameFields);
ViewBad.colorize(R.color.gray, nameFields);
}
public void wizzBangPow() {
ViewBag.enable(nameFields);
ViewBag.fadeIn(2000, nameFields);
} (Aside: this example set of controls should probably live in a custom view not an activity, but bear with me) |
Ah, but now you've changed what's happening to start solving the problems and you are moving toward what my implementation of So let me throw another use-case into the mix. Often times I have a set of buttons on screen which I want to control. In code, I only interact with these buttons through In your new example I would list the injects and the array as fields, perform injection, create the array and pass in the list of fields, and then at the call site use that array. I think it's getting better, but I still have to duplicate the list of fields twice. Losing the allocation of the |
Yeah - I think we are converging on the same solution. Good discussion, IMO. Extensibility is probably a matter of preference in this case. Personally, I prefer the explicit methods but, hey, maybe that's just me :) Reminds me of fest-android in that sense: a bit of work in the library to make explicit methods, but I think it is more readable than generic matchers. At first glance, this seemed like it might fit better as its own library - applying properties to a group of views doesn't seem to have much to do with "injection" - but I hadn't considered the emphasis on grouping up views with the annotation. Maybe it still should be it's own thing - |
Yeah it's a tough distinction to make. I like that you brought up fest-android. That's a good counter-point to what I've been saying. I've been thinking about something more like Hamcrest where you can create arbitrary matchers but perhaps there is value in being concrete. I'll have to think about it more. As to "injection", I've been meaning to rebrand the library as view-based boilerplate reduction for a while now! |
Be able to apply an animator to the ViewBag could also be useful. |
About the custom properties / explicit methods debate, I also think it's only a matter of preference, and custom properties don't prevent anyone from making his own library on top of it to provide explicit methods. So I actually think it's better. Moreover it would avoid having both |
Here's a similar use case I ran into today, than I'm not sure ViewBag would handle. (Although it would help.) protected void updateViewsByCase(){
if (caseButton()){
button.setVisibility(View.VISIBLE);
textView.setVisibility(View.GONE);
progress.setVisibility(View.GONE);
} else if (caseText()){
button.setVisibility(View.GONE);
textView.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
} else {
button.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
progress.setVisibility(View.VISIBLE);
}
} This may not be the best way to achieve what I'm looking for... but I do find myself writing this type of code occasionally. Here it's how I handle different cases in a ListView empty view. |
@bobz Yep. Still a bit awkward in that case but it'd become: thingsBag.apply(Views.VISIBILITY, GONE);
if (caseButton()) {
button.setVisibility(VISIBLE);
} else if (caseText()) {
textView.setVisibility(VISIBLE);
} else {
progress.setVisibility(VISIBLE);
} Although in general you might want to consider a tri-state value to simplify to: Whatever whatever = determineCase();
button.setVisibility(whatever == FOO ? VISIBLE : GONE);
textView.setVisibility(whatever == BAR ? VISIBLE : GONE);
progress.setVisibility(whatever == BAZ ? VISIBLE : GONE); |
FYI opinionated people see #119 for the implementation of this. |
Frequently an action needs applied across multiple views. Currently I've been writing standalone methods for this which is cumbersome and prone to error long-term.
A view bag aggregates multiple views of type
T
and allows applying properties across all of them at once.You can define your own properties for common actions.
Generics allow using non-
View
-specific methods.The text was updated successfully, but these errors were encountered: