Ich möchte meine Variablen an der Spitze meiner class anstatt in der Methode setzen

Ich kann dieses verwirrende Problem anscheinend nicht angehen, ich habe viele Dinge, die ich an der Spitze meines Kurses hinzufügen möchte, um Unordnung zu vermeiden.

Da mehrere Methoden diese Checkbox-Variablen verwenden.

Ich hätte gerne alles oben direkt unter der öffnenden Klammer.

Hier funktioniert was, aber nicht was ich will .:

public class MyClass extends Activity implements View.OnClickListener { //leaving out most code like onCreate. Just pretend it's there. public void checkboth(View view) { CheckBox cb1 = (CheckBox) findViewById(R.id.cb1); CheckBox cb2 = (CheckBox) findViewById(R.id.cb2); cb1.setchecked(true); cb2.setchecked(true); } @Override public void onClick(View v) { } } 

Aber für das Leben von mir kann ich nicht herausfinden, warum ich das nicht tun kann:

 public class MyClass extends Activity implements View.OnClickListener { CheckBox cb1 = (CheckBox) findViewById(R.id.cb1); CheckBox cb2 = (CheckBox) findViewById(R.id.cb2); //leaving out most code like onCreate. Just pretend it's there. public void checkboth(View view) { cb1.setchecked(true); cb2.setchecked(true); } @Override public void onClick(View v) { } } 

   

Sie können Views außerhalb einer Methode wie dieser nicht initialisieren

 CheckBox cb1 = (CheckBox) findViewById(R.id.cb1); CheckBox cb2 = (CheckBox) findViewById(R.id.cb2); 

weil das bedeuten würde, dass diese Zeilen vor onCreate() was dazu führt, dass diese Variablen null und eine NPE casting, wenn Sie versuchen, Methoden für diese Variablen aufzurufen. Dies liegt daran, dass Sie setContentView(R.layout.your_layout) innerhalb von onCreate() und Ihre Views innerhalb dieses layout “live” sind. Dies bedeutet, dass sie nicht initialisiert werden können, bis Ihr layout durch Aufrufen von setContentView() inflated wurde. Sie müssen setContentView() aufrufen, bevor Sie versuchen, Ihre Views zu initialisieren . Es gibt keinen Weg um diesen Teil herum.

Was einige Leute tun können, ist, eine separate function zu erstellen, die diese Variablen initialisiert, nachdem setContentView() aufgerufen wurde. Etwas wie das

 public class MyActivity // declare your Views so they are global to the class TextView tv; // more views @Override public void onCreat(stuff) { // super call setContentView(R.layout.my_layout); init(); 

Dann initialisieren Sie in Ihrer function init() alle Views Sie deklariert haben

 private void init() { tv = (TextView) findViewById(R.id.myTextView); // more initializations } 

Sie können sie aber nur in onCreate() , onResume() oder wo auch immer initialisieren, nachdem setContentView() sie auf diese Weise setContentView() und initialisiert, um sicherzustellen, dass sie alle für andere functionen, Listener, innere classn usw. verfügbar sind. der Activity Und wenn Sie viele Views haben, kann es das “Durcheinander” ein wenig verringern.

findViewById ist eine Methode, die von der Aktivität (oder einer beliebigen Ansichtsgruppe) ausgeführt werden kann, nachdem die Ansicht aufgebläht wurde. Um eine Ansicht auf eine Aktivitätsebene aufzublasen, rufen Sie normalerweise setContentView auf.

Da setContentView noch nicht aufgerufen wurde, sind der Aktivität keine Ansichten zugeordnet.

Hier ist, wie es geht

 public class MyClass extends Activity implements View.OnClickListener { CheckBox cb1; CheckBox cb2; public void onCreate(Bundle sis) { super.onCreate(sis); setContentView(R.layout.whatever); cb1 = (CheckBox) findViewById(R.id.cb1); cb2 = (CheckBox) findViewById(R.id.cb2); } public void checkboth(View view) { cb1.setchecked(true); cb2.setchecked(true); } @Override public void onClick(View v) { } } 

Sie können die Methode (findViewById) hier nicht aufrufen und erwarten einen Nicht-Null-Wert. Die Ansichten werden erst nach dem Aufruf von setContentView (R.layout.my_layout) in android erstellt. Was Sie tun müssen, ist etwa so:

 public class MyClass extends Activity implements View.OnClickListener { CheckBox cb1 = null; CheckBox cb2 = null; //leaving out most code like onCreate. Just pretend it's there. public void onCreate(Bundle savedInstanceState) { super.onCreate(); setContentView(R.layout.my_layout); cb1 = (CheckBox) findViewById(R.id.cb1); cb2 = (CheckBox) findViewById(R.id.cb2); } public void checkboth(View view) { cb1.setchecked(true); cb2.setchecked(true); } @Override public void onClick(View v) { } } 

Wenn Sie die Deklarationen an den Anfang der class verschieben, ändern Sie lokale Variablen in Felder. Diese Felder werden beim Erstellen einer Instanz initialisiert – was bedeutet, dass sie initialisiert werden, “bevor” der Konstruktor ausgeführt wird.

Jetzt können Sie keine Instanzmethoden (wie findViewById ) findViewById bevor der implizite Aufruf von super() beendet wird.

Verschiebe sie zum Konstruktor und die Dinge sollten funktionieren.