2012-03-31 10 views
10

Wewnętrzna klasa to Adapter, wewnętrzna wewnętrzna klasa to Listener. Jak uzyskać dostęp do (ukrytych) elementów/metod adaptera od Listenera?Dwie podwójne zagnieżdżone anonimowe klasy wewnętrzne. Jak zdobyć anonimowych członków klasy pierwszego poziomu?

list.setAdapter(new Adapter() { 
    public View getView() { 
    // ... 
    button.setListener(new Listener() { 
     public void onClick() { 
     Adapter.this.remove(item); 
     } 
    ); 
    } 
}); 

Normalnie, aby uzyskać dostęp do zewnętrznych klas członków, wystarczy powiedzieć Outer.this.member, ale w tym przypadku to dał mi następujący błąd (przy założeniu klasa):

error: not an enclosing class: ArrayAdapter 

Więc jak czy macie dostęp do wewnętrznych członków klasy z wewnętrznej klasy wewnętrznej? Nie lubię zagnieżdżonych anonimowych klas wielopoziomowych, ale w tym przypadku uczę się nowego interfejsu API i nie jestem jeszcze pewny czy jest to jeszcze lepszy sposób. Już obejść, ale chciałem wiedzieć tak. Metoda remove() nie jest tak naprawdę zasłonięta przez wewnętrzną wewnętrzną klasę, więc określenie klasy nie jest w tym przypadku konieczne, ale chcieliśmy wyjaśnić w kodzie dokładnie, gdzie znajduje się ta metoda remove(). Chciałem też wiedzieć, na wypadek, gdyby był zasłonięty. Wierzę, że używanie Outer.$6.remove() zadziała, ale nie sądzę, że powinno tak być.

Odpowiedz

12

Przypisz this do zmiennej, a następnie przejść, że jednym z najbardziej wewnętrznej klasy.

list.setAdapter(new Adapter() { 
    public View getView() { 
    final Adapter that = this; 
    button.setListener(new Listener() { 
     public void onClick() { 
     that.remove(item); 
     } 
    ); 
    } 
}); 

Nie jestem pewien, co byłoby dobrym nazewnictwem tutaj. Być może adapter?

+0

Rozumiem. Pomyślałem, że będzie istnieć składnia językowa do użycia w celu uzyskania Adaptera, o którym nie wiedziałem. BTW "to" musiałoby być ostateczne. – Chloe

+1

Preferuję to podejście, ponieważ jest ono łatwe do odczytania i jednoznaczne. – skrat

+0

Występuje błąd kompilacji na linii Adapter, która = Adapter.this; (Adapter nie jest klasą zamykającą). Zamiast tego powinieneś raczej mówić końcowy Adapter, który = to .. jeśli w ogóle .. – sethu

0

jego proste, jak to: try outer.remove bez tej klasie wskaźnik

+0

To nie zadziała. remove() nie jest metodą zewnętrzną. Jest to metoda adaptera. – Chloe

1

Wystarczy wywołać metodę bezpośrednio na adapterze:

list.setAdapter(new Adapter() { 
    public View getView() { 
    // ... 
    button.setListener(new Listener() { 
     public void onClick() { 
     remove(item); // <-- this will call Adapter's method of the anonymous class 
     } 
    ); 
    } 
}); 
+2

Wiem o tym. Ale co jeśli słuchacz ma metodę remove()? Co wtedy? – Chloe

+1

Dobre pytanie! Zajmę się tym dzisiaj wieczorem. – Bohemian

Powiązane problemy