Search code examples
androidandroid-activity

How to call on activity method from view?


I have done I game in which I want to call on a method I have in a view from another view. I figured I would somehow have to send the "first view" into the "second view" through the my MainActivity in order for the second view to be able to call on the first view methods. However, I couldn't come up with any way of sending in the first view to the second view through my MainAcitivity, so I decided to change tactics. I now tried to have a function in my MainActivity to handle the interection between the views, but once again I was not able to call on the method from the second View.

Therefore my question is how do you send a view into another view through an Activity, or If that's not possible how do you call on an activity method through a view?

Here is the code (I added some comments to better show the problem I'm having):

public class MainActivity extends AppCompatActivity {

    private FishView gameView;
    private SmallBall smallBall ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout screen = findViewById(R.id.gameScreen);
        gameView = new FishView(this);
        smallBall = new SmallBall(this);
        screen.addView(gameView); // first view
        screen.addView(smallBall); //second view
    }

    //this is the method I want to reach through the View
    public void handleAvoidedBall(){
        gameView.avoidedBall();
    }

}

public class SmallBall extends View {

    private final Bitmap sodaCan;
    private final static long smallBallPeriod = 60;
    private final Handler handler = new Handler();

    public SmallBall(Context context) {
       super(context);
       Paint smallBall = new Paint();
       smallBall.setColor(Color.GRAY);
       smallBall.setAntiAlias(false);
       resetBall();
       sodaCan = BitmapFactory.decodeResource(getResources(),R.drawable.sodacan);

       Timer movementTimer = new Timer();
       movementTimer.scheduleAtFixedRate(smallBallTask, 0, smallBallPeriod);
    }


    private final TimerTask smallBallTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                @Override
                public void run() {
                    invalidate();
                    if (isBallLanded()){
                    //Here I want to call on a handleAvoidedBall() in MainActivity        
                    //OR simply have gameView here if possible

                      // gameView.avoidedBall();
                      //OR
                      //SomeMainAcitvityObject.handleAvoidedBall();  
                    }

                }
            });
        }
    };

     @Override
    protected void onDraw(Canvas canvas) {
    ..... //Do stuff}

}

So as I hopefully have explained somewhat decent now, I'm wondering how to either send gameView into the SmallBall view OR how to call on handleAvoidedBall() in MainActivity from the SmallBall view?

Thank you for your time and hope you have a wonderful day!


Solution

  • As @LukeWaggoner mentioned, you should consider using listeners instead of making view static in your activity.

    You told us, that you'd like to add more than one SmallBall views, so I figure that you don't want to write a listener's code for each of them.

    It is easily doable with MainActivity implementing SmallBallListener.

    Listener:

    public interface SmallBallListener {
        void onAvoidedBall();
    }
    

    SmallBall class:

    public void setListener(SmallBallListener listener){
        this.listener = listener;
    }
    

    MainActivity:

    public class MainActivity extends AppCompatActivity implements SmallBallListener {
    
        private FishView gameView;
        private SmallBall smallBall ;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            RelativeLayout screen = findViewById(R.id.gameScreen);
            gameView = new FishView(this);
            screen.addView(gameView); // first view
    
            // Add 10 small ball views
            for(int i = 0; i < 10; i++) {
              SmallBall ball = new SmallBall(this);
              ball.setListener(this); // MainActivity is a listener here, so each ball has the same listener code
              screen.addView(ball);
            }
        }
    
        //this is the method I want to reach through the View
        public void handleAvoidedBall() {
            gameView.avoidedBall();
        }
    
        @Override
        public void onAvoidedBall() { // this is the SmallBallListener method
          this.handleAvoidedBall();
        }
    }
    

    So whichever SmallBall view call listener.onAvoidedBall(), it will fire onAvoidedBall() method in MainActivity class.