Android: Implicit super constructer undefined for default constructer - java

Ok, first of all, I know you have seen this problem before, and I'll tell you why this is different. I have a class, DrawView (followed some Canvas tutorials) and it extends View. Ok, but I want a separate class to handle all the animations, so I can just call, for example, mainMenuAnimation() and it will draw it instead of coding it to the actual game loop. Well, if I create a class for holding the animations, Animations.java, and extend DrawView, I get an error from Eclipse:
Implicit super constructor DrawView() is undefined for default constructor. Must define an explicit constructor
The problem is, if I call the DrawView() constructor, it makes a new Animations.java, and so on. (Maybe I should define Animations a = new Animations()? Not sure if I would run into problems later on though). So, if I add an empty constructor in DrawView(), it gives me this error:
Implicit super constructor View() is undefined for default constructor. Must define an explicit constructor
I have no idea what to do, help?
Okay, the reason why I instanced Animations in the DrawView() constructor is because Animations' constructor has to be super(context) and the only way to access the context is through the DrawView() constructor.
DrawView constructor code:
Paint paint; //initialize EVERYTHING
Resources res;
Bitmap title;
Rect titleRect;
boolean inMainMenu, issetBackgroundDrawableSupported;
List<BitmapDrawable> mainMenuAnimation;
int mainMenuAnimationIndex = 0;
public DrawView(Context context) {
super(context);
res = getResources(); //required stuff
title = BitmapFactory.decodeResource(getResources(),R.drawable.title); //title stuff
titleRect = new Rect(res.getDisplayMetrics().widthPixels/2 - title.getWidth()*10 , 100, res.getDisplayMetrics().widthPixels/2 + title.getWidth()*10, 200); //left, top, right, bottom
inMainMenu = false; //main menu stuff
issetBackgroundDrawableSupported = true;
mainMenuAnimation = new ArrayList<BitmapDrawable>();
mainMenuAnimation.add(new BitmapDrawable(getResources(), BitmapFactory.decodeResource(res, R.drawable.mainmenu_background_1)));
mainMenuAnimation.add(new BitmapDrawable(getResources(), BitmapFactory.decodeResource(res, R.drawable.mainmenu_background_2)));
mainMenuAnimation.add(new BitmapDrawable(getResources(), BitmapFactory.decodeResource(res, R.drawable.mainmenu_background_3)));
Animations animations = new Animations(getApplication());
}
And the Animations.java code:
public class Animations extends DrawView {
//define animations
#SuppressLint("NewApi")
public void mainMenuScroll(Canvas canvas) {
inMainMenu = true;
//draw main menu here
if (inMainMenu = true) { //main menu loop
if (issetBackgroundDrawableSupported) { //check if background drawing is supported
try {
setBackgroundDrawable(mainMenuAnimation.get(mainMenuAnimationIndex));
} catch (Exception e){
issetBackgroundDrawableSupported = false; //say it is unsupported
setBackground(mainMenuAnimation.get(mainMenuAnimationIndex));
}
}
else {
setBackground(mainMenuAnimation.get(mainMenuAnimationIndex));
}
mainMenuAnimationIndex++;
if (mainMenuAnimationIndex == 3) { //restart main menu animation
mainMenuAnimationIndex = 0;
}
}
}
}
Ok, I realized another Eclipse notification, might be useful. It says:
Custom view com/spng453/agenericrpg/Animations is missing constructor used by tools: (Context) or (Context,AttributeSet) or (Context,AttributeSet,int)
Sounds relevant, but I'm not sure what to do about it.

All Views run within the context of a Context. (I guess that's why it's called that =P). This includes your custom View.
You're going to want to define an Animations constructor that takes a Context, so you can pass it through to the super constructors. This is the cleanest way to get rid of your errors, and will also fix the last problem you mentioned (namely, the Android system is trying to instantiate your class, but it doesn't know what to do with a View that doesn't take a Context in its constructor).
public Animations(Context context) {
super(context);
}

Related

How notify current layer for position change

I'm currently using osmdroid to display current positioning.
Based on the following example i tried to optimize the system a little bit by not constructing the ItemizedOverlay<OverlayItem> and ArrayList<OverlayItem> each time my location is changed, but construct them only once in the constructor, and later on simply add points to my ArrayList variable.
Here's how it looks now:
private void InitializeMarkersOverlay() {
mOverlayItemArrayList = new ArrayList<OverlayItem>();
ItemizedOverlay<OverlayItem> locationOverlay =
new ItemizedIconOverlay<OverlayItem>(this, mOverlayItemArrayList, null);
mMapView.getOverlays().add(locationOverlay);
}
and when a new location arrives:
private void AddPointToOverlay(GeoPoint gPt, boolean bShouldClearList) {
OverlayItem overlayItem = new OverlayItem("", "", gPt);
Drawable markerDrawable = ContextCompat.getDrawable(this, R.drawable.pin);
overlayItem.setMarker(markerDrawable);
// first time initializer
if(bShouldClearList) {
mOverlayItemArrayList.clear();
}
mOverlayItemArrayList.add(overlayItem);
}
Since my mMapView already has a pointer to mOverlayItemArrayList i was hoping that my mapview's layer would be automatically notified regarding the change. but nothing actually happens. Only by recreating the objects, i get to see the pin.
Adding to the list does not work because ItemizedIconOverlay need to do some operations on addition. You can check source code for ItemizedIconOverlay.
You can see there is call to populate() in addItem method (and all other methods which are manipulating with items).
public boolean addItem(final Item item) {
final boolean result = mItemList.add(item);
populate();
return result;
}
But populate() is an implementation detail and is marked as protected so you cannot call it directly.
Correct solution would be:
Don't keep reference to the list but to ItemizedIconOverlay
instance.
Use mLocationOverlay.addItem(overlayItem)
You may need to call mapView.invalidate() after adding new point.
I got it working by accessing the overlay directly from the mapview object, not sure why exactly, as i was hoping mMapView.getOverlays() would hold a reference to the ItemizedIconOverlay and its itimized array
if(mMapView.getOverlays().size() > 0) {
((ItemizedIconOverlay<OverlayItem>)mMapView.getOverlays().get(0)).removeAllItems();
((ItemizedIconOverlay<OverlayItem>)mMapView.getOverlays().get(0)).addItem(overlayItem);
}
}

Modifying ListView's smoothScrollToPosition transition

The default behavior for a ListView when calling smoothScrollToPosition on it, it to move with linear speed to the specified position.
Digging into ListView's and AbsListView's code, I can see that this behavior takes place because AbsListView uses a PositionScroller object (implementing AbsPositionScroller) that in turn uses a FlingRunnable object on which the method startScroll gets called with linear = true (which ends up having its OverScroller object use a LinearInterpolator).
I want to modify this behavior, and have it use for example the Scroller.ViscousFluidInterpolator class that the OverScroller class would use by default, but I'm not finding a way to do it.
I see that AbsListView defines a AbsPosScroller interface (that himself implements with a PositionScroller class), that I could try to implement with my own class to have it end up using the ViscousFluidInterpolator, but for some reason this interface is private to the package android.widget...
Am I missing something, or does it look like this has been written in a way that prevents it to have a behavior like that one be customized? Why would they bother writing up a AbsPosScroller interface in first place?
Any leads on how could I get the behavior I want without having to write my entire ListView class from scratch?
While I still don't know why would they write these components in a way that their behavior can't be customized easily when it would've been pretty easy to do it, I came up with an alternative implementation of smoothScrollToPosition (awesomeScrollToPosition in the code below) that does what I needed.
This solution makes use of an OverScroller object (that internally uses the ViscousInterpolator unless a different one is specified) to provide the effect I was looking for, for scrolling to elements within the visible page (the solution to achieve scrolling across pages is more convoluted, but this works for the problem I needed to solve).
I basically implemented a Runnable class private to my own ListView subclass (MyListView) that deals with the scrolling animation, re-posting itself to the UI thread for as long as the animation needs to run, using scrollingListBy in every frame (this method is only available since KitKat [19] though).
public class MyListView extends ListView {
private MyScroller mScroller;
/* MyListView constructors here */
public void awesomeScrollToPosition(int position, int duration) {
if (getChildCount() == 0) {
// Can't scroll without children (visible list items)
return;
}
if (mScroller == null) {
mScroller = new MyScroller();
}
if (mScroller.isRunning()) {
mScroller.stop();
}
int firstPos = getFirstVisiblePosition();
int lastPos = getLastVisiblePosition();
if (!(firstPos <= position && position <= lastPos)) {
// Can't scroll to an item outside of the visible range this easily
return;
}
int targetPosition = position - firstPos;
int targetTop = getChildAt(targetPosition).getTop();
mScroller.start(targetTop, duration);
}
private class MyScroller implements Runnable {
OverScroller mScroller;
boolean mRunning;
int mLastY;
MyScroller() {
mScroller = new OverScroller(getContext());
mRunning = false;
}
void start(int y, int duration) {
// start scrolling
mLastY = 0;
mScroller.startScroll(0, 0, 0, y, duration);
mRunning = true;
postOnAnimation(this);
}
boolean isRunning() {
return mRunning;
}
#Override
public void run() {
boolean more = mScroller.computeScrollOffset();
final int currentY = mScroller.getCurrY();
// actual scrolling
scrollListBy(currentY - mLastY);
if (more) {
mLastY = currentY;
// schedule next run
postOnAnimation(this);
} else {
stop();
}
}
public void stop() {
mRunning = false;
removeCallbacks(this);
}
}
}

Java: Accessing resources and the Law Of Demeter

Overview
In my (Android) Java game, I have a class called resources. As the name suggests, this class holds the resources for the game. All of my OpenGL objects (Sprites) are created here
It's looks something like the following (obviously, this is a simplified version compared to that which appears in the real project):
public class Resources {
Hero hero;
Enemy enemy;
MenuButtons mainMenuButtons;
Background background;
Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
}
So, within my mainMenu scene, I need access my objects, so we may see something like this:
public class mainMenu implements Scene {
Resources resources;
public mainMenu(Resources resources){
this.resources = resources;
}
#Override
public void render(){
resources.background.draw();
resources.hero.draw();
resources.enemy.draw();
mainMenuButtons.draw();
}
#Override
public void updateLogic(){
resources.hero.move();
resources.enemy.move();
resources.mainMenubuttons.animate();
}
}
Now, the above method is just one way to get access to the objects in resources and their methods. But does this actually break the Law of Demeter? If not, why not? If so, what is the best way to get access to these objects in a way that does not violate the LOD?
Accessors?
One option (which I've ruled out TBH - see below) is placing accessor methods into my resources class. So that I could do something like:
resources.drawBackround();
I have a lot of objects and I need an accessor for each method/variable of each object. Not really practical, it seems like I'm writing a ton of extra code and most importantly, it makes the resources class ridiculously long as it becomes filled with these accessors. Therefore, I'm not going down this road.
Passing in objects into the scene's constructor
Of course, I can also do something like this:
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(hero, enemy, mainMenuButtons, background);
So I can simply do this:
background.draw(); //etc....
This is workable for simple scene's (such as menu systems that don't require a lot of objects) but for the main game, it could quickly become a mess as I'd have to pass references to some 30+ objects into the constructor which doesn't really sound quite right......
So I would really appreciate if someone could point out the best way to proceed and why.
So I would really appreciate if someone could point out the best way to proceed and why.
The best way, in my opinion, is to keep the Resources class, make all objects private to not break the law and write accessors (but not for every object like you already ruled out).
I have a lot of objects and I need an accessor for each method/variable of each object. Not really practical, it seems like I'm writing a ton of extra code and most importantly, it makes the resources class ridiculously long as it becomes filled with these accessors. Therefore, I'm not going down this road.
I assume many objects are of the same class. So you do not have to make an accessor for every object what would really blow up the class.
I a game you normally have a hero, one or more enemies and many sprites.
public class Resources {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
private Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
public Hero getBackground() {
return background;
}
public Hero getHero() {
return hero;
}
public List<Enemy> getEnemies() {
ArrayList<Enemy> list = new ArrayList<Enemy>();
list.add(enemy);
list.add(next_enemy);
return list;
}
public List<Sprite> getSprites() {
ArrayList<Sprite> list = new ArrayList<Sprite>();
list.addAll(enemy.getActiveSprites());
return list;
}
}
Instead of getHero() and getEnemy() you could also make a getActor() method if Hero and Enemy are derived from the same class.
The getSprites() method is just an example how it could look like.
If that solution is not going to work for you, I have another suggestion.
Make the Resources class do some work.
public class ResourceManager {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
private Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(this);
}
public void render(Scene scene) {
this.background.draw();
if (scene != mainMenu) {
this.hero.draw();
this.enemy.draw();
}
this.mainMenuButtons.draw();
}
public void updateLogic(Scene scene){
this.hero.move();
this.enemy.move();
this.mainMenubuttons.animate();
}
}
The mainMenu then calls logic methods directly in the RescourceManager class.
public class mainMenu implements Scene {
ResourceManager resourceManager;
public mainMenu(ResourceManager resourceManager){
this.resourceManager = resourceManager;
}
#Override
public void render(){
resourceManager.render(this);
}
#Override
public void updateLogic(){
resourceManager.updateLogic(this);
}
}
I hope my suggestions helped you a bit figure out how to continue with your project.
You could use dependency injection and eliminate your Resources class. Then you can call functions on your fields and wouldn't be in violation of the Law of Demeter.
Here is an example using constructor injection:
public class MainMenu implements Scene {
Background background;
Hero hero;
Enemy enemy;
MenuButtons buttons
public mainMenu(Background background, Hero hero, Enemy enemy, MenuButtons buttons){
this.background = background;
this.hero = hero;
this.enemy = enemy;
this.buttons = buttons;
}
#Override
public void render(){
this.background.draw();
this.hero.draw();
this.enemy.draw();
this.mainMenuButtons.draw();
}
#Override
public void updateLogic(){
this.hero.move();
this.enemy.move();
this.mainMenubuttons.animate();
}
}
With dependency injection, you pass instances into constructors and functions instead of "newing" them inside your class. You need to manage your instances somewhere though, and there are plenty of libraries that will do that for you. Dagger is a popular one for Android: http://square.github.io/dagger/
The idea of passing a list isn't a bad first step, but it's not sufficient. Game developers have a (somewhat controversial) concept of a structure called a "scene graph" that helps them keep track of their resources (among other things). https://en.wikipedia.org/?title=Scene_graph
It's a pretty complicated concept, but you're going to need to learn about it sooner or later. There's a lot of good advice on gamedev.stackexchange.com, so I'd suggest you take a peek over there.
Here's a nice YouTube video tutorial on the subject. https://www.youtube.com/watch?v=ktz9AlMSEoA
You could create an Drawer class that handles the drawing of all the objects. Your scene objects simply need to feed the Drawer the objects that I assume are Drawable.
public class Drawer {
public void drawObjects(Drawable... objects) {
for(Drawable drawable : objects) {
drawable.draw();
}
}
}
This is then used by Scene to draw those objects.
public class mainMenu implements Scene {
Resources resources;
Drawer drawer;
...
public void render() {
drawer.drawObjects(resources.background,
resources.hero,
resources.enemy,
resources.mainMenuButtons);
}
...
}
A similar strategy, using an Updater, can applied for the other methods. If your updateLogic() method makes as simple of calls as it looks, you can definitely do the same thing, by making all those objects inherit from an Updateable interface.
public interface Updateable {
void update();
}
Hero's and Enemy's update() methods could simply call their move() methods, while MenuButtons's update() could delegate to animate(), etc.
Obviously, if you like, you can use some sort of collection instead of varargs for the parameter of Drawer's drawObjects(). I just like the nice fluency made possible by the varargs, since you don't have to create the collection.
For other tips for keeping code in line with the Law of Demeter, check out this article: Law of Demeter and How to Work With It
I like the concept of a ResourceManager. But a ResourceManager should be responsilbe for loading Resources, caching and freeing them. Rendering is definitly a Method of a Render Object.
So the Scence - render Method could delegate the rendering to it after instantiating a Renderer and feed it with Drawables as the Renderer does not render Resources but renderable objects.
Say:
class MainMenu implements Scene {
Renderer sceneRenderer = new Renderer();
AnimatedRenderer animatedRenderer = new AnimatedRenderer();
ResourceManager resourceManager = ResourceManager.getInstance();
List<Resource> resources;
List<Drawable> renderedObjects;
GameObjectController gameObjectController;
void initializeScene() {
resources = resourceManager.getResources();
renderedObjects = resourcesAsRenderables();
sceneRenderer.setDrawables(renderedObjects);
}
List<Drawable> resourcesAsRenderables() {
// if resources are not directly renderable, do decoration etc
// and return a List of Drawable
}
#Override
public void render(){
sceneRenderer.render();
}
#Override
public void updateLogic(){
moveGameObjects();
doAnimations();
}
protected void moveGameObjects() {
gameObjectController.moveAllObjects(this, resources);
}
protected void doAnimations() {
animatedRenderer.render(resources);
}
class ResourceManager {
private static ResourceManager instance = null;
List<Resource> resources;
public ResourceManager getInstance() {
if(instance == null) {
instance = new ResourceManager();
instance.loadResources();
}
return instance;
}
private void loadResources() {
resources = new LinkedList<Resource>();
resources.add(new Hero());
....
}
public List<Resource> getResources() {
return resources;
}
}
This clearly separates the logic and responsibilities for the tasks carried out during the scene lifecycle. A resource manager which is responsible for retrieving resources and as they may take long loading times does things like caching or freeing in low memory situations hiding the details from the client. A renderer which is responsible for displaying the objects and a controller which is responsible for moving the objects. The controller itself may implement handlers for keyboard events but that is not something which must be transparent to the scene. The renderer may swap backgrounds in or out or scale or set lighting effects but the scene only calls its render method. The animated renderer is responsible for starting , rendering and stopping animations.
Change this:
public void render(){
resources.background.draw();
resources.hero.draw();
resources.enemy.draw();
mainMenuButtons.draw();
}
#Override
public void updateLogic(){
resources.hero.move();
resources.enemy.move();
resources.mainMenubuttons.animate();
}
With this:
public void render(){
resources.render();
}
#Override
public void updateLogic(){
resources.update();
}
ResourceManager don't have to know what's inside Resources. It may be one enemy or ten, it doesn't care to ResourceManager.
And so in 'Resource' you can do:
public void update(){
hero.update();// Cause hero may, or may not move, he makes the choice
enemy.update();//...
mainMenubuttons.update();//.
}
public void render(){
...
}
More than this! you could change the "Resource" implementation with an interface and you will be programming for interfaces and not for implementations, which is cool! This way you can have a 'Resources' for in-game and another one for menus that will be used in same way: Only changing, at runtime, the concrete Resources you will be in a menu or in game!
Anyway, not always is needed to fill Demeter.
As can be seen your Resources dont need to be recreated, instead they do use some resources that cant be reloaded (probably images).
You should share the images object within a Resource class, and create your objects within a Scene class, on the constructor of the entities you can get the shared resource that is pre-loaded.

Java android surfaceview became null when i pass it to another class construct

I have 3 classes one of them is an activity.
Inside activity oncreate
Camera camera = Camera.open();
MovementDetector detector = new MovementDetector(this, camera);
if(detector == null)Log.d(null, "detector null in activity");
MovementResult result = new MovementResult(this, detector);
Inside MovementResult
public class MovementResult extends SurfaceView implements SurfaceHolder.Callback, Runnable {
SurfaceHolder holder;
MovementDetector detector;
public MovementResult(Context context, MovementDetector detectorview) {
super(context);
holder = getHolder();
holder.addCallback(this);
detectorview = detector;
if(detector == null)Log.d(null, "detector null in constructor");
if(detectorview == null)Log.d(null, "detectorview null in constructor");
}
After a long and painful search (becouse i havent checked becouse i dont see the reason...) turned out in the class MovementResult detector is null. Both log shows up in the logcat that you can see in the constructor however the log in the activity dont shows.
So i have an object in an activity that is not null. Then i pass it to another ones constructor and it becomes null there. What can be the reason?
detectorview is the argument passed, detector is the null member.
It seems like you want to set detector to be detectorview, but instead you are setting (the passed) detectorview to be (the null) detector, which is certainly not what you want.

Android - Right design to implement AsyncTask or Thread

I have a getViewBitmap() method that creates a Bitmap with a 3rd party library (which is proprietary) and goes like this:
public Bitmap getViewBitmap(int index) {
Bitmap retBitmap = null;
int width = 400;
int height = 200;
try {
retBitmap = lib.createBitmap(width, height, index);
} catch(BMException e) {
e.printStacktrace();
}
return retBitmap;
}
This method is used for creating two page view bitmap in another method:
public Bitmap getTwoPageBitmap(int firstPageIndex, intSecondPageIndex) {
Bitmap first = getViewBitmap(firstPageIndex);
Bitmap second = getViewBitmap(secondPageIndex);
Bitmap retBitmap = Bitmap.create(800, 400, first.getConfig());
Canvas helperCanvas = new Canvas(splitViewBm);
helperCanvas.drawBitmap(leftPageBitmap, 0, 0, null);
helperCanvas.drawBitmap(rightPageBitmap, leftPageBitmap.getWidth(), 0, null);
return retBitmap;
}
And then finally in initiated method, I have this:
public View createView() {
MyView v = new MyView();
if(pagePortratit) {
v.setPageView(getViewBitmap(0));
} else {
// if page is landscape
v.setPageView(getTwoPageBitmap(0, 1));
}
return v;
}
Now - I wanna make the getViewBitmap(int) method Asynchronous. Since the "lib.createBitmap(int, int, int)" is pretty slow and it blocks the UI, I want the creation of the bitmap (getViewBitmap(int)) to be in another thread, with possibility to interrupt it's work.
What is the correct design for such design so that the method that is actually heavy goes async?
You likely want to subclass AsyncTask (read here) and put your getBitmapView code in the doInBackground() method (#Override). When it's done, have the onPostExecute() method update the View/UI. The logic for determining landscape or portrait will want to be outside the AsyncTask and you'll just want to farm out to the task (using .execute()) which ever view is needed.
That might be one approach.
I think the best thing that you can do is to use AysncTask which allows u to update the UI Directly without special handling for UI Thread update.

Categories