Fragments에서 onBackPressed ()를 구현하는 방법은 무엇입니까?
onBackPressed()
Android 활동에서 구현하는 방식과 비슷한 방식으로 Android Fragment에서 구현할 수 있는 방법이 있습니까?
조각 수명주기에는 없습니다 onBackPressed()
. onBackPressed()
안드로이드 3.0 프래그먼트 를 오버라이드하는 다른 대안이 있습니까?
이 방법으로 onBackPressed
Activity에서 재정의 를 해결했습니다 . 모든이 FragmentTransaction
있습니다 addToBackStack
커밋하기 전에 :
@Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getSupportFragmentManager().popBackStack();
}
}
가장 좋은 해결책은
자바 솔루션
간단한 인터페이스를 만듭니다.
public interface IOnBackPressed {
/**
* If you return true the back press will not be taken into account, otherwise the activity will act naturally
* @return true if your processing has priority if not false
*/
boolean onBackPressed();
}
그리고 당신의 활동에서
public class MyActivity extends Activity {
@Override public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
super.onBackPressed();
}
} ...
}
마지막으로 조각에서 :
public class MyFragment extends Fragment implements IOnBackPressed{
@Override
public boolean onBackPressed() {
if (myCondition) {
//action not popBackStack
return true;
} else {
return false;
}
}
}
코 틀린 솔루션
1-인터페이스 작성
interface IOnBackPressed {
fun onBackPressed(): Boolean
}
2-활동 준비
class MyActivity : AppCompatActivity() {
override fun onBackPressed() {
val fragment =
this.supportFragmentManager.findFragmentById(R.id.main_container)
(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let {
super.onBackPressed()
}
}
}
3-대상 조각 구현
class MyFragment : Fragment(), IOnBackPressed {
override fun onBackPressed(): Boolean {
return if (myCondition) {
//action not popBackStack
true
} else {
false
}
}
}
@HaMMeRed에 따르면 여기에 의사 코드가 어떻게 작동 해야하는지 의사가 있습니다. BaseActivity
SlidingMenu lib 예제와 같이 하위 조각이있는 기본 활동이 호출되었다고 가정 해 봅시다. 단계는 다음과 같습니다.
먼저 일반적인 메소드를 갖도록 인터페이스를 구현하는 인터페이스와 클래스를 만들어야합니다.
수업 인터페이스 만들기
OnBackPressedListener
public interface OnBackPressedListener { public void doBack(); }
의 기술을 구현하는 수업 만들기
OnBackPressedListener
public class BaseBackPressedListener implements OnBackPressedListener { private final FragmentActivity activity; public BaseBackPressedListener(FragmentActivity activity) { this.activity = activity; } @Override public void doBack() { activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); } }
이제부터 코드
BaseActivity
와 그 조각 에 대해 작업하겠습니다.수업 상단에 비공개 청취자 만들기
BaseActivity
protected OnBackPressedListener onBackPressedListener;
리스너를 설정하는 메소드 작성
BaseActivity
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; }
재정의에서
onBackPressed
그런 것을 구현하십시오.@Override public void onBackPressed() { if (onBackPressedListener != null) onBackPressedListener.doBack(); else super.onBackPressed();
당신의 조각에
onCreateView
당신의 청취자를 추가해야합니다@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { activity = getActivity(); ((BaseActivity)activity).setOnBackPressedListener(new BaseBackPressedListener(activity)); View view = ... ; //stuff with view return view; }
Voila, 이제 조각으로 다시 클릭하면 사용자 정의 on back 메소드를 잡아야합니다.
이것은 나를 위해 일했다 : https://stackoverflow.com/a/27145007/3934111
@Override
public void onResume() {
super.onResume();
if(getView() == null){
return;
}
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
// handle back button's click listener
return true;
}
return false;
}
});
}
그런 종류의 기능을 원한다면 활동에서 기능을 재정의 한 다음 YourBackPressed
모든 조각에 인터페이스를 추가 해야합니다.이 단추를 누를 때마다 관련 조각을 호출합니다.
편집 : 이전 답변을 추가하고 싶습니다.
오늘이 작업을 수행하려면 다른 패널이 마스터 / 메인 컨텐츠 패널과 동시에 업데이트 될 것으로 예상되는 경우 브로드 캐스트 또는 주문 된 브로드 캐스트를 사용합니다.
LocalBroadcastManager
지원 라이브러리에서이 기능을 사용하면 브로드 캐스트를 전송하고 onBackPressed
관심있는 조각을 구독하면됩니다. 나는 메시징이 더 분리 된 구현이고 더 잘 확장 될 것이라고 생각한다. 그래서 그것은 나의 공식적인 구현 권장 사항이 될 것이다. 그냥 사용하는 Intent
메시지의 필터로의 조치를. 새로 만든 ACTION_BACK_PRESSED
을 보내고 활동에서 보내고 관련 조각에서 듣습니다.
그 중 어느 것도 구현하기 쉽지 않으며 최적의 방식으로 작동하지 않습니다.
프래그먼트에는 작업을 수행 할 메소드 호출 onDetach가 있습니다.
@Override
public void onDetach() {
super.onDetach();
PUT YOUR CODE HERE
}
이 작업을 수행합니다.
addToBackStack
아래와 같이 조각 사이를 전환하는 동안 추가 하십시오.
fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit();
쓰면 addToBackStack(null)
자체적으로 처리하지만 태그를 제공하면 수동으로 처리해야합니다.
이 질문과 일부 답변이 5 년이 넘었으므로 솔루션을 공유하겠습니다. 이것은 @oyenigun의 답변에 대한 후속 및 현대화입니다.
업데이트 : 이 기사의 맨 아래에는 Activity가 전혀 포함되지 않는 추상 Fragment 확장을 사용하여 대체 구현을 추가했습니다.이 기능은 다른 백 동작이 필요한 중첩 된 조각과 관련된 더 복잡한 조각 계층 구조를 가진 사람에게 유용합니다.
내가 사용하는 일부 프래그먼트가 작은 정보 뷰와 같이 뒤로 버튼으로 닫고 싶은 더 작은 뷰를 가지고 있기 때문에 이것을 구현해야했지만, 이는 동작을 재정의 해야하는 모든 사람에게 좋습니다 조각 내부의 뒤로 버튼.
먼저 인터페이스를 정의하십시오
public interface Backable {
boolean onBackPressed();
}
내가 부르는이 인터페이스 Backable
(이름 지정 규칙의 sticker입니다) onBackPressed()
에는 boolean
값을 반환 해야하는 단일 메소드 가 있습니다. 뒤로 버튼 누름이 뒤로 이벤트를 "흡수"했는지 알아야하기 때문에 부울 값을 적용해야합니다. 리턴 true
은 추가 조치가 필요하지 않음을 의미하며, 그렇지 않으면 false
기본 뒤로 조치가 여전히 수행되어야한다고 말합니다. 이 인터페이스는 자체 파일 (바람직하게는 별도의 패키지 interfaces
) 이어야합니다 . 클래스를 패키지로 분리하는 것이 좋습니다.
둘째, 최고의 조각을 찾으십시오
Fragment
백 스택에서 마지막 객체 를 반환하는 메서드를 만들었습니다 . 태그를 사용합니다 ... ID를 사용하는 경우 필요한 사항을 변경하십시오. 탐색 상태 등을 처리하는 유틸리티 클래스 에이 정적 메소드가 있지만 물론 가장 적합한 위치에 배치하십시오. 교화를 위해라는 클래스에 내 것을 넣었습니다 NavUtils
.
public static Fragment getCurrentFragment(Activity activity) {
FragmentManager fragmentManager = activity.getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
String lastFragmentName = fragmentManager.getBackStackEntryAt(
fragmentManager.getBackStackEntryCount() - 1).getName();
return fragmentManager.findFragmentByTag(lastFragmentName);
}
return null;
}
백 스택 수가 0보다 큰지 확인하십시오. 그렇지 않으면 ArrayOutOfBoundsException
런타임에 가 발생할 수 있습니다. 0보다 크지 않으면 null을 반환합니다. 나중에 null 값을 확인합니다 ...
셋째, 조각으로 구현
Backable
뒤로 단추 동작을 대체해야하는 조각이있는 인터페이스를 구현하십시오 . 구현 방법을 추가하십시오.
public class SomeFragment extends Fragment implements
FragmentManager.OnBackStackChangedListener, Backable {
...
@Override
public boolean onBackPressed() {
// Logic here...
if (backButtonShouldNotGoBack) {
whateverMethodYouNeed();
return true;
}
return false;
}
}
에서 onBackPressed()
재정의, 당신이 필요로하는 어떤 논리했습니다. 뒤로 버튼 이 백 스택을 팝업 하지 않게 하려면 (기본 동작) 백 이벤트가 흡수되었음을 true로 리턴 하십시오. 그렇지 않으면 false를 반환하십시오.
마지막으로, 활동에서 ...
onBackPressed()
메소드를 대체 하고이 로직을 추가하십시오.
@Override
public void onBackPressed() {
// Get the current fragment using the method from the second step above...
Fragment currentFragment = NavUtils.getCurrentFragment(this);
// Determine whether or not this fragment implements Backable
// Do a null check just to be safe
if (currentFragment != null && currentFragment instanceof Backable) {
if (((Backable) currentFragment).onBackPressed()) {
// If the onBackPressed override in your fragment
// did absorb the back event (returned true), return
return;
} else {
// Otherwise, call the super method for the default behavior
super.onBackPressed();
}
}
// Any other logic needed...
// call super method to be sure the back button does its thing...
super.onBackPressed();
}
백 스택에서 현재 조각을 얻은 다음 null 검사를 수행하여 Backable
인터페이스를 구현하는지 확인합니다 . 그렇다면 이벤트가 흡수되었는지 판별하십시오. 그렇다면 우리는 끝났고 onBackPressed()
돌아올 수 있습니다. 그렇지 않으면, 그것을 정상적인 역 프레스로 취급하고 super 메소드를 호출하십시오.
활동을 포함하지 않는 두 번째 옵션
때때로, 당신은 Activity가 이것을 처리하기를 원하지 않으며, 조각 내에서 직접 처리해야합니다. 그러나 누가 백 프레스 API로 프래그먼트를 가질 수 없다고 말 합니까? 조각을 새로운 클래스로 확장하십시오.
Fragment를 확장하고 View.OnKeyListner
인터페이스를 구현하는 추상 클래스를 작성하십시오 .
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public abstract class BackableFragment extends Fragment implements View.OnKeyListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(this);
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackButtonPressed();
return true;
}
}
return false;
}
public abstract void onBackButtonPressed();
}
보시다시피, 확장되는 조각 BackableFragment
은 View.OnKeyListener
인터페이스를 사용하여 클릭을 자동으로 캡처합니다 . 표준 논리를 사용하여 onBackButtonPressed()
구현 된 onKey()
메소드 내 에서 추상 메소드를 호출하여 뒤로 버튼 누름을 식별하십시오. 뒤로 버튼 이외의 키 클릭을 등록해야하는 경우 조각에서 super
재정의 할 때 메서드 를 호출해야합니다 onKey()
. 그렇지 않으면 추상화의 동작 이 재정의 됩니다.
사용하기 쉽고 확장하고 구현하십시오.
public class FragmentChannels extends BackableFragment {
...
@Override
public void onBackButtonPressed() {
if (doTheThingRequiringBackButtonOverride) {
// do the thing
} else {
getActivity().onBackPressed();
}
}
...
}
onBackButtonPressed()
수퍼 클래스 의 메소드는 추상적이므로 일단 확장하면 구현해야합니다 onBackButtonPressed()
. void
프래그먼트 클래스 내에서 작업을 수행하기 만하면되므로 반환 되며 흡수를 다시 액티비티로 전달할 필요가 없습니다. 뒤로 버튼으로 수행하는 작업에 처리가 필요하지 않은 경우 Activity 메서드를 호출 해야 합니다 onBackPressed()
. 그렇지 않으면 뒤로 버튼이 비활성화되고 원하지 않습니다!
주의 사항 보시다시피, 이것은 키 리스너를 프래그먼트의 루트 뷰로 설정하므로 집중해야합니다. 이 클래스를 확장하는 프래그먼트에 포함 된 편집 텍스트 (또는 다른 포커스 스틸 링보기)가 있거나 다른 내부 프래그먼트 또는보기가있는 경우이를 별도로 처리해야합니다. 백 프레스에 초점을 잃기 위해 EditText 를 확장하는 좋은 기사가 있습니다 .
누군가가 이것을 유용하게 사용하기를 바랍니다. 행복한 코딩.
해결책은 간단합니다.
1) 모든 조각이 확장되는 기본 조각 클래스가있는 경우이 코드를 해당 클래스에 추가하십시오. 그렇지 않으면 기본 조각 클래스를 작성하십시오
/*
* called when on back pressed to the current fragment that is returned
*/
public void onBackPressed()
{
// add code in super class when override
}
2) 활동 클래스에서 다음과 같이 onBackPressed를 대체하십시오.
private BaseFragment _currentFragment;
@Override
public void onBackPressed()
{
super.onBackPressed();
_currentFragment.onBackPressed();
}
3) Fragment 클래스에서 원하는 코드를 추가하십시오.
@Override
public void onBackPressed()
{
setUpTitle();
}
onBackPressed()
조각이 활동에서 분리됩니다.
@Sterling Diaz의 답변에 따르면 나는 그가 옳다고 생각합니다. 그러나 어떤 상황은 잘못 될 것입니다. (예 : 화면 회전)
isRemoving()
목표 달성 여부 를 감지 할 수 있다고 생각합니다 .
onDetach()
또는에 쓸 수 있습니다 onDestroyView()
. 일입니다.
@Override
public void onDetach() {
super.onDetach();
if(isRemoving()){
// onBackPressed()
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if(isRemoving()){
// onBackPressed()
}
}
글쎄, 나는 이것을 이렇게했고, 그것은 나를 위해 일한다.
간단한 인터페이스
FragmentOnBackClickInterface.java
public interface FragmentOnBackClickInterface {
void onClick();
}
구현 예
MyFragment.java
public class MyFragment extends Fragment implements FragmentOnBackClickInterface {
// other stuff
public void onClick() {
// what you want to call onBackPressed?
}
그런 다음 활동에서 onBackPressed를 재정의하십시오.
@Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
List<Fragment> frags = getSupportFragmentManager().getFragments();
Fragment lastFrag = getLastNotNull(frags);
//nothing else in back stack || nothing in back stack is instance of our interface
if (count == 0 || !(lastFrag instanceof FragmentOnBackClickInterface)) {
super.onBackPressed();
} else {
((FragmentOnBackClickInterface) lastFrag).onClick();
}
}
private Fragment getLastNotNull(List<Fragment> list){
for (int i= list.size()-1;i>=0;i--){
Fragment frag = list.get(i);
if (frag != null){
return frag;
}
}
return null;
}
아래와 같이 프로젝트에 인터페이스를 추가해야합니다.
public interface OnBackPressed {
void onBackPressed();
}
그런 다음 조각에이 인터페이스를 구현해야합니다.
public class SampleFragment extends Fragment implements OnBackPressed {
@Override
public void onBackPressed() {
//on Back Pressed
}
}
그리고 당신은 아래처럼 활동 onBackPressed 이벤트 에서이 onBackPressed 이벤트를 트리거 할 수 있습니다.
public class MainActivity extends AppCompatActivity {
@Override
public void onBackPressed() {
Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
if (currentFragment instanceof OnBackPressed) {
((OnBackPressed) currentFragment).onBackPressed();
}
super.onBackPressed();
}
}
EventBus를 사용하는 경우 아마도 훨씬 간단한 솔루션 일 것입니다.
조각에서 :
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
EventBus.getDefault().register(this);
}
@Override
public void onDetach() {
super.onDetach();
EventBus.getDefault().unregister(this);
}
// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
getSupportFragmentManager().popBackStack();
}
활동 클래스에서 다음을 정의 할 수 있습니다.
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
super.onBackPressed();
}
@Override
public void onBackPressed() {
EventBus.getDefault().post(new BackPressedMessage(true));
}
BackPressedMessage.java는 POJO 객체 일뿐입니다.
이것은 매우 깨끗하며 인터페이스 / 구현 번거 로움이 없습니다.
이것은 트릭을 수행하는 작은 코드 일뿐입니다.
getActivity().onBackPressed();
그것이 누군가를 돕기를 바랍니다 :)
이것은 내 솔루션입니다.
에 MyActivity.java :
public interface OnBackClickListener {
boolean onBackClick();
}
private OnBackClickListener onBackClickListener;
public void setOnBackClickListener(OnBackClickListener onBackClickListener) {
this.onBackClickListener = onBackClickListener;
}
@Override
public void onBackPressed() {
if (onBackClickListener != null && onBackClickListener.onBackClick()) {
return;
}
super.onBackPressed();
}
그리고 단편에서 :
((MyActivity) getActivity()).setOnBackClickListener(new MyActivity.OnBackClickListener() {
@Override
public boolean onBackClick() {
if (condition) {
return false;
}
// some codes
return true;
}
});
onDestroyView ()를 사용하는 것은 어떻습니까?
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
// handle back button
replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags);
return true;
}
return false;
}
});
}
뒤로 버튼을 눌렀을 때 활동이 완료되도록 ft.addToBackStack () 메소드를 구현하지 마십시오.
proAddAccount = new ProfileAddAccount();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, proAddAccount);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
다음 단계를 따르십시오.
조각을 추가하는 동안 항상
fragmentTransaction.add(R.id.fragment_container, detail_fragment, "Fragment_tag").addToBackStack(null).commit();
그런 다음 주요 활동에서 재정의 onBackPressed()
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
앱에서 뒤로 버튼을 처리하려면
Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag("Fragment_tag");
if (f instanceof FragmentName) {
if (f != null)
getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit()
}
그게 다야!
매우 짧고 달콤한 답변 :
getActivity().onBackPressed();
내 경우의 전체 시나리오에 대한 설명 :
MainActivity에 FragmentA가 있고 FragmentA에서 FragmentB를 열었습니다 (FragmentB는 FragmentA의 자식 또는 중첩 조각입니다)
Fragment duedateFrag = new FragmentB();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container_body, duedateFrag);
ft.addToBackStack(null);
ft.commit();
이제 FragmentB에서 FragmentA로 이동하려면 간단히 FragmentB를 넣을 수 있습니다 getActivity().onBackPressed();
.
활동 수명주기에서 FragmentActivity 또는 AppCompatActivity를 사용하면 항상 Android 뒤로 버튼이 FragmentManager 트랜잭션을 처리합니다.
백 스택을 처리하기 위해 백 스택 수 또는 태그를 처리 할 필요는 없지만 조각을 추가하거나 교체하는 동안 초점을 유지해야합니다. 뒤로 버튼 케이스를 처리하기 위해 다음 스 니펫을 찾으십시오.
public void replaceFragment(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!(fragment instanceof HomeFragment)) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.activity_menu_fragment_container, fragment).commit();
}
여기에서는 내 응용 프로그램의 홈 페이지이므로 홈 조각에 대한 스택을 다시 추가하지 않습니다. addFBackStack을 HomeFragment에 추가하면 응용 프로그램이 acitivity의 모든 frament를 제거하기 위해 대기 한 다음 빈 화면이 표시되므로 다음 조건을 유지합니다.
if (!(fragment instanceof HomeFragment)) {
transaction.addToBackStack(null);
}
이제 acitvity에서 이전에 추가 된 조각을 볼 수 있으며 HomeFragment에 도달하면 앱이 종료됩니다. 다음 스 니펫을 볼 수도 있습니다.
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
closeDrawer();
} else {
super.onBackPressed();
}
}
에 따르면 AndroidX 릴리스 노트 , androidx.activity 1.0.0-alpha01
출시 및 출시되고 ComponentActivity
, 기존의 새로운 기본 클래스 FragmentActivity
와 AppCompatActivity
. 이 릴리스에는 새로운 기능이 있습니다.
이제 액티비티의 메소드를 재정의 할 필요없이 OnBackPressedCallback
비아 addOnBackPressedCallback
를 등록하여 onBackPressed()
콜백 을 수신 할 수 있습니다.
역행을 처리하기 위해 활동에 단편을 등록 할 수 있습니다.
interface BackPressRegistrar {
fun registerHandler(handler: BackPressHandler)
fun unregisterHandler(handler: BackPressHandler)
}
interface BackPressHandler {
fun onBackPressed(): Boolean
}
용법:
조각에서 :
private val backPressHandler = object : BackPressHandler {
override fun onBackPressed(): Boolean {
showClosingWarning()
return false
}
}
override fun onResume() {
super.onResume()
(activity as? BackPressRegistrar)?.registerHandler(backPressHandler)
}
override fun onStop() {
(activity as? BackPressRegistrar)?.unregisterHandler(backPressHandler)
super.onStop()
}
활동 중 :
class MainActivity : AppCompatActivity(), BackPressRegistrar {
private var registeredHandler: BackPressHandler? = null
override fun registerHandler(handler: BackPressHandler) { registeredHandler = handler }
override fun unregisterHandler(handler: BackPressHandler) { registeredHandler = null }
override fun onBackPressed() {
if (registeredHandler?.onBackPressed() != false) super.onBackPressed()
}
}
public class MyActivity extends Activity {
protected OnBackPressedListener onBackPressedListener;
public interface OnBackPressedListener {
void doBack();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
@Override
public void onBackPressed() {
if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
@Override
protected void onDestroy() {
onBackPressedListener = null;
super.onDestroy();
}
}
단편에서 다음을 추가하고 mainactivity의 인터페이스를 구현하는 것을 잊지 마십시오.
public class MyFragment extends Framgent implements MyActivity.OnBackPressedListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MyActivity) getActivity()).setOnBackPressedListener(this);
}
@Override
public void doBack() {
//BackPressed in activity will call this;
}
}
최고의 솔루션
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
public class BaseActivity extends AppCompatActivity {
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
for (Fragment frag : fm.getFragments()) {
if (frag == null) {
super.onBackPressed();
finish();
return;
}
if (frag.isVisible()) {
FragmentManager childFm = frag.getChildFragmentManager();
if (childFm.getFragments() == null) {
super.onBackPressed();
finish();
return;
}
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
else {
fm.popBackStack();
if (fm.getFragments().size() <= 1) {
finish();
}
return;
}
}
}
}
}
An Activity A가 있고 B, C 및 D와 같은 3 개의 조각을 만드는 경우에는 간단합니다. 이제 조각 B 또는 C에 있고 onBackPressed
매번 조각 D로 이동하려는 경우 onBackPressed()
방법을 재정의해야 합니다. 기본 활동 A 및 조각으로 이동하면 기본 활동 A에서 해당 조각을 인식 하는 TAG 또는 해당 조각의 이름 을 전달하십시오 .
나는 당신이 쉽게 이해할 수있는 그 예를 보여주고 있습니다 ....
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, new C_fragment(),"xyz").commit();
}
또는 프래그먼트 B에서 프래그먼트 C로 이동하고 다시 누르면 다음과 같이 프래그먼트 D에오고 싶습니다.
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, new C_frament(), "xyz").commit();
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Fragment C");
}
});
이제 주요 활동에서 onBackPressed () 메소드를 재정의해야합니다 .... 아래와 같이.
@Override
public void onBackPressed() {
FragmentManager fragmentManager =getSupportFragmentManager();
if (((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")) != null && ((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")).isVisible()) {
Fragment fragment = new D_Fragment();
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
getSupportActionBar().setTitle("D fragment ");
} else {
super.onBackPressed();
}
}
나는 다음과 같이 다른 접근법을 사용했다.
- 오토 이벤트 버스는 활동과 조각 사이의 통신에
- 호출 프래그먼트가 정의한 래핑 된 커스텀 백 액션을 포함하는 액티비티의 스택
Runnable
- 때
onBackPressed
지배 활동에서 호출, 그것은 가장 최근의 사용자 정의 팝업 다시 조치를하고를 실행합니다Runnable
. 스택에 아무것도 없으면 기본값super.onBackPressed()
이 호출됩니다
이 다른 SO 질문에 대한 답변으로 샘플 코드에 대한 전체 접근 방식이 여기 에 포함 됩니다 .
너무 늦었지만 지난주에 같은 문제가 발생했습니다. 어떤 대답도 도움이되지 않았습니다. 그런 다음 코드를 가지고 놀고 있었고 이미 조각을 추가했기 때문에 이것이 효과가있었습니다.
액티비티 OnPageChangeListener
에서ViewPager
사용자가 두 번째 활동에 때를 알 수 있도록. 그가 두 번째 활동에 있으면 true
다음과 같이 부울 을 작성하십시오 .
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(0);
mViewPager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mSectionsPagerAdapter.instantiateItem(mViewPager, position);
if(position == 1)
inAnalytics = true;
else if(position == 0)
inAnalytics = false;
}
@Override
public void onPageScrolled(int position, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
이제 뒤로 버튼을 누를 때마다 부울을 확인하고 현재 항목을 첫 번째 조각으로 설정하십시오.
@Override
public void onBackPressed() {
if(inAnalytics)
mViewPager.setCurrentItem(0, true);
else
super.onBackPressed();
}
파편: 메소드를 배치하는 BaseFragment를 작성하십시오.
public boolean onBackPressed();
활동:
@Override
public void onBackPressed() {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (!fragment.isVisible()) continue;
if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) {
return;
}
}
}
super.onBackPressed();
}
당신의 활동은 첨부되고 보이는 조각을 통해 실행되며 각각에 대해 onBackPressed () 를 그중 하나가 'true'를 반환하면 중단됩니다 (처리되었으므로 더 이상의 조치는 없음).
좋아, 나는 마침내 좋은 해결책을 찾았다.
액티비티 하우징의 onCreate ()에서 프래그먼트는 다음과 같이 백 스택 변경 리스너를 추가합니다.
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
//List<Fragment> f only returns one value
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
(또한 fragmenManager를 추가하면 활동에 선언됩니다. 이제 조각을 변경할 때마다 현재 조각 문자열이 현재 조각의 이름이됩니다. 그런 다음 onBackPressed () 활동에서 뒤로 버튼의 작업을 다음과 같이 제어 할 수 있습니다.
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentOne":
// your code here
return;
case "FragmentTwo":
// your code here
return;
default:
fragmentManager.popBackStack();
// default action for any other fragment (return to previous)
}
}
이 방법이 저에게 효과적임을 확인할 수 있습니다.
참고 URL : https://stackoverflow.com/questions/5448653/how-to-implement-onbackpressed-in-fragments
'Programming' 카테고리의 다른 글
.NET의 문자열에서 분음 부호 (악센트)를 어떻게 제거합니까? (0) | 2020.02.20 |
---|---|
CSS에 패딩이있을 때 넘치지 않고 TextArea를 100 % 너비로 만들려면 어떻게합니까? (0) | 2020.02.20 |
파이썬에서 새로운 받아쓰기 (0) | 2020.02.20 |
Visual Studio에 대한 형식 코드 바로 가기가 있습니까? (0) | 2020.02.20 |
자식 bisect를 사용하는 방법? (0) | 2020.02.20 |