Android에서 다른 조각으로 이동한 후 탐색 스택을 지우는 방법
안드로이드에서 새로운 네비게이션 아키텍처 구성요소를 사용하고 있는데 새 조각으로 이동한 후 네비게이션 스택을 지우는 데 어려움을 겪고 있습니다.
예:저는 loginFragment에 있으며 홈 프래그먼트로 이동할 때 이 프래그먼트가 스택에서 지워져서 사용자가 뒤로 버튼을 누를 때 loginFragment로 되돌아가지 않기를 바랍니다.
간단한 NavHostFragment.findNavController(Fragment).navigate(R.id .homeFragment)를 사용하여 탐색하고 있습니다.
현재 코드:
mAuth.signInWithCredential(credential)
.addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
}
});
탐색기()에서 NavOptions(탐색 옵션)를 사용하려고 했지만 뒤로 가기 버튼이 여전히 loginFragment(로그인 프래그먼트)로 돌아갑니다.
NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setPopUpTo(R.id.homeFragment, false).build();
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment, null, navOptions);
먼저속성추가app:popUpTo='your_nav_graph_id'
그리고.app:popUpToInclusive="true"
작업 태그로 이동합니다.
<fragment
android:id="@+id/signInFragment"
android:name="com.glee.incog2.android.fragment.SignInFragment"
android:label="fragment_sign_in"
tools:layout="@layout/fragment_sign_in" >
<action
android:id="@+id/action_signInFragment_to_usersFragment"
app:destination="@id/usersFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
둘째, 위의 동작을 매개변수로 사용하여 대상으로 이동합니다.
findNavController(fragment).navigate(
SignInFragmentDirections.actionSignInFragmentToUserNameFragment())
자세한 내용은 문서를 참조하십시오.
참고: 방법을 사용하여 탐색하는 경우navigate(@IdRes int resId)
, 원하는 결과를 얻지 못합니다.그래서 방법을 사용했습니다.navigate(@NonNull NavDirections directions)
.
당신의 질문은 구체적으로 Pop Behavior / Pop To / app:popUpTo (xml)를 어떻게 사용하는지에 관한 것이라고 생각합니다.
문서에서,
탐색하기 전에 지정된 대상으로 팝업이 나타납니다.이 대상을 찾을 때까지 백스택에서 일치하지 않는 대상을 모두 팝니다.
예제(Simple Job hunting 앱)
start_screen_nav 그래프는 다음과 같습니다.
startScreenFragment (start) -> loginFragment -> EmployerMainFragment
-> loginFragment -> JobSeekerMainFragment
내가 길을 찾고 싶다면EmployerMainFragment
다음을 포함하여 모두 팝니다. startScreenFragment
그러면 코드는 다음과 같습니다.
<action
android:id="@+id/action_loginFragment_to_employerMainFragment"
app:destination="@id/employerMainFragment"
app:popUpTo="@+id/startScreenFragment"
app:popUpToInclusive="true" />
내가 길을 찾고 싶다면EmployerMainFragment
를 제외하고 모두 팝니다. startScreenFragment
그러면 코드는 다음과 같습니다.
<action
android:id="@+id/action_loginFragment_to_employerMainFragment"
app:destination="@id/employerMainFragment"
app:popUpTo="@+id/startScreenFragment"/>
내가 길을 찾고 싶다면EmployerMainFragment
그리고 팝loginFragment
그러나 그렇지는 startScreenFragment
그러면 코드는 다음과 같습니다.
<action
android:id="@+id/action_loginFragment_to_employerMainFragment"
app:destination="@id/employerMainFragment"
app:popUpTo="@+id/loginFragment"
app:popUpToInclusive="true"/>
오어
<action
android:id="@+id/action_loginFragment_to_employerMainFragment"
app:destination="@id/employerMainFragment"
app:popUpTo="@+id/startScreenFragment"/>
내 경우 새 조각을 열기 전에 백스택에 있는 모든 것을 제거해야 했기 때문에 이 코드를 사용했습니다.
navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);
첫 번째 줄은 홈 프래그먼트이므로 모든 백스택을 완전히 제거하고 fragment_company에서 다시 클릭하면 앱을 닫습니다.
위의 내용들 중 어느 것도 제게 도움이 되지 않았기 때문에 여기에 또 다른 답변을 덧붙이겠습니다.탐색 그래프가 여러 개 있습니다.
findNavController().navigate(R.id.dashboard_graph,null,NavOptions.Builder().setPopUpTo(findNavController().graph.startDestination, true).build())
이것이 제가 전체 백스택을 성공적으로 클리어할 수 있는 유일한 방법이었습니다.구글은 정말로 이것을 더 간단하게 만들 필요가 있습니다.
참고: Clear task는 더 이상 사용되지 않습니다. 공식 설명은 다음과 같습니다.
이 메서드는 더 이상 사용되지 않습니다.NavController의 그래프 ID와 함께 setPopUpTo(int, boolean)를 사용하고 포함을 true로 설정합니다.
오래된 대답
코드의 모든 퍼지를 겪고 싶지 않다면, 당신은 그냥 확인해 볼 수 있습니다.Clear Task
인에Launch Options
그 행위의 성질상
편집: Android Studio 3.2 Beta 5 이후로 작업 지우기가 실행 옵션 창에 더 이상 표시되지 않지만 다음을 추가하여 내비게이션의 XML 코드, 작업 태그에 사용할 수 있습니다.
app:clearTask="true"
NavController navController
=Navigation.findNavController(requireActivity(),
R.id.nav_host_fragment);// initialize navcontroller
if (navController.getCurrentDestination().getId() ==
R.id.my_current_frag) //for avoid crash
{
NavDirections action =
DailyInfoSelectorFragmentDirections.actionGoToDestionationFragment();
//for clear current fragment from stack
NavOptions options = new
NavOptions.Builder().setPopUpTo(R.id.my_current_frag, true).build();
navController.navigate(action, options);
}
새 네비게이션 아키텍처 구성요소로 일부 조각에 대해 네비게이션에서 UP을 비활성화하는 방법 덕분에 드디어 알게 되었습니다.
탐색 옵션으로 .setClearTask(true)를 지정해야 했습니다.
mAuth.signInWithCredential(credential)
.addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setClearTask(true).build();
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment,null,navOptions);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
}
});
이 코드를 사용합니다.
navController.navigateUp();
그런 다음 새 프래그먼트 안드로이드 버전 4.1.2를 호출합니다.
제가 하는 방법은 이렇습니다.
//here the R.id refer to the fragment one wants to pop back once pressed back from the newly navigated fragment
val navOption = NavOptions.Builder().setPopUpTo(R.id.startScorecardFragment, false).build()
//now how to navigate to new fragment
Navigation.findNavController(this, R.id.my_nav_host_fragment)
.navigate(R.id.instoredBestPractice, null, navOption)
위해서
// Navigation library
def nav_version = "2.3.5"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
이 솔루션은 저에게 적합합니다.
findNavController().popBackStack(R.id.<Current Fragment Id In NavGraph>, true)
findNavController().navigate(R.id.< Your Destination Fragment in NavGraph>)
Navigation View(메뉴 드로어)와 함께 Navigation 구성 요소를 사용한 경우:
1.
mNavController.popBackStack(R.id.ID_OF_FRAGMENT_ROOT_TO_POP, true)
mNavController.navigate(
R.id.DESTINATION_ID,
null,
NavOptions.Builder()
.setPopUpTo(R.id.POP_TO_DESTINATION_ID, true)
.build()
)
사이드 메뉴 드로어에서 로그아웃을 클릭한 후 스택을 지우고 싶었습니다.누군가에게 도움이 되었기를!
다음과 같이 기본 작업의 백 프레스를 재정의할 수 있습니다.
override fun onBackPressed() {
val navigationController = nav_host_fragment.findNavController()
if (navigationController.currentDestination?.id == R.id.firstFragment) {
finish()
} else if (navigationController.currentDestination?.id == R.id.secondFragment) {
// do nothing
} else {
super.onBackPressed()
}
}
위의 어떤 해결책도 제게 도움이 되지 않습니다.몇 시간을 들인 후 해결책은 다음과 같습니다.
참고: 여러 개가 있습니다.nav_graphs
서로 다른 조각들 사이에서 전환하는 것.nav_graphs
.
- xml에서 아래와 같이 작업을 정의합니다.
<action android:id="@id/your_action_id" app:destination="@id/the_fragment_id_you_want_to_navigate_to" app:popUpTo="@id/nav_graph_which_contains_destination_fragment" app:popUpToInclusive="true" />
- Java/Kotlin 코드에서 위의 작업을 사용하여 탐색합니다.
findNavController(R.id.your_nav_name)?.apply { navigate(R.id.your_action_id) backQueue.clear() }
Jetpack 구성요소 ❤️
navHostController.navigate(Routes.HOME) {
this.popUpTo(Routes.ONBOARDING) {
this.inclusive = true
}
}
나는 백 버튼이 내 시작 조각으로 돌아가는 것을 막기 위해 한동안 애를 먹었습니다. 그것은 내 경우에는 한 번만 나타나야 하는 인트로 메시지였습니다.
쉬운 해결책은 사용자가 머물러야 할 목적지를 가리키는 글로벌 액션을 만드는 것이었습니다.설정해야 합니다.app:popUpTo="..."
올바르게 - 팝업할 대상으로 설정합니다.저 같은 경우는 제 인트로 메시지였습니다.세트도app:popUpToInclusive="true"
저 같은 경우에는 각자의 탐색 그래프가 있는 두 가지 활동을 사용하고 있습니다.저의 첫 번째 활동은 "nav_graph"의 호스트이며 인증을 다루는 프래그먼트를 가지고 있고 두 번째 활동은 "nav_graph_home"의 호스트입니다.nav_graph에 대한 설정을 확인하실 수 있습니다.
nav_graph 예제
로그인 프래그먼트에 대한 코드를 다시 입력하면 다음과 같이 적을 수 있습니다.
findNavController().navigate(R.id.action_logInFragment_to_nav_graph_home)
사용자가 로그인한 후 뒤로 버튼을 누르면 앱이 닫힙니다.팝업을 포함하지 않고 로그인 조각이 포함된 현재 탐색 그래프로 팝업이 뜨도록 설정해야 합니다.
편집: 이 후에도 위쪽 단추가 위쪽 막대에 계속 나타납니다.이러한 행동을 피하기 위해서는 첫 번째 활동에서 어떤 단편이 최상위 수준으로 간주되는지를 알려주어야 합니다.이렇게 하려면 첫 번째 탐색 그래프와 두 번째 탐색 그래프의 홈 조각 집합을 포함하는 앱바 구성을 탐색 호스트 조각과 함께 "setupActionBarWithNavController()" 메서드의 매개 변수 목록에 추가하면 됩니다.코드는 다음과 같습니다.
class MainActivity : AppCompatActivity(R.layout.activity_main) {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Retrieve NavController from the NavHostFragment
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
// Set up the action bar for use with the NavController
setupActionBarWithNavController(navController, AppBarConfiguration(setOf(R.id.logInFragment,R.id.homeFragment)))
}
/**
* Handle navigation when the user chooses Up from the action bar.
*/
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
이것은 제 생애 첫 기부입니다. 이것이 도움이 되기를 바랍니다.
위해서androidx.compose
버전 1.2.0+
하위 버전에 몇 가지 문제가 있었지만 1.2 플러스(이 글을 쓸 당시 베타)는 완벽하게 작동합니다.
구성에서 navGraph에 대한 구문 개선:
navController.navigate(item.name) {
navController.graph.startDestinationRoute?.let { route ->
// use saveState = false to NOT save the state for the popped route
popUpTo(route) { saveState = true }
}
launchSingleTop = true
restoreState = true
}
버튼을 사용하여 다른 fragment로 이동하고 있으므로 각 버튼에서 이 작업을 수행합니다.
val navOptions = NavOptions.Builder().setLaunchSingleTop(true).setPopUpTo(R.id.homeFragment, false).build()
findNavController(R.id.mainNavHostFragment).navigate(R.id.destination, null, navOptions)
프로그래밍 방식으로 작업을 수행할 때는 다음과 같은 방법으로 작업을 계속할 수 있습니다.
findNavController().navigate(
//your navigation direction
R.id.action_fragmentB_to_fragmentC,
//pass arguments if you have, else null
null,
//Pass the fragment id where you want to land on the back press at fragmentC,
//true/false, in case you want to remove the fragmentA from the back stack use the TRUE and vice versa
NavOptions.Builder().setPopUpTo(R.id.fragmentA, true).build()
)
또한 아래 스크린샷과 같이 네비게이션 그래프 XML에서 다음과 같은 방법으로 달성할 수 있습니다.
베스트 프랙티스는 아니지만 나에게는 효과가 있습니다 (Kotlin/Fragment)
while (findNavController().navigateUp()){findNavController().popBackStack()}
findNavController().navigate(R.id.other_fragment)
다음과 같이 간단하게 수행할 수 있습니다.
getFragmentManager().popBackStack();
카운트를 확인하려면 다음 작업을 수행할 수 있습니다.
getFragmentManager().getBackStackEntryCount()
언급URL : https://stackoverflow.com/questions/50514758/how-to-clear-navigation-stack-after-navigating-to-another-fragment-in-android
'programing' 카테고리의 다른 글
커서를 선언하는 올바른 방법은 무엇입니까? (0) | 2023.09.13 |
---|---|
Should I use Vagrant or Docker for creating an isolated environment? (0) | 2023.09.13 |
행이 없는 경우 행을 삽입하는 방법, 그렇지 않으면 MariaDB에서 두 경우 모두 ID를 선택하고 반환하는 방법은 무엇입니까? (0) | 2023.09.13 |
지난 5년간 조회 (0) | 2023.09.13 |
min SDK version/target SDK version과 complete SDK version의 차이점은 무엇입니까? (0) | 2023.09.13 |