【问题标题】:How to make a callback between Activity and Fragment?如何在Activity和Fragment之间进行回调?
【发布时间】:2013-05-05 16:05:56
【问题描述】:

我的活动中有这个界面。

public interface LogoutUser {
    void logout();
}

我的片段实现了这个接口,所以在我的片段中,我有这个:

@Override
public void logout() {
    // logout
}

在我的活动中我调用

mLogoutUser.logout();

mLogoutUser 属于 LogoutUser 接口类型。

我的问题是 mLogoutUser 对象为空。怎么初始化呢?

谢谢!

【问题讨论】:

  • mLogoutUser = yourFragment;

标签: android interface android-activity callback fragment


【解决方案1】:

正如我在评论中所说,我在片段中使用 onAttach 方法解决了这个问题,但是这样你必须在片段中声明回调字段(在这种情况下为 mLogoutUser),并以这种方式初始化它:

public class MyFragment extends ListFragment {
    LogoutUser mLogoutUser;

    // Container Activity must implement this interface
    public interface LogoutUser {
        public void logout();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mLogoutUser = (LogoutUser) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement LogoutUser");
        }
    }

    ...
}

Communicating with Other Fragments 中的更多信息。


但如果您的情况是活动中声明的字段,您可以使用活动中的onAttachFragment 方法以这种方式初始化您的侦听器字段:

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    mLogoutUser = (LogoutUser) fragment;
}

此外,您可以使用事件总线在片段和活动之间进行这种通信。一个选项是来自 Square 的 Otto library

【讨论】:

  • 非常感谢@androidevil。你救了我的一天!顺便说一句,如果我们附加了多个片段,我们可以在 onAttachFragment 中使用 if(fragment instanceof fragmentone){}。
  • 这不是最好的方法,你违反了 OpenClose 原则。实际上,如果你想在其他活动中重用这个片段,因为你正在做实例检查,你不能这样做
  • 随着 onAttach(Activity activity) 被弃用,并且 onAttach(Context context) 现在可用,我认为最初的建议现在是可以接受的。
【解决方案2】:

从 Fragment 创建回调到 Activity 的示例

public interface CallBackListener {
    void onCallBack();// pass any parameter in your onCallBack which you want to return
}

CallBackFragment.class

public class CallBackFragment extends Fragment {

    private CallBackListener callBackListener;

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        return inflater.inflate(R.layout.fragment_call_back, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //getActivity() is fully created in onActivityCreated and instanceOf differentiate it between different Activities
        if (getActivity() instanceof CallBackListener)
            callBackListener = (CallBackListener) getActivity();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Button btn = (Button) view.findViewById(R.id.btn_click);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(callBackListener != null)
                    callBackListener.onCallBack();
            }
        });
    }
}

CallbackHandlingActivity.class

public class CallbackHandlingActivity extends AppCompatActivity implements CallBackListener
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_all_user);

    }

    @Override
    public void onCallBack() {
        Toast.makeText(mContext,"onCallback Called",Toast.LENGTH_LONG).show();
    }
}

【讨论】:

  • 感谢您提供完整的示例答案!
  • @Nepster 为了避免内存泄漏,是否有必要将 Fragment.onDestroy() / Fragment.onStop() 中的 callBackListener 清空?
  • 谢谢!工作!那么创建从 Activity 到 Fragment 的回调的示例呢???
【解决方案3】:

Android Fragments - Communicating with Activity

您需要使用getFragmentById()getFragmentByTag() 获取对片段的引用

getFragmentManager().findFragmentById(R.id.example_fragment);

【讨论】:

  • 谢谢。另一种方法是使用 onAttach()
  • @androidevil onAttach() 怎么用?
  • onAttach() 自 API 23 起已弃用。
  • 据我所知,onAttach(Activity activity) 已被弃用,取而代之的是 onAttach(Context context)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多