Where to put helper methods? - android

I have a method that darkens a given hex color and percent. Currently, the only place I use this method is within one of my Activity classes (I may or may not end up using it in other classes later on).
public static int darkenColor(int color, int percent) { ... }
However, where should I put this method? Should I create a new class called Helpers that contains all of these methods that I may use only once throughout the entire app?

This is just a matter of choice. You can have Set of utility classes and have these helper methods to be in those classes. But, This method is for not used in one of your activity, and If you do not see that it will get reused in the near future in some other point, Put it as a private method inside your Activity. I say this because you do not want to over complicate the code and also By this way another developer can easily follow the flow of execution.
But after sometimes if you feel, that this code is getting reused, put that into a logically meaningful Utility class. When the code base is huge, you do not have any choice to follow a solid standardization of there to put your code, That is why there are things like Layered architectures etc.

Related

Android MVP (Repository pattern) get Camera/Gallery Image?

I am trying to implement MVP architecture using google sample code for mvp. I have an activity as View that has a presenter and model. On button click user can capture and save image in external storage. And on capture click, I also need to play a sound.
I am not sure which code should be put in which class because I cannot put camera capture and play sound code in Activity (which I treat as view) to keep the view as dumb as possible and I cannot put that code in Presenter because it uses Android framework classes (context etc).
So, the only option is to put it in model but in sample code, model only has Repositories (that I believe is relevant to data sources only local/remote).
How to put this code in model and how to link it with other components like View and Presenter? Any guidelines?
Here's one way you can go about solving an issue like that.
Your problem is that some code makes sense to go into a presenter, however it's too Androidy, so you can simply interface around it.
What you basically need is two things that can do certain functions.
interface CapturingSoundPlayer {
void playSound();
}
interface ImageCapturer {
void captureImage();
}
Please note that names and method signatures are up to you and what you need, I am merely using them to make a point.
Now it's perfectly safe for your application to have those two interfaces as dependencies, they have nothing to do with Android, we have simply take then technology out of the equation and only left the behaviour.
You need to pass these dependencies to your presenter and use them whenever needed.
class Presenter {
private final CapturingSoundPlayer soundPlayer;
private final ImageCapturer capturer;
Presenter(CapturingSoundPlayer soundPlayer, ImageCapturer capturer) {
this.soundPlayer = soundPlayer;
this.capturer = capturer;
}
void onCaptureButtonClicked() {
soundPlayer.playSound();
capturer.captureImage();
}
}
Now the implementation for those interfaces can be completely separate from your Activity, making your view still stupid.
Those interfaces (and their implementation) are simply logical units/entities that your presenter uses to split up the logic. I simply think of the functions of "capture" and "playSound" as simple actions, just like view.showLoading, and your presenter plays an orchestrator, it uses "something" to manipulate the view, which is the view interface, and it uses something else to manipulate sound, which is the interface for doing that.
if repositories are considered to be data sources, then in my opinion those helpers don't fit under that definition.
If you have a utility to retrieve the images that has been captured, that would basically can be considered as a repo for your images, but simply taking an image, is just another action.
You can structure/organise them as you feel fit, but just because you are using MVP, not every class you create has to be either one of those letters (M/V/P).
Sometimes any of those layers will need classes that logical units to do something, so that you have better separation of concerns.
Consider you have quite complex formatting logic, it would make sense to separate that in a separate class other than the presenter, but does that mean that the separate class is now model? It could, but it doesn't have to be.

Runtime: detect all classes from a given package and call certain methods (static and non-static) for each of the classes found

We here (two small teams) are writing an Android library (OpenGL ES 3.1 based graphics effects library, but that's irrelevant to the question). One team writes the Core part (this code ends up in the (*.library.core package) , while another writes the individual effects (each effect is a single .java file in *.library.effects package + some shader code).
Currently the development works like this: each time a new effect gets written (lets say the class that implements it is called EffectBlahBlah), the Core team has to go over their code and, in one place, add a call to a static method EffectBlahBlah.init(), in another place - a call to another static method EffectBlahBlah.getUniforms(), etc etc. There are AFAIK 7 different places where we have to add 7 different calls to certain (static and non-static) methods from the new effect.
Now - having to add 7 lines of code is not the end of the world; however (especially in light of the fact that we are hoping to open the development of the effect part to outside programmers) we are hoping to automatize this in the following way:
have the Core scan the *.library.effect package and come up with a
list of all Effect classes that are there (we know how to do this)
in each of those 7 places in our code, automatically call the
appropriate method for each discovered class.
Now, if not for the static methods (which have to be there) I'd know how to do this: have all Effects extend an abstract class (lets say 'BaseEffect') which declares the 7 methods abstract, in each of the 7 places instantiate each effect in a loop using Class.forName(), cast it to a BaseEffect and call the appropriate method.
However Java does not allow abstract methods to be static. What do you recommend then?
You can use reflection for this. A possible sequence of calls is roughly:
Use Class.forName(name) to get the Class instance describing your class.
Call getMethods() on the Class instance to get the list of methods (or getMethod() to directly get a method, if you can figure out how to use it).
For the entries in the returned list of Method instances, use getModifiers() to check if it's static, and getName() to identify a specific method.
Once you found the desired Method instance, call the invoke() method on it to call the method. For static methods, you can use null for the receiver (first argument).

Is there a way to customize the threshold for ViewPager scrolling?

I am not able to find a way to change the touch threshold for scrolling pages in ViewPager:
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
Looking at the source code, ViewPager has a method called determineTargetPage that checks to see if the move touch gesture distance > threshold range, but looks like there's no way to modify this range.
Any suggestions on how I can control this threshold (if at all possible)?
Going out on a bit of a limb here; I have no doubt that you may have to tweak this concept and/or code.
I will recommend what I did in the comments above; to extend ViewPager and override its public constructors, and call a custom method which is a clone of initViewPager() (seen in the source you provided). However, as you noted, mFlingDistance, mMinimumVelocity, and mMaximumVelocity are private fields, so they can't be accessed by a subclass.
(Note: You could also change these methods after the constructors are called, if you wanted to.)
Here's where it gets a bit tricky. In Android, we can use the Java Reflection API to make those fields accessible.
It should work something like this:
Class clss = getClass.getSuperClass();
Field flingField = clss.getDeclaredField("mFlingDistance"); // Of course create other variables for the other two fields
flingField.setAccessible(true);
flingField.setInt(this, <whatever int value you want>); // "this" must be the reference to the subclass object
Then, repeat this for the other two variables with whatever values you want. You may want to look at how these are calculated in the source.
Unfortunately, as much as I would like to recommend using Reflection to override the private method determineTargetPage(), I don't believe it's possible to do this--even with the expansive Reflection API.

Robolectric Custom Shadow Object

OOTB, Robolectric does not support Locales that well. Therefore, if your app is dependent on locales (which a lot of apps are if they are i18n'nd properly) this can be a royal pain. Long story short, I created my own ShadowFooGeocoder and ShadowFooAddress that allow me to simulate the locale I want. They're basically re-implementations of the existing shadows.
However, when I bind my class as such: bindShadowClass(ShadowFooGeocoder.class), this works great. At runtime, the correct shadow is returned. The problem is that I want to set up the simulations on this object and I'm not sure how. shadowOf(instance) where instance is an injected GeoCoder returns ShadowGeoCoder. I've tried working directly with the ShadowWrangler, but that also returns a ShadowGeocoder.
How can I get at my shadowed class that I've bound through the bindShadowClass(...) call so I can set my expectations (simulations)?
Note: This is a repost of the same question on the Robolectric group here. I posted here because my success rate of getting anyone to answer questions on the group is fairly low. I'm hoping for a better result here.
What I've basically done here is extend ShadowGeocoder like this:
#SuppressWarnings({"UnusedDeclaration"})
#Implements(Geocoder.class)
public class ShadowFooBarGeocoder extends ShadowGeocoder {
// implementation stuff
}
Then I would bind it using the bindShadowClasss(...) and when I retreive the shadow via the static shadowOf(...) call I get back a "ShadowGeocoder" which is an instance of ShadowFooBarGeocoder. I then cast it to that type and perform whatever work I need to.

Android: How to best pass data to a view?

I have a view that displays all the levels of my game. These levels are read by the activity and then passed into the view. I could read them from the view, but it's not really its responsibility, and I'm a fan of separation of concerns.
Right now, I'm calling a setter for this:
((GameView) findViewById(R.id.game)).setLevels(loadLevels());
However, I don't like the fact that the view will be dysfunctional if I forget to call the setter. Is there a better way to pass the levels in?
It is also a bit a matter of preference. Theoretically it's perfectly fine to pass the levels as you're doing. Alternatively, if you need more than just set the levels, but provide further functionalities (i.e. also saving of levels) I normally use a separate class responsible for handling such things (i.e. a Repository, some "Manager" class etc...). This class is then passed into the View on the constructor preferably s.t. one is forced to provide it. Of course, in order to separate things, I use interfaces rather than specific implementations s.t. it may then look as follows:
public class MyView {
public MyView(ILevelLoader levelLoader){
this.levelLoader = levelLoader;
}
...
}
Often, this may not work, because the view is something instantiated by the framework directly rather than by the application. In such a situation you're forced to do it through an appropriate setter. It is some sort of MVC/MVP pattern.
Just for your interest, you might also want to take a look at IoC containers and dependency injection. Guice provided by Google is a nice framework I've already used on Android.
I hope I didn't miss the point, but here goes:
Generally you have either a function setting something (like the text for a textview), or an attribute you set in the xml.
Take a look over at this answer I got on a question: How to layout a 'grid' of images in the center of the screen
There are some things the custom view needs, but lets take an example: 'numColumns'.
you can set it using setNumColumns (that would be the equivalent of your loadLevels() ? )
you can ignore it, it'll revert to default.
you can set it as an attribute lik so: app:numColumns="3"
You can try to use the attribute or the default in the class to accomplish this.
Make your view an abstract class with an abstract method getLevels()? This way, when you instantiate the class if you forget to pass the levels in your code won't compile.
Whether or not this is better is a matter of taste I guess :)

Categories

Resources