2016-05-06 4 views
0

Dies ist Code von Head First Android. In der onAttach-Methode frage ich mich, wie die Activity-Aktivitätsvariable in WorkoutListListener typisiert wird. Gibt es eine Super-Sub-Beziehung?Android - Aktivität Typecasting in einen Schnittstellentyp

public class WorkoutListFragment extends ListFragment { 

public WorkoutListFragment() { 
    // Required empty public constructor 
} 

static interface WorkoutListListener { 
    void itemClicked(long id); 
} 

private WorkoutListListener listener; 

@Override 
public View onCreateView(LayoutInflater inflater, 
         ViewGroup container, Bundle savedInstanceState) { 

    String[] names = new String[Workout.workouts.length]; 
    for (int i = 0; i < Workout.workouts.length; i++) { 
     names[i] = Workout.workouts[i].getName(); 
    } 

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1, names); 
    setListAdapter(adapter); 

    return super.onCreateView(inflater, container, savedInstanceState); 
} 

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    if (listener != null) { 
     listener.itemClicked(id); 
    } 

} 

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(context); 
    this.listener = (WorkoutListListener) activity; 
} 

}

Antwort

1

Vor allem das ist ein riskantes Vorgehen. Die sicherste Lösung wäre:

public void onAttach(Activity activity) { 
    super.onAttach(context); 
if(activity instanceof WorkoutListListener) { 
    this.listener = (WorkoutListListener) activity; 
} 

}

Nun, was Sie hier sehen, ist ein gemeinsames Prasseln des Beobachters, die in Android verwendet wird. Wenn eine Aktivität einige Fragmente verwaltet und einige Ereignisse aus den Fragmenten beobachten und darauf basierende Aktionen ausführen möchte, implementiert die Aktivität eine vordefinierte interface, dieselbe Schnittstelle, die zum Umwandeln in onAttach verwendet wird.

In Ihrem Beispiel muss die Aktivität, die die Anzeige des Fragments behandelt, die Schnittstelle implementieren.

Worst-Case-Szenario WorkoutListListener ist eine Aktivität, die ein wirklich schlechter Name für eine Aktivität :)) ist, dann müssen alle Aktivitäten, die das Fragment behandelt, Unterklasse sein. (aber die zweite Option ist hässlich).

+0

Sie meinen, die Aktivitäten müssen WorkoutListListener richtig erweitern? –

+0

@KevinBaik, Technisch gesehen sollte '' 'WorkoutListListener''' eine Schnittstelle sein, also müssen die Aktivitäten die Schnittstelle implementieren, wenn' '' WorkoutListListener''' eine Unterklasse von '' Activity''' ist, dann ja, alle Die Aktivitäten müssen '' 'WorkoutListListener''' erweitern. – danypata

+0

Vielen Dank für Ihre Hilfe –

0

onAttach erwartet eine Aktivitätsreferenz vom Typ Activity. Das ist der allgemeine Aktivitätstyp von Android. Eine benutzerdefinierte Aktivität (wie die im Beispiel) kann jedoch eine Schnittstelle implementieren. Daher müssen wir den Verweis Activity activity auf unseren benutzerdefinierten Aktivitätstyp umwandeln oder einfach den Schnittstellentyp für die Zuweisung (z. B. im veröffentlichten Code) umwandeln.

+0

Wenn die übergebene Aktivität die Schnittstelle nicht implementiert, führt diese Typumwandlung zu einem Fehler? –

+0

Ja, dieses Fragment kann nur ein Kind von WorkoutListListener sein – cyroxis

+0

Die Typumwandlung führt nicht zu einem Kompilierungsfehler. Eine Klassen-Cast-Ausnahme wird jedoch ausgelöst, wenn eine Schnittstellenmethode für die falsch gewichtete Instanz aufgerufen wird. –