I have an activity which has a container for fragments.
I have three fragments in that particular activity. When I rotate the screen it comes to first fragment. How can I make it show the second fragment if it was the current screen.
I tried to add this method Handle Fragment On Screen Orientation Changes?.
But I am having error:
java.lang.IllegalStateException: Fragment VerifyOtp{d123b5f} (79fc7cef-725d-48cb-9591-3fa9da9f864f) is not currently in the FragmentManager
MainActivity code:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val sharedPref = getSharedPreferences("loggedUser", Context.MODE_PRIVATE)
val userPhone = sharedPref.getString("userPhone", null)
val location = sharedPref.getString("location", null)
if(userPhone == null){
val loginFragment = LoginFragment()
supportFragmentManager.beginTransaction().replace(R.id.loginFrameLayout, loginFragment).commit()
}
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
instantiateFragment(savedInstanceState)
}
private fun instantiateFragment(inState: Bundle){
val manager = supportFragmentManager
val transaction = manager.beginTransaction()
if(inState != null){
manager.getFragment(inState, "VERIFY_OTP")
}
}
}
LoginFragment:
class LoginFragment : Fragment() {
private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentLoginBinding.inflate(inflater, container, false)
val view = binding.root
ArrayAdapter.createFromResource(
view.context,
R.array.country_code,
android.R.layout.simple_spinner_item
).also { adapter ->
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.countryCode.adapter = adapter
}
val fragmentVerifyOTP = VerifyOtp()
binding.btnLogin.setOnClickListener {
var userPhoneNumber = binding.userPhoneNumber.text.toString()
if(userPhoneNumber.isEmpty() || userPhoneNumber.length < 10) {
binding.userPhoneNumber.error = "Phone Number Required"
}else{
val arguments = Bundle()
arguments.putString("Phone", userPhoneNumber)
fragmentVerifyOTP.arguments = arguments
val transaction = activity?.supportFragmentManager?.beginTransaction()
if (transaction != null) {
transaction.replace(R.id.loginFrameLayout, fragmentVerifyOTP, "VERIFY_OTP")
transaction.addToBackStack("")
transaction.commit()
}
}
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
VerifyOTP:
class VerifyOtp : Fragment() {
private var _binding: FragmentVerifyOtpBinding? = null
private val binding get() = _binding!!
private lateinit var phone: String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentVerifyOtpBinding.inflate(inflater, container, false)
val view = binding.root
val bundle = this.arguments
if(bundle != null){
phone = bundle.getString("Phone").toString()
}
val application = requireNotNull(this.activity).application
val dataSource = AppDatabase.getInstance(application)
val viewModelFactory = LoginSharedViewModelFactory(phone, dataSource)
val viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(LoginSharedViewModel::class.java)
viewModel.setPhoneNumber(phone)
viewModel.phoneNumber.observe(viewLifecycleOwner, { phone ->
binding.tvOTPPhoneNumber.text = phone
})
binding.btnVerify.setOnClickListener {
val isFieldsSet = checkAllFields()
if(isFieldsSet && viewModel.newUser()){
val transaction = fragmentManager?.beginTransaction()
if (transaction != null) {
transaction.replace(R.id.loginFrameLayout, UserDetails())
transaction.addToBackStack("")
transaction.commit()
}
}else if(isFieldsSet && !viewModel.newUser()){
insertToSharedPreference(viewModel.phoneNumber.value,
viewModel.currentUser.value?.location
)
val user = viewModel.phoneNumber.value
val intent = Intent(view.context, Home::class.java).apply {
putExtra("USER_PHONE", user)
}
startActivity(intent)
}
}
return view
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val manager = activity?.supportFragmentManager
manager?.putFragment(outState, "VERIFY_OTP", VerifyOtp())
}