마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Bundle 값이 저장이 안됩니다..

0 추천

안녕하세요

fragment 간의 값을 전달하기 위해 Bundle을 이용하는데 값이 저장이 안되네요..

저장한 값을 화면에 출력하도록했더니 아얘 안뜨는 것으로보아 Bundle자체에 값이 저장이 안돼서

if(getArguments() != null)

저 조건문에서 막혀서 실행이 안되는 듯합니다. 근데 무엇이 문제인지를 모르겠어요

일단 모든 코드 적어볼게용..

 

LoginFragment.java (전달하는 코드) (정보전송 칸에 bundle 있습니당)

package com.cookandroid.capstone4;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class LoginFragment extends Fragment {
    MainActivity activity;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (MainActivity)getActivity();
    }
    @Override
    public void onDetach() {
        super.onDetach();
        activity = null;
    }
    Bundle bundle = new Bundle();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_login, container, false);

        //변수 생성
        EditText login_id = view.findViewById(R.id.login_id);
        EditText login_pw = view.findViewById(R.id.login_pw);
        Button login_btn = view.findViewById(R.id.login_btn);
        TextView login_signup_btn = view.findViewById(R.id.login_signup_btn);

        //로그인 버튼을 눌렀을 때
        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("");   //입력칸 비우기
            }
        });

        //회원가입 버튼 눌렀을 때
        login_signup_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                activity.onFragmentChange(1);              //홈 화면으로 이동
                login_id.setText("");   login_pw.setText("");   //입력칸 비우기
            }
        });

        return view;
    }
}

HomeFragment.java (받는 코드)

package com.cookandroid.capstone4;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class HomeFragment extends Fragment {
    String str; String str1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        //변수 생성
        TextView home_loc = view.findViewById(R.id.home_loc);
        TextView home_dust = view.findViewById(R.id.home_dust);
        TextView home_temp = view.findViewById(R.id.home_temp);
        TextView home_humi = view.findViewById(R.id.home_humi);

        if(getArguments() != null) {
            str = getArguments().getString("s");
            str1 = getArguments().getString("s1");
            home_loc.setText(str);
            home_dust.setText(str1);
        }


        return view;
    }
}

살려주세용 ㅠㅅㅠ

낭낭이야 (120 포인트) 님이 2022년 9월 28일 질문

2개의 답변

0 추천

로그인 버튼 이벤트 처리가 이상해 보여요.

        //로그인 버튼을 눌렀을 때
        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에서 구현하는 것으로 대체했습니다. 그렇게 어렵지 않은 코드이므로 읽어보시면 이해가 가실겁니다.

 

 

 

 

 

spark (226,420 포인트) 님이 2022년 9월 28일 답변
spark님이 2022년 9월 28일 수정
0 추천
assert getArguments() != null;
String str = getArguments().getString("s");
String str1 = getArguments().getString("s1");

 

jay_choi (530 포인트) 님이 2023년 3월 2일 답변
...