Tytuł mówi wszystko. Otrzymuję błąd kompilacji w moim onClick
.
Oto kod.
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);
}
Odpowiedzi:
Jeśli nie chcesz, aby była ostateczna, zawsze możesz po prostu ustawić ją jako zmienną globalną.
źródło
Możesz zadeklarować zmienną jako ostateczną lub uczynić ją zmienną instancji (lub globalną). Jeśli uznasz to za ostateczne, nie będziesz mógł go później zmienić.
Każda zmienna zdefiniowana w metodzie i udostępniona przez anonimową klasę wewnętrzną musi być ostateczna. W przeciwnym razie możesz użyć tej zmiennej w klasie wewnętrznej, nie wiedząc, że jeśli zmienna zmieni się w klasie wewnętrznej, a następnie zostanie użyta później w otaczającym zakresie, zmiany wprowadzone w klasie wewnętrznej nie zostaną zachowane w otaczającym zakresie. Zasadniczo to, co dzieje się w klasie wewnętrznej, pozostaje w klasie wewnętrznej.
Napisałem tutaj bardziej szczegółowe wyjaśnienie . Wyjaśnia również, dlaczego zmienne instancji i globalne nie muszą być deklarowane jako ostateczne.
źródło
Błąd mówi wszystko, zmień:
do
źródło
final
w języku Java mów. Wraz z brakiem parametrów przez odniesienie ta reguła zapewnia, że lokalne są przypisywane tylko w metodzie, do której należą. Dzięki temu kod jest bardziej czytelny.addSiteButton.setOnClickListener(new View.OnClickListener() {
Czy masz pojęcie, dlaczego tak się dzieje?null
. Prawdopodobnie findViewById wracanull
. Nie mogę powiedzieć nic więcej, nie będąc programistą Androida; Radzę otworzyć osobne pytanie. Z pewnością nie ma to nic wspólnego z klasami wewnętrznymi, final, et similia .Oto zabawna odpowiedź.
Możesz zadeklarować ostateczną jednoelementową tablicę i zmienić elementy tablicy, jak tylko chcesz. Jestem pewien, że łamie to powód, dla którego ta reguła kompilatora została zaimplementowana w pierwszej kolejności, ale jest przydatna, gdy jesteś w ograniczonym czasie, tak jak ja dzisiaj.
Właściwie nie mogę żądać uznania za ten. To była rekomendacja IntelliJ! Czuje się trochę hacky. Ale nie wygląda tak źle jak zmienna globalna, więc pomyślałem, że warto o tym tutaj wspomnieć. To tylko jedno rozwiązanie problemu. Niekoniecznie najlepsza.
źródło
Jak powiedział @Veger, możesz sprawić,
final
że zmienna będzie używana w klasie wewnętrznej.Nazwałem to
pager
raczej niżmPager
dlatego, że używasz jej jako zmiennej lokalnej wonCreate
metodzie.m
Prefiks jest cusomarily zarezerwowane dla zmiennych składowych klasy (czyli zmienne, które są zadeklarowane na początku klasy i są dostępne dla wszystkich metod klasy).Jeśli faktycznie potrzebujesz zmiennej składowej klasy, nie działa, aby była ostateczna, ponieważ nie możesz użyć
findViewById
do ustawienia jej wartości doonCreate
. Rozwiązaniem jest nieużywanie anonimowej klasy wewnętrznej. W ten sposóbmPager
zmienna nie musi być deklarowana jako ostateczna i może być używana w całej klasie.źródło
źródło