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

프래그먼트 체크박스에 따른 액티비티 리스트뷰 변경

0 추천

프래그먼트에 있는 체크박스를 선택하면 액티비티에서 보이는 Listview의 내용이 바뀌어야하는데 그 부분을 어떻게 해야할지 전혀 모르겠습니다. ㅠㅠ 체크박스가 있는 프래그먼트에서 액티비티에 있는 리스트뷰에 접근하는 방법이나 액티비티에서 onCheckedChanged 메소드를 호출해서 리스트뷰를 변경해야할까요?ㅠㅠ

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_res_list);

    RecommendByKeyword rk = new RecommendByKeyword();

    rk.setUserInput(userinput);
    rk.RecommendRestaurantsList();

    outputs = rk.getResults();

    adapter = new SingleAdapter();

    listView = (ListView)findViewById(R.id.res_list);
    listView.setAdapter(adapter);

    for(int i = 0; i < outputs.length; i++){
        adapter.addItem(outputs[i]);
    }

    adapter.notifyDataSetChanged();

    res = adapter.getRes();
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        String result = "";
        UserInput ui = new UserInput();
        RecommendByKeyword keyword = new RecommendByKeyword();

        if(cb_f1.isChecked() == true) {
            result += cb_f1.getText().toString();
        }
        if(cb_f2.isChecked() == true) {
            result += cb_f2.getText().toString();
        }
        if(cb_f3.isChecked() == true) {
            result += cb_f3.getText().toString();
        }
    }
}
mjsky97 (140 포인트) 님이 2020년 12월 11일 질문

1개의 답변

0 추천

액티비티와 프레그먼트의 아주 클래식컬한 메세지 교환방식은 interface를 사용하는 겁니다.

public class MyActivity extends AppCompatActivity implements MyFragmentListener {

     @Override
     public void onCheckBoxChecked() {
          updateListView();
     }
}



public class MyFragment extends Fragment {

    private MyFragmentListener myFragmentListener;


    @Override
     public void onAttach (Context context) {
           if (context instanceof MyFragmentListener)  {
                   myFragmentListener = (FragmentListener) context;
                   return;
           }
          
     }


    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
             if (myFragmentListener == null) {
                  Log.w("MyFragment", "Please implement interface if you want to talk to fragment");
                  return;
            }


           if (checked) {
                 myFragmentListener.onCheckBoxChecked();
           }
    }

}

public interface MyFragmentListener {
   //님의 상황에 맞게 좀더 명료한 이름을 사용하세요.
    public void onCheckBoxClicked() ;
}

 

다른 방법으로는 EventBus같은 전역적인 메세지 교환 방식을 사용하셔도 되는데, 이건 남용하면 곤란한 방식이고, 만약 ViewModel을 사용하신다면 액티비티와 ViewModel을 공유할 수도 있습니다.

 

질문과는 상관없지만, 눈에 띄어서... 아래처럼 유틸리티 메소드를 사용하시면 중복코드를 줄일 수 있을 것 같네요.

public static String checkedString(CompoundButton button) {
     return button.isChecked() ? button.getText().toString() : "";
}

String checkedStrings = checkeString(cb_f1) + checkeString(cb_f2)  + checkeString(cb_f3);

 

spark (227,530 포인트) 님이 2020년 12월 11일 답변
저는 바로 호출합니다. 좋은 방법인지는 모르겠어요.

Fragment가 어차피 Acitvity 아래에 존재하니까, 부모를 호출하는 거죠.

((MyActivity) getActivity()).onCheckboxChecked();

이벤트 버스는 저도 비동의하고요, 메시지 관리가 안될 정도로 복잡해지고,
나중에 유지보수 어렵습니다.

viewModel 공유는 생각보다 직관적이지 않은 것 같습니다.
공유할 부분이 적다는 것, 그리고 왜 공유해야 하는지가 헷갈립니다.

Listener는 좋은 방법인 것 같네요.
나중에 기회가 되면 한번 사용해 보겠습니다~
...