4

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?

futlib
  • 8,258
  • 13
  • 40
  • 55

3 Answers3

2

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.

Juri
  • 32,424
  • 20
  • 102
  • 136
  • I've looked at Guice, but didn't spot what I wanted to do. Did I miss something? – futlib Feb 06 '11 at 17:18
  • No Guice and dependency injection is just related to the comment you state that you like the "separation of concerns" :). Dependency Injection is a too broad topic to be mentioned in the comment here, just look around for it on the web. It's a good practice of coding in terms of creating loosely coupled components. – Juri Feb 06 '11 at 17:23
0

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.

Community
  • 1
  • 1
Nanne
  • 64,065
  • 16
  • 119
  • 163
  • So when I add a setter to my view, I can call it with app:propertyName in XML? That's nice, but I can't imagine how to pass a series of levels there. – futlib Feb 06 '11 at 17:18
0

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 :)

ns476
  • 375
  • 1
  • 3
  • I don't think this will work, because my view is in fact instantiated by the Android SDK - I'm adding it in a XML layout file. – futlib Feb 06 '11 at 17:00