Variabele is toegankelijk binnen de innerlijke klasse. Moet definitief worden verklaard

Ik krijg een compilatiefout in mijn onClick.

Hier is de code.

public class fieldsActivity extends Activity {
Button addSiteButton;
Button cancelButton;
Button signInButton;
/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // to create a custom title bar for activity window
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.fields);
    // use custom layout title bar
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar);
    Pager adapter = new Pager();
    ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
    mPager.setAdapter(adapter);
    mPager.setCurrentItem(1);
    addSiteButton = (Button) findViewById(R.id.addSiteButton);
    addSiteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           mPager.setCurrentItem(2, true); //Compilation error happens here.
        }
    });
    cancelButton = (Button) findViewById(R.id.cancel_button);
    signInButton = (Button) findViewById(R.id.sign_in_button);
}

Antwoord 1, autoriteit 100%

Als je het niet definitief wilt maken, kun je er altijd een globale variabele van maken.


Antwoord 2, autoriteit 52%

Je kunt de variabele definitief declareren of er een instantie (of globale) variabele van maken. Als je het definitief verklaart, kun je het later niet meer wijzigen.

Elke variabele die in een methode is gedefinieerd en toegankelijk is voor een anonieme innerlijke klasse, moet definitief zijn. Anders zou je die variabele in de binnenste klasse kunnen gebruiken, niet wetende dat als de variabele verandert in de binnenste klasse, en deze later in het omsluitende bereik wordt gebruikt, de wijzigingen die in de binnenste klasse zijn aangebracht, niet blijven bestaan in het omsluitende bereik. Kortom, wat er in de innerlijke klas gebeurt, blijft in de innerlijke klas.

Ik heb hier een uitgebreide uitleggeschreven . Het verklaart ook waarom instantie- en globale variabelen niet definitief hoeven te worden verklaard.


Antwoord 3, autoriteit 33%

De fout zegt alles, verander:

ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

naar

final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

Antwoord 4, autoriteit 21%

Hier is een grappig antwoord.

Je kunt een laatste array met één element declareren en de elementen van de array blijkbaar zo veel veranderen als je wilt. Ik weet zeker dat het de reden verbreekt waarom deze compilerregel in de eerste plaats is geïmplementeerd, maar het is handig als je in een time-bind zit zoals ik vandaag was.

Ik kan hier eigenlijk geen krediet voor claimen. Het was de aanbeveling van IntelliJ! Voelt een beetje hacky aan. Maar het lijkt niet zo slecht als een globale variabele, dus ik vond het de moeite waard om het hier te vermelden. Het is maar één oplossing voor het probleem. Niet per se de beste.

final int[] tapCount = {0};
addSiteButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       tapCount[0]++;
    }
});

Antwoord 5, autoriteit 3%

Zoals @Veger al zei, je kunt het finalmaken, zodat de variabele kan worden gebruikt in de innerlijke klasse.

final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);

Ik noemde het pagerin plaats van mPageromdat je het gebruikt als een lokale variabele in de onCreatemethode. Het voorvoegsel mis gewoonlijk gereserveerd voor klassenlidvariabelen (d.w.z. variabelen die aan het begin van de klasse worden gedeclareerd en beschikbaar zijn voor alle klassenmethoden).

Als je echt een klasselidvariabele nodig hebt, werkt het niet om deze definitief te maken, omdat je findViewByIdpas kunt gebruiken om de waarde ervan in te stellen tot onCreate. De oplossing is om geen anonieme inner class te gebruiken. Op deze manier hoeft de variabele mPagerniet definitief te worden verklaard en kan deze door de hele klas worden gebruikt.

public class MainActivity extends AppCompatActivity {
    private ViewPager mPager;
    private Button mButton;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...
        mPager = (ViewPager) findViewById(R.id.fieldspager);
        // ...
        mButton.setOnClickListener(myButtonClickHandler);
    }
    View.OnClickListener myButtonClickHandler = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mPager.setCurrentItem(2, true);
        }
    };
}

Antwoord 6

   public class ConfigureActivity extends Activity {
        EditText etOne;
        EditText etTwo;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_configure);
            Button btnConfigure = findViewById(R.id.btnConfigure1);   
            btnConfigure.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            configure();
                        }
                    });
    }
    public  void configure(){
            String one = etOne.getText().toString();
            String two = etTwo.getText().toString();
    }
}

Other episodes