로그인 버튼 이벤트 처리가 이상해 보여요.
//로그인 버튼을 눌렀을 때
login_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//정보 전송
HomeFragment homeFragment = new HomeFragment();
bundle.putString("s", login_id.getText().toString());
bundle.putString("s1", "pw");
homeFragment.setArguments(bundle);
activity.onFragmentChange(2); //홈 화면으로 이동
login_id.setText(""); login_pw.setText(""); //입력칸 비우기
}
});
작성하신 코드를 보면 로그인 버튼 클릭시 생성하는 HomeFragment와 activity.onFragmentChange(2)가 호출될 때 생성되는 HomeFragment가 다른 인스턴스로 보입니다. HomeFragment를 오픈하는 코드를 activity.onFragmentChange(2)로 옮기세요. 이왕이면 onFragmentChange 보다는 어떤 동작을 하는지 쉽게 알 수 있는 메소드명을 사용하세요. 예를 들면, onShowLoginScreen() 과 같은 식으로 말이죠.
참고가 될 수 있도록 액티비티와 프레그먼트 간에 인터페이스를 이용하여 어떻게 커뮤니케이션을 하는지 샘플 코드를 올립니다.
public interface Navigatable {
void goHome(LoginInfo loginInfo);
}
public class MainActivity extends AppCompatActivity implements Navigatable {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void goHome(LoginInfo loginInfo) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentContainer, HomeFragment.newInstance(loginInfo))
.commit();
}
}
public class LoginInfo implements Serializable {
private final String userId;
private final String password;
public LoginInfo(String userId, String password) {
this.userId = userId;
this.password = password;
}
public String getUserId() {
return userId;
}
public String getPassword() {
return password;
}
}
public class LoginFragment extends Fragment {
private Navigatable navigatable;
public LoginFragment() {
// Required empty public constructor
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
navigatable = (Navigatable) context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_login, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupViews();
}
private EditText userIdEdt, passwordEdt;
private void setupViews() {
userIdEdt = requireView().findViewById(R.id.userIdEdt);
passwordEdt = requireView().findViewById(R.id.passwordEdt);
requireView().findViewById(R.id.loginBtn).setOnClickListener(v -> submitLogin());
}
private void submitLogin() {
navigatable.goHome(getLoginInfo());
}
private LoginInfo getLoginInfo() {
return new LoginInfo(
userIdEdt.getText().toString(),
passwordEdt.getText().toString()
);
}
}
public class HomeFragment extends Fragment {
private static final String ARG_LOGIN_INFO = "LoginInfo";
public HomeFragment() {
}
public static HomeFragment newInstance(LoginInfo loginInfo) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putSerializable(ARG_LOGIN_INFO, loginInfo);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupViews();
}
private void setupViews() {
System.out.println(requireLoginInfo());
}
@NotNull
private LoginInfo requireLoginInfo() {
return (LoginInfo) requireArguments().getSerializable(ARG_LOGIN_INFO);
}
}
Navigator라는 네비게이션만 담당하는 전용클래스를 만들어서 사용하는 것이 더 좋은 방법이지만 코드가 너무 복잡해질 것 같아 Navigatable이라는 인터페이스를 MainActivity에서 구현하는 것으로 대체했습니다. 그렇게 어렵지 않은 코드이므로 읽어보시면 이해가 가실겁니다.