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

Fragment에서 activity로 데이터 전달 하기

0 추천

Fragment에서 Activity로 데이터를 전송해서 값을 출력해봤는데요... 작동하지 않는 것 같습니다.

 

[WriteLogMain.class]

public class WriteLogMain extends AppCompatActivity {
    Toolbar toolbar;
    Button writeLogBtn;
    ArrayList<String> registerHealthLog = new ArrayList<>();

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

        toolbar = findViewById(R.id.logMainToolbar);
        setSupportActionBar(toolbar); // 툴바를 액티비티의 앱바로 지정한다.

        // 현재 날짜 가져오기.
        // SimpleDateFormat을 통해 원하는 형식으로 데이터를 가져옴.
        long now = System.currentTimeMillis();
        Date date = new Date(now);
        SimpleDateFormat dateFormat = new SimpleDateFormat("M" + "월");
        String getTime = dateFormat.format(date);

        ActionBar actionBar = getSupportActionBar(); // 툴바에 대한 참조 획득하기
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        actionBar.setTitle(getTime + " 운동기록");

        // 로그 기록 버튼을 클릭하면 로그 기록 화면으로 이동
        writeLogBtn = findViewById(R.id.writeLogBtn);
        writeLogBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), WriteLog.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        int i = 0;
        String s = data.getStringExtra("0");
        while(s != null) {
            registerHealthLog.add(s);
            s = data.getStringExtra(String.valueOf(i++));
        }
    }
}

 

로그 기록 버튼을 클릭하면 프래그먼트 화면을 가진 액티비티 화면으로 이동합니다.

이제 프래그먼트에 있는 리사이클러뷰에서 아이템을 클릭하고 등록하기 버튼을 클릭하면 값들이 배열에 넘어와야 할 것 같은데 안넘어오네요..

 

[프래그먼트 화면을 가진 액티비티.class]

        // 등록하기 버튼을 클릭하면 클릭된 아이템들을 모두 가져옴
        registerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Activity로 데이터 전송
                Context context = v.getContext();
                Intent intent = new Intent(context, WriteLogMain.class);

                ArrayList<String> requestList = HealthLogAdapter.GetItems();
                for(int i = 0; i < requestList.size(); i++) {
                    intent.putExtra(String.valueOf(i), requestList.get(i));
                }
                context.startActivity(intent);
            }
        });

 

[리사이클러뷰에서 선택된 것만 배열에 담기]

else {
    ItemList item = itemList.get(position);
    String text = item.getListText();
    holder.getTextView().setText(text);
    holder.getTextView().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if ( mSelectedItems.get(position, false) ){
                mSelectedItems.put(position, true); // 선택 해제 되면 색상 변경
                selectedItems.remove(itemList.get(position)); // 선택 해제된 로그 배열에서 제거
                v.setBackgroundColor(Color.WHITE);
            } else {
                mSelectedItems.put(position, false); // 선택 되면 색상 변경
                selectedItems.add(itemList.get(position).getListText()); // 로그 추가를 위해 배열에 담기
                v.setBackgroundColor(0xffd3d3d3);
            }
        }
    });
}
매력적인수박 (670 포인트) 님이 2021년 7월 17일 질문

1개의 답변

0 추천

Activity 띄우는 부분과 결과를 받아오는 부분이 일치하지 않아요. Activity 에서 결과를 받으려면  context.startActivityForResult로 요청하고 onActivityResult콜백에서 받게 되어있습니다. 그리고 WrieLog 클래스에서는 setRestul를 통해 finish하기 전에 결과를 세팅하셔야 합니다. 그런데 님의 context.startActivity를 호출하셨고 setResult도 하지 않으셨으니 결과를 받을 수가 없겠죠.

그리고 최근에  startActivityForResult는 deprecated되었습니다. 대신 새로 추가된 Result API를 사용하라는게 구글의 권장사항입니다. 개인적으로는 startActivityForResult보다 훨씬 좋은 구조로 보입니다.

개발자 문서: https://developer.android.com/training/basics/intents/result

public class WriteLogResultContract extends ActivityResultContract<Void, ArrayList<String>> {
   @Override
   public createIntent(Context context, Void input) {
         Intent intent = new Intent(context, WriteLog.class);
         return intent;
   }

   @Override
   public ArrayList<String> parseResult(int resultCode, Intent intent) {
       if (resultCode != Activity.RESULT_OK) return;
       return intent.getStringArrayListExtra("키값")
   }
}

/ /WriteLogMain
//아래코드는 Lifecycle이 CREATE 상태가 되기 전에 호출되어야 하므로, 멤버 인스턴스로 선언
ActivityResultLauncher<Void> writeLogResult = registerForActivityResult(new WriteLogResultContract(),
    new ActivityResultCallback<ArrayList<String>>() {
        @Override
        public void onActivityResult(ArrayList<String> logs) {
            // 결과값에 따른 처리
        }
});

...

registerBtn.setOnClickListener( v -> {
     writeLogResult.launch();
});


// WriteLog
holder.getTextView().setOnClickListener(v -> {
     requestList = ...

     Intent intent = new Intent();
     intent.putExtra("키값", requestList);
     setResult(Activity.RESULT_OK, intent);
     // finish(); - Activity.finish를 호출해야 Activity가 닫히므로 OnClickListner를 액티비티와 연결해서 사용하세요.
});

 

spark (224,800 포인트) 님이 2021년 7월 18일 답변
spark님이 2021년 7월 18일 수정
...