[android] Fragments에서 onBackPressed ()를 구현하는 방법은 무엇입니까?

onBackPressed()Android 활동에서 구현하는 방식과 비슷한 방식으로 Android Fragment에서 구현할 수 있는 방법이 있습니까?

조각 수명주기에는 없습니다 onBackPressed(). onBackPressed()안드로이드 3.0 프래그먼트 를 오버라이드 할 수있는 다른 방법이 있습니까?



답변

이 방법으로 onBackPressedActivity에서 재정의 를 해결했습니다 . 모든이 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에 따르면 여기에 의사 코드가 어떻게 작동 해야하는지에 대한 대답이 있습니다. BaseActivitySlidingMenu lib 예제와 같이 하위 조각이있는 기본 활동이 호출되었다고 가정 해 봅시다. 단계는 다음과 같습니다.

먼저 일반적인 메소드를 갖도록 인터페이스를 구현하는 인터페이스와 클래스를 만들어야합니다.

  1. 수업 인터페이스 만들기 OnBackPressedListener

    public interface OnBackPressedListener {
        public void doBack();
    }
  2. 의 기술을 구현하는 수업 만들기 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);
        }
    }
  3. 이제부터 코드 BaseActivity와 그 조각 에 대해 작업하겠습니다.

  4. 수업 위에 비공개 청취자 만들기 BaseActivity

    protected OnBackPressedListener onBackPressedListener;
  5. 리스너를 설정하는 메소드 작성 BaseActivity

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }
  6. 재정의에서 onBackPressed그런 것을 구현하십시오.

    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null)
            onBackPressedListener.doBack();
        else
            super.onBackPressed();
  7. 당신의 조각에 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
    }

이 작업을 수행합니다.


답변

androidx.appcompat:appcompat:1.1.0이상을 사용하는 경우 OnBackPressedCallback다음과 같이 조각에을 추가 할 수 있습니다

requireActivity()
    .onBackPressedDispatcher
    .addCallback(this, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            Log.d(TAG, "Fragment back pressed invoked")
            // Do custom work here    

            // if you want onBackPressed() to be called as normal afterwards
            if (isEnabled) {
                isEnabled = false
                requireActivity().onBackPressed()
            }
        }
    }
)

참조 https://developer.android.com/guide/navigation/navigation-custom-back를