Android:无法从一个片段导航到另一个片段

时间:2016-12-26 22:05:57

标签: android android-fragments socket.io

This is the login screen, which leads to the next screen(Chat Screen)

This is the Chat Screen- which I am unable to navigate to

我正在尝试实现聊天功能,其中登录和聊天屏幕都是片段。我没有任何错误。但是,该应用程序未导航到聊天屏幕。我不知道我失踪的地方。 任何建议都将不胜感激。

********登录片段********

public class LoginFragment extends Fragment {

private EditText mUsernameView;
private Button signInButton;
private String mUsername;
private Socket mSocket;

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

    View loginview = inflater.inflate(R.layout.fragment_login, container, false);

    ChatApplication app = (ChatApplication) getActivity().getApplication();
    mSocket = app.getSocket();

    // this is the login form
    mUsernameView = (EditText) loginview.findViewById(R.id.username_input);
    mUsernameView.setOnEditorActionListener(new TextView.OnEditorActionListener()
    {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent)
        {
            if(id == R.id.login || id == EditorInfo.IME_NULL)
            {
                attemptLogin();
                return true;
            }
                return false;
        }
    });

    signInButton = (Button) loginview.findViewById(R.id.sign_in_button);
    signInButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            attemptLogin();
        }
    });

    mSocket.on("login",onLogin);

    return loginview;
}

@Override
public void onDestroy() {
    super.onDestroy();

    mSocket.off("login", onLogin);
}

/*
    This method attempts the following
    1- clears the error message/resets the error message.
    2- checks if the user has entered valid username
    3- attempts user login
 */
private void attemptLogin()
{
    mUsernameView.setError(null);  //1
    String username = mUsernameView.getText().toString().trim();
    if(TextUtils.isEmpty(username))  //2
    {
        mUsernameView.setError("This field is required!");
        mUsernameView.requestFocus();
        return;
    }

    mUsername = username;

    mSocket.emit("add user", username); //3
}

private Emitter.Listener onLogin = new Emitter.Listener()
{
    @Override
    public void call(Object... args)
    {
        JSONObject data = (JSONObject) args[0];
        int numUsers;
        try
        {
            numUsers = data.getInt("numUsers");
        }
        catch (JSONException e)
        {
            return;
        }

        Intent intent = new Intent();
        intent.putExtra("username",mUsername);
        intent.putExtra("numUsers",numUsers);
        getActivity().setResult(RESULT_OK,intent);
        getActivity().finish();
    }
};

}

**************聊天片段*************

   public class ChatFragment extends Fragment
{


    private static final int REQUEST_LOGIN = 1;

    private static final int TYPING_TIMER_LENGTH = 600;

    private RecyclerView mMessagesView;
    private EditText mInputMessageView;
    private List<Message> mMessages = new ArrayList<Message>();
    private RecyclerView.Adapter mAdapter;
    private boolean mTyping = false;
    private Handler mTypingHandler = new Handler();
    private String mUsername;
    private Socket mSocket;

    private Boolean isConnected = true;

    public ChatFragment() {
        super();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mAdapter = new MessageAdapter(context, mMessages);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);

        ChatApplication app = (ChatApplication) getActivity().getApplication();
        mSocket = app.getSocket();
        mSocket.on(Socket.EVENT_CONNECT,onConnect);
        mSocket.on(Socket.EVENT_DISCONNECT,onDisconnect);
        mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        mSocket.on("new message", onNewMessage);
        mSocket.on("user joined", onUserJoined);
        mSocket.on("user left", onUserLeft);
        mSocket.on("typing", onTyping);
        mSocket.on("stop typing", onStopTyping);
        mSocket.connect();

        startSignIn();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_chat, container, false);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        mSocket.disconnect();

        mSocket.off(Socket.EVENT_CONNECT, onConnect);
        mSocket.off(Socket.EVENT_DISCONNECT, onDisconnect);
        mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        mSocket.off("new message", onNewMessage);
        mSocket.off("user joined", onUserJoined);
        mSocket.off("user left", onUserLeft);
        mSocket.off("typing", onTyping);
        mSocket.off("stop typing", onStopTyping);
    }

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

        mMessagesView = (RecyclerView) view.findViewById(R.id.messages);
        mMessagesView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mMessagesView.setAdapter(mAdapter);

        mInputMessageView = (EditText) view.findViewById(R.id.message_input);
        mInputMessageView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int id, KeyEvent event) {
                if (id == R.id.send || id == EditorInfo.IME_NULL) {
                    attemptSend();
                    return true;
                }
                return false;
            }
        });
        mInputMessageView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (null == mUsername) return;
                if (!mSocket.connected()) return;

                if (!mTyping) {
                    mTyping = true;
                    mSocket.emit("typing");
                }

                mTypingHandler.removeCallbacks(onTypingTimeout);
                mTypingHandler.postDelayed(onTypingTimeout, TYPING_TIMER_LENGTH);
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        ImageButton sendButton = (ImageButton) view.findViewById(R.id.send_button);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                attemptSend();
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (Activity.RESULT_OK != resultCode) {
            getActivity().finish();
            return;
        }

        mUsername = data.getStringExtra("username");
        int numUsers = data.getIntExtra("numUsers", 1);

        addLog(getResources().getString(R.string.message_welcome));
        addParticipantsLog(numUsers);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Inflate the menu; this adds items to the action bar if it is present.
        inflater.inflate(R.menu.menu_main, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_leave) {
            leave();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void addLog(String message) {
        mMessages.add(new Message.Builder(Message.TYPE_LOG)
                .message(message).build());
        mAdapter.notifyItemInserted(mMessages.size() - 1);
        scrollToBottom();
    }

    private void addParticipantsLog(int numUsers) {
        addLog(getResources().getQuantityString(R.plurals.message_participants, numUsers, numUsers));
    }

    private void addMessage(String username, String message) {
        mMessages.add(new Message.Builder(Message.TYPE_MESSAGE)
                .username(username).message(message).build());
        mAdapter.notifyItemInserted(mMessages.size() - 1);
        scrollToBottom();
    }

    private void addTyping(String username) {
        mMessages.add(new Message.Builder(Message.TYPE_ACTION)
                .username(username).build());
        mAdapter.notifyItemInserted(mMessages.size() - 1);
        scrollToBottom();
    }

    private void removeTyping(String username) {
        for (int i = mMessages.size() - 1; i >= 0; i--) {
            Message message = mMessages.get(i);
            if (message.getType() == Message.TYPE_ACTION && message.getUsername().equals(username)) {
                mMessages.remove(i);
                mAdapter.notifyItemRemoved(i);
            }
        }
    }

    private void attemptSend() {
        if (null == mUsername) return;
        if (!mSocket.connected()) return;

        mTyping = false;

        String message = mInputMessageView.getText().toString().trim();
        if (TextUtils.isEmpty(message)) {
            mInputMessageView.requestFocus();
            return;
        }

        mInputMessageView.setText("");
        addMessage(mUsername, message);

        // perform the sending message attempt.
        mSocket.emit("new message", message);
    }

    private void startSignIn() {
        mUsername = null;
    /* Error:
        Intent intent = new Intent(getActivity(), LoginFragment.class);
        startActivityForResult(intent, REQUEST_LOGIN);
    */

     // Solution 1: for calling a fragment from a fragment
        Intent intent = new Intent(getActivity(),LoginFragment.class);
        getActivity().startActivityForResult(intent,REQUEST_LOGIN);

/*
     // Solution 2: for calling a fragment from a fragment
        LoginFragment loginFragment = new LoginFragment();
        FragmentManager fManager = getFragmentManager();
        FragmentTransaction fTransaction = fManager.beginTransaction();
        fTransaction.replace(R.id.id_fragment_chat,loginFragment);
        fTransaction.addToBackStack(null);
        fTransaction.commit();

*/
    }

    private void leave() {
        mUsername = null;
        mSocket.disconnect();
        mSocket.connect();
        startSignIn();
    }

    private void scrollToBottom() {
        mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
    }

    private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(!isConnected) {
                        if(null!=mUsername)
                            mSocket.emit("add user", mUsername);
                        Toast.makeText(getActivity().getApplicationContext(),
                                R.string.connect, Toast.LENGTH_LONG).show();
                        isConnected = true;
                    }
                }
            });
        }
    };
.
.
.
}

2 个答案:

答案 0 :(得分:1)

使用核心片段结构而不是使用直接扩展

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;

/**
 *
 * This is main core fragment. All fragment defined in this project that extends this fragment.
 *
 * @author viral
 *
 */
public class CoreFragment extends Fragment {

    private static FragmentManager fm;
    private CharSequence tabTitle;

    /**
     * This method switch fragment.
     * 
     * @param fragment - from fragment 
     * @param viewReplace - Destination view/container
     * 
     */
    public void switchFragment(Fragment fragment, int viewReplace){
        try {
            FragmentManager fragmentManager = getFragmentManager();
            if(fragmentManager != null)
                fm = fragmentManager;

            fm.beginTransaction()
                .replace(viewReplace, fragment)
                .commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This method switch fragment.
     * 
     * @param fragment - from fragment 
     * @param viewReplace - Destination view/container
     * 
     */
    public void switchFragmentWithBackstack(Fragment fragment, int viewReplace){
        try {
            FragmentManager fragmentManager = getFragmentManager();
            if(fragmentManager != null)
                fm = fragmentManager;
            fm.beginTransaction()
                .replace(viewReplace, fragment)
                .addToBackStack(null)
                .commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

然后根据您的应用程序要求使用switchFragment / switchFragmentWithBackstack方法。

  

你的所有片段扩展了CoreFragment

答案 1 :(得分:0)

关于你的private void startSignIn() { mUsername = null; Intent intent = new Intent(getActivity(), LoginFragment.class); startActivityForResult(intent, 0); } ...你想做什么?开始另一项活动?然后你应该调用这个活动,并在这个活动中添加这个片段。或者,如果你想在同一个活动中将一个片段替换为另一个片段,你应该这样做,而不是startActivity:

YourFragment fragment = new YourFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment, YOUR_TAG)
                .commit();