这是Head First Android的代码。在onAttach方法中,我想知道如何将Activity活动变量强制转换为WorkoutListListener。是否存在超级子关系?
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;
}
}
答案 0 :(得分:1)
首先,这是一种冒险的方法。最安全的解决方案是:
public void onAttach(Activity activity) {
super.onAttach(context);
if(activity instanceof WorkoutListListener) {
this.listener = (WorkoutListListener) activity;
}
}
现在你看到的是在android中使用的常见的观察者模式。
如果活动正在管理某些片段并希望从片段中观察某些事件并根据该片段执行操作,则该活动将实现预定义的interface
,即用于在onAttach
中投射的相同界面。
因此,在您的示例中,处理片段显示的活动必须实现WorkoutListListener
接口。
最糟糕的情况WorkoutListListener
是一个Activity,它是一个非常糟糕的活动名称:)),那么处理该片段的所有活动都必须是WorkoutListListener
的子类。 (但第二种选择很难看。)
答案 1 :(得分:0)
toggleSelected(obj, event) {
if(event.shiftKey) {
do this
} else {
do that
}
}
需要onAttach
类型的活动引用。这是Android的通用活动类型。但是,自定义活动(例如示例中的活动)可能会实现某些界面。因此,我们需要将Activity
引用转换为我们的自定义活动类型,或者只是为了赋值而转换为接口类型(例如在发布的代码中)。