java - 阻止应用程序在向上导航时返回登录/注册屏幕
问题描述
我正在开发具有登录、注册和重置密码屏幕的应用程序,问题是在注册或登录后,当我单击后退按钮时它不会关闭应用程序,即使我使用app:launchSingleTop="true"
和导航到注册或登录屏幕也是如此app:popUpToInclusive="true"
但它似乎不起作用
下面的gif更多地解释了这个问题
导航图xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/registerFragment">
<fragment
android:id="@+id/loginFragment"
android:name="com.mml.mymall.LoginFragment"
android:label="fragment_login"
tools:layout="@layout/fragment_login">
<action
android:id="@+id/action_loginFragment_to_registerFragment"
app:destination="@id/registerFragment"
app:enterAnim="@anim/slide_in_left"
app:exitAnim="@anim/slide_in_right"
app:popEnterAnim="@anim/slide_out_right"
app:popExitAnim="@anim/slide_out_left" />
<action
android:id="@+id/action_loginFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:launchSingleTop="true"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_loginFragment_to_resetPasswordFragment"
app:destination="@id/resetPasswordFragment"
app:popUpTo="@id/loginFragment" />
</fragment>
<fragment
android:id="@+id/registerFragment"
android:name="com.mml.mymall.RegisterFragment"
android:label="fragment_register"
tools:layout="@layout/fragment_register">
<action
android:id="@+id/action_registerFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:enterAnim="@anim/slide_in_left"
app:exitAnim="@anim/slide_out_right"
app:popEnterAnim="@anim/slide_out_right"
app:popExitAnim="@anim/slide_out_left" />
<action
android:id="@+id/action_registerFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:launchSingleTop="false"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/homeFragment"
android:name="com.mml.mymall.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home"/>
<fragment
android:id="@+id/resetPasswordFragment"
android:name="com.mml.mymall.ResetPasswordFragment"
android:label="fragment_reset_password"
tools:layout="@layout/fragment_reset_password" />
</navigation>
登录片段
public class LoginFragment extends Fragment {
private FragmentLoginBinding binding;
private FirebaseAuth firebaseAuth;
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentLoginBinding.inflate(inflater, container, false);
firebaseAuth = FirebaseAuth.getInstance();
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.inputEmail.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
checkInputs();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
binding.inputPassword.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
checkInputs();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
binding.btnlogin.setOnClickListener(view1 -> checkEmailAndPassword());
binding.textViewSignUp.setOnClickListener(view1 ->
Navigation.findNavController(requireView()).navigate(
LoginFragmentDirections.actionLoginFragmentToRegisterFragment()
)
);
binding.forgotPassword.setOnClickListener(view1 ->
Navigation.findNavController(requireView()).navigate(LoginFragmentDirections.actionLoginFragmentToResetPasswordFragment()
));
}
private void checkEmailAndPassword() {
binding.progressBar.setVisibility(View.VISIBLE);
if (TextUtils.isEmpty(binding.inputEmail.getText()) ||
!Patterns.EMAIL_ADDRESS.matcher(binding.inputEmail.getText()).matches()) {
binding.inputEmail.setError("Invalid email");
binding.progressBar.setVisibility(View.INVISIBLE);
} else if (TextUtils.isEmpty(binding.inputPassword.getText()) ||
binding.inputPassword.getText().toString().length() < 8) {
binding.inputPassword.setError("Invalid password");
binding.progressBar.setVisibility(View.INVISIBLE);
} else {
firebaseAuth.signInWithEmailAndPassword(binding.inputEmail.getText().toString(),
binding.inputPassword.getText().toString()).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
binding.progressBar.setVisibility(View.INVISIBLE);
Navigation.findNavController(requireView())
.navigate(LoginFragmentDirections
.actionLoginFragmentToHomeFragment());
} else {
binding.progressBar.setVisibility(View.INVISIBLE);
Toast.makeText(requireContext(), task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
private void checkInputs() {
if (!TextUtils.isEmpty(binding.inputEmail.getText())) {
binding.btnlogin.setEnabled(!TextUtils.isEmpty(binding.inputPassword.getText()));
} else {
binding.btnlogin.setEnabled(false);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
注册片段
@Override
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.alreadyHaveAccount.setOnClickListener(view1 ->
Navigation.findNavController(getView())
.navigate(RegisterFragmentDirections.actionRegisterFragmentToLoginFragment())
);
}
MainActivity 类
public class MainActivity extends AppCompatActivity {
private NavController navController;
private FirebaseAuth firebaseAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_MyMall);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = firebaseAuth.getCurrentUser();
NavHostFragment navHostFragment =
(NavHostFragment)
getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_container);
navController = navHostFragment.getNavController();
if (currentUser != null) {
navController.navigate(R.id.homeFragment);
}
}
@Override
public boolean onSupportNavigateUp() {
return navController.navigateUp() || super.onSupportNavigateUp();
}
}
PS:我尝试了没有这种方法的应用程序,onSupportNavigateUp
但没有效果,我还有另一个具有相同结构但在 kotlin 中的项目,一切正常
解决方案
您应该将popUpTo
属性设置为操作。由于您的起始目的地是 RegisterFragment,您可以设置popUpTo="@id/registerFragment"
为@id/action_loginFragment_to_homeFragment
@id/action_registerFragment_to_homeFragment
例如:
<action
android:id="@+id/action_loginFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@id/registerFragment"
app:popUpToInclusive="true" />
推荐阅读
- javascript - 如何根据另一个 td 中的选择列表项在 td 中显示模型中的数据
- xml - 将 .xml 图像注释转换为遮罩(.jpg 或 .png)
- r - 按组计算速率
- mysql - 在 MySQL 查询中对记录子集执行一些算术运算
- javascript - face-api.js - 为什么浏览器的 faceapi.detectAllFaces() 比服务器的快?
- c# - 使用 JSON 正文绑定模型,不使用 [FromBody]
- console - Julia:控制台输入验证
- powerbi-desktop - 如何减少/消除 Power BI Desktop 中的数据导入?
- php - 为什么不序列化 ActiveForm 对象
- c# - 在 Azure Rest API C# 中查找 SID 的用户名