2016-04-27 13 views
0

Ich arbeite an einem 2D-Spiel und ich versuche, die Ansicht zu machen, wo ich zeichne und alles zu aktualisieren sagen die Aktivität, die es enthält, dass das Spiel endete und ein Pop-up auf der Bildschirm. Das Problem ist, dass ich nicht weiß, wie man auf die Methode in der Aktivität von der Ansicht aus zugreift, weil sie an verschiedenen Threads arbeiten.android - Call-Methode in Sicht von Aktivität

Der Code sieht mehr oder weniger so aus und ich möchte auf die Methode displayFrame() von der View-Klasse zugreifen. Die Methode im echten Code führt mehr Operationen mit anderen textViews usw. durch, auf die nur die Aktivität Zugriff hat.

public class MainActivity extends Activity{ 

    private MyView myView; 
    RelativeLayout finalFrame; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     myView = new MyView(this.getApplicationContext()); 
     this.setContentView(myView); 

     finalFrame = (RelativeLayout) findViewById(R.id.framefinal); 
    } 

    private void displayFrame(){ 
     this.finalFrame.setVisibility(View.VISIBLE); 
    } 
} 

public class MyView extends SurfaceView implements SurfaceHolder.Callback{ 
    private MyThread myThread; 
    private boolean finished = false; 

    public MyView(Context context) { 
     super(context); 

     getHolder().addCallback(this); 
     this.myThread = new MyThread(getHolder(), this); 

     this.myThread.setRunning(true); 
    } 

    public void update() { 
     this.finished = someMethod(); 
     if(this.finished){ 
      MainActivity.displayFrame(); 
     } 
    } 

    public void draw(Canvas canvas){ 
     //draw something 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 

    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 

    } 
} 

public class MyThread extends Thread{ 
    private MyView myView; 
    private SurfaceHolder surfaceHolder; 
    private boolean running = false; 
    private static Canvas canvas; 

    public MyThread(SurfaceHolder surfaceHolder, MyView myView){ 
     super(); 
     this.surfaceHolder = surfaceHolder; 
     this.myView = myView; 
    } 

    @Override 
    public void run(){ 
     while(running){ 
      canvas = null; 

      try { 
       canvas = this.surfaceHolder.lockCanvas(); 
       synchronized (surfaceHolder) { 
        this.myView.update(); 
        this.myView.draw(canvas); 
       } 
      } catch (Exception e) {e.printStackTrace();} 
      finally{ 
       if(canvas!=null) 
       { 
        try { 
         surfaceHolder.unlockCanvasAndPost(canvas); 
        } 
        catch(Exception e){e.printStackTrace();} 
       } 
      } 
     } 
    } 

    public void setRunning(boolean running){ 
     this.running = running; 
    } 
} 
+0

public class MainActivity versuchen Aktivität erweitert { public class MainActivity erstreckt Aktivität {ist wie das ist, oder einfach nur einfügen Problem – Haroon

+0

es ist nicht ... sorry: P es bearbeitet (nur ein Pastenproblem) – TBone91

Antwort

1

Der einfachste Weg, dies zu tun ist, eine Listener-Schnittstelle in Ihrer Ansicht zu definieren und die Tätigkeit, die ihn umsetzen lassen. Dann kannst du die Aktivität, die dein Spiel beendet hat, benachrichtigen und die entsprechende Logik ausführen.

public class MyView extends SurfaceView implements SurfaceHolder.Callback { 

    // your other fields 
    private GameListener mGameListener; 

    public void setGameListener(GameListener gameListener) { 
     mGameListener = gameListener; 
    } 

    public void update() { 
     // your logic 
     if (mGameListener != null) { 
      // calling onGameEnd on the main thread 
      post(new Runnable() { 

       public void run() { 
        mGameListener.onGameEnd(); 
       } 

      }); 
     } 
    } 

    // rest of your class as it is 

    public interface GameListener { 

     void onGameEnded(); 

    } 
} 

public class MainActivity extends Activity implements GameListener { 

    // the rest of your class 

    public void onGameEnded() { 
     // call the method you need 
    } 
} 
+0

Das hat perfekt funktioniert. Danke :) – TBone91

+0

Update: Das Layout ist konstruiert, aber nicht gezeichnet .... Ich kann auf die Schaltflächen auf der Ansicht klicken, aber ich kann es nicht grafisch sehen oder irgendetwas, das es enthält – TBone91

+0

Welches Layout ist nicht genau gezeichnet? –

0
public class MyView extends SurfaceView implements SurfaceHolder.Callback{ 
private MyThread myThread; 
private boolean finished = false; 
private Context context; 

public MyView(Context context) { 
    super(context); 
    this.context=context; 

    getHolder().addCallback(this); 
    this.myThread = new MyThread(getHolder(), this); 

    this.myThread.setRunning(true); 
} 

runOnUiThread(new Runnable(){ 
@Override 
public void run(){ 
    update(); 
} 
}); 

    public void update() { 
    this.finished = someMethod(); 
    if(this.finished){ 
     MainActivity mainActivity = (MainActivity) context; 
     mainActivity.displayFrame(); 
    } 
} 

public void draw(Canvas canvas){ 
    //draw something 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 

} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 

} 
} 

Können Sie diese

+0

dies funktioniert nicht, weil ich den Kontext zu MainActivity – TBone91

+0

nicht werfen kann, was du meinst, du kannst nicht werfen, was verhindert, dass du es tust? – Haroon

+0

scheint es, dass sich der Kontext geändert hat und ich einen Fehler bekomme, der besagt, dass es nicht gecastet werden kann. – TBone91