如何从视图调用活动方法?

时间:2019-05-13 20:30:43

标签: android android-activity

我做完我想在另一个视图中调用一个视图中的方法的游戏。我认为我将不得不通过我的MainActivity将“第一视图”发送到“第二视图”,以便第二视图能够调用第一视图方法。但是,我无法通过MainAcitivity提出将第一个视图发送到第二个视图的任何方法,因此我决定更改策略。现在,我试图在MainActivity中使用一个函数来处理视图之间的交互,但是再次无法从第二个View调用该方法。

因此,我的问题是如何通过活动将视图发送到另一个视图,或者如果不可能,如何通过视图调用活动方法?

这是代码(我添加了一些注释以更好地显示我遇到的问题):

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}

}

因此,正如我希望现在已经解释得体面的那样,我想知道如何将gameView发送到SmallBall视图中,或者如何从SmallBall视图中调用MainActivity中的handleAvoidedBall()?

感谢您的时间,希望您有美好的一天!

3 个答案:

答案 0 :(得分:1)

您最好的选择是定义一个在SmallBallView上设置的侦听器。

定义监听器:

public interface BallListener {
    void onAvoided(SmallBall ball);
}

然后在SmallBall类中,您将具有以下方法:

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

实例化SmallBall类后,在活动中调用此方法:

smallBall.setListener(new SmallBallListener(){
    @Override
    public void onAvoided(SmallBall ball){
        // Do stuff here
    }
})

答案 1 :(得分:0)

原来我要做的就是设置:

private FishView gameView;

至:

public static FishView gameView;

然后在SmallBall视图中简单地使用“ MainActivity.gameView”。这也没有给我任何其他警告,所以这也很好。

答案 2 :(得分:0)

如@LukeWaggoner所述,您应该考虑使用侦听器,而不要在活动中将视图设为静态。

您告诉我们,您想添加多个SmallBall视图,所以我认为您不想为每个视图编写侦听器的代码。

使用MainActivity实现SmallBallListener很容易做到。

监听器:

public interface SmallBallListener {
    void onAvoidedBall();
}

SmallBall类:

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();
    }
}

因此,无论哪个SmallBall视图调用listener.onAvoidedBall(),它都会触发MainActivity类中的onAvoidedBall()方法。