Android中片段与活动之间的沟通

时间:2016-12-25 13:20:10

标签: android android-fragments android-activity design-patterns callback

我考虑了this documentation和几个SO问题或不同的教程,用于片段到活动的沟通。我正在为我的应用程序建立一个简单的聊天。当我点击InboxFragment中的聊天室时,我想将聊天室的名称传递给我的ChatActivity,并将聊天室的名称添加到 ChatActivity

问题是我总是收到ChatActivity implement interface OnChatRommSelected的错误消息。

错误消息是:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.lyl.nairad, PID: 3018
                  java.lang.ClassCastException: com.lyl.nairad.Activities.MainAppActivity@2600f9ae must implement OnChatRoomSelected
                      at com.lyl.nairad.Fragments.InboxFragment.onStart(InboxFragment.java:137)

我的 InboxFragment 如下所示:

编辑:InboxFragment中还有一些变量等,但我让它们离开以尽量缩短代码。

public class InboxFragment extends Fragment {

    // [BEGIN: Communication instances
    OnChatRoomSelected mCallback;
    // END]

    private final String TAG = "InboxFragment";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_inbox, container, false);
        callingActivity = getActivity();
        // Some Code...

        chats.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                sendChatRoomName(String.valueOf(chats.getItemAtPosition(position)));
                Intent i = new Intent(getActivity(), ChatActivity.class);
                startActivity(i);
            }
        });

        return view;
    }
    public void refresh(){

        ((TextView)getActivity().findViewById(R.id.toolbar_title)).setText("Chats");
    }

    @Override
    public void onResume() {
        super.onResume();
        refresh();
    }

    // [BEGIN: Interface for Fragment to Activity Communication
    public interface OnChatRoomSelected {
        public void selectedChatRoom(String chatRoomName);
    }

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

    @Override
    public void onStart() {
        super.onStart();
        try {
            mCallback = (OnChatRoomSelected) getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException(getActivity().toString()
                    + " must implement OnChatRoomSelected");
        }
    }

    public void sendChatRoomName(String chatRoomName) {
        mCallback.selectedChatRoom(chatRoomName);
    }
    // END}
}

我的 ChatActivity 如下所示:

public class ChatActivity extends Activity implements InboxFragment.OnChatRoomSelected {

    Button send;
    EditText msgField;
    ListView newsExtending;
    ArrayList<String> messages;
    ArrayAdapter<String> adapter;

    private final String TAG = "ChatActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        messages = new ArrayList<>();
        send = (Button) findViewById(R.id.sendMsgBtn);
        msgField = (EditText) findViewById(R.id.aMessage);
        newsExtending = (ListView) findViewById(R.id.privateMessagesList);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, messages);
        newsExtending.setAdapter(adapter);

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = msgField.getText().toString();
                messages.add(text);
                adapter.notifyDataSetChanged();
                msgField.setText("");
            }
        });

    }
    @Override
    public void selectedChatRoom(String chatRoomName) {
        messages.add(chatRoomName);
        adapter.notifyDataSetChanged();
    }

}

当我发表评论时

@Override
    public void onStart() {
        super.onStart();
       /* try {
            mCallback = (OnChatRoomSelected) getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException(getActivity().toString()
                    + " must implement OnChatRoomSelected");
        }*/
    }
InboxFragment中的

,我的错误如下:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.lyl.nairad, PID: 3334
                  java.lang.NullPointerException: Attempt to invoke interface method 'void com.lyl.nairad.Fragments.InboxFragment$OnChatRoomSelected.selectedChatRoom(java.lang.String)' on a null object reference
                      at com.lyl.nairad.Fragments.InboxFragment.sendChatRoomName(InboxFragment.java:143)
                      at com.lyl.nairad.Fragments.InboxFragment$2.onItemClick(InboxFragment.java:102)

2 个答案:

答案 0 :(得分:1)

使用方法 onAttach(上下文上下文)注册回调

@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mCallback = (ChatActivity) context;
        } catch (ClassCastException e) {
            Log.e("Custom TAG", "ClassCastException", e);
        }
    }

onDetach 取消注册回调

@Override
public void onDetach() {
 mCallback = null;        
 super.onDetach();

}

答案 1 :(得分:0)

您应该通过活动上下文获取接口方法,并在onAttach()回调中执行此操作

    @override
    public void onAttach(Context context){
     super.onAttach(context);
     try {
        mCallback = (OnChatRoomSelected) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(getActivity().toString()
                + " must implement OnChatRoomSelected");
    }
  }