Fragment에서 Back키가 눌렸을 때 이를 받아먹고 싶지만,
이게 뜻대로 안 됨. 키 이벤트는 다 액티비티가 받아먹으니까.
그래서 Fragment가 붙어있는 액티비티에다가, (다시말해, Fragment에서 getActivity를 하면 얻을 수 있는 Activity에서)
1 2 3 4 5 6 7 8 | public interface onKeyBackPressedListener { public void onBack(); } private onKeyBackPressedListener mOnKeyBackPressedListener; public void setOnKeyBackPressedListener(onKeyBackPressedListener listener) { mOnKeyBackPressedListener = listener; } // In MyActivity |
이런 리스너 인터페이스를 만들어주고,
Back 키 이벤트를 받을 Fragment에서 implement 해줌
1 2 3 4 5 6 7 8 9 10 | @Override public void onBack() { if (mWebView.canGoBack()) { mWebView.goBack(); } else { MyActivity activity = (MyActivity) getActivity(); activity.setOnKeyBackPressedListener(null); activity.onBackPressed(); } } // in SearchFragment |
그리고 이 Fragment를 리스너로 등록해줌, getActivity로 할 수도 있지만,
onAttach에서 해주면 매개변수로 바로 등록가능
1 2 3 4 5 | @Override public void onAttach(Activity activity) { super.onAttach(activity); ((MyActivity) activity).setOnKeyBackPressedListener(this); } // in SearchFragment |
내 경우, WebView가 들어있는 Fragment이고 웹 브라우저에서 뒤로 갈 수 있는데도 뒤로가기 키를 누르면
Fragment가 종료되어버리는 현상때문에 Fragment에서 BackKey이벤트를 낚아채갈 필요성이 생긴거.
그리고 이게 액티비티의 onBackPressed()임.
1 2 3 4 5 6 7 8 | @Override public void onBackPressed() { if (mOnKeyBackPressedListener != null) { mOnKeyBackPressedListener.onBack(); } else { super.onBackPressed(); } } // in MyActivity |
맨 처음에는 mOnKeyBackPressedListener가 null이기 때문에, (Fragment가 아직 생기지도 않았으니까)
super.onBackPressed()가 실행되지만,
Fragment가 Attach 된 후에는, 이 Fragment가 Listener를 초기화했기 때문에
back key 이벤트를 낚아채올 수 있다. -> 그러다가 뒤로갈 수 없어지면, 리스너 해제해버리고 onBackPressed()해주면 끝!
쓸 데 없이 현재 프래그먼트가 뭔지 저장하고, 스트링 비교하고, 이런거 필요 없이 정말 깔~끔한 코드.