Android:在回压片段上不加载内容



因此,我在项目中使用AndroidNavigation component。我有一个包含3个片段的活动,它们完美地加载并完成了它们需要做的一切。问题是有一个片段在从backpack返回时没有加载其内容。

我使用ViewModel中声明的navigate函数和Navigation中的Directions。示例(vm.navigate(SomeFragmentDirections.actionSomeFragmentToOtherFragment(

A(活性(->B(片段(->C(片段(->D(片段(

当我按下Dfragment返回Cfragment时,它显示了上面的navbar,但没有加载它的内容。我在其他项目中(甚至在这个项目中(对所有其他活动/片段使用相同的原则,我没有遇到这个问题。调用了所有lifecycle函数,一切都应该正常。logcat没有显示任何错误。如果有人对此有所了解,我将不胜感激。

编辑:

这是未加载的片段(片段C(片段D是webView片段,片段C在vm.navigate(RegisterFragmentDirections.actionRegisterFragmentToWebViewFragment(webURL))功能

class RegisterFragment : BaseFragment() {

private val vm: RegisterViewModel by viewModel()

override fun getViewModel(): BaseViewModel = vm

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentRegisterBinding.inflate(inflater, container, false)
context ?: return binding.root
injectFeature()
setToolbar(binding)
subscribeUi(binding)
return binding.root
}
/**
* set toolbar
* **/
private fun setToolbar(binding: FragmentRegisterBinding) {
if (activity is WelcomeActivity) {
binding.appBarLayout.backClickListener = (activity as WelcomeActivity).createOnBackClickListener()
} else if(activity is LoginActivity) {
binding.appBarLayout.backClickListener = (activity as LoginActivity).createOnBackClickListener()
}
}
/**
* set ui
* **/
private fun subscribeUi(binding: FragmentRegisterBinding) {
// set bindings
binding.contentRegister.viewModel = vm
binding.contentSuccess.viewOwner = this
// set true full screen
(activity as LoginActivity).setFullScreen(false)
// set dark status bar icons
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity!!.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
// set initial margin top
ViewCompat.setOnApplyWindowInsetsListener(binding.rootLayout) { _, insets ->
binding.appBarLayout.toolbar.setMarginTop(insets.systemWindowInsetTop)
insets
}
// set phone number mask listener
binding.contentRegister.etPhoneNumber.addTextChangedListener(PhoneNumberFormattingTextWatcher())
// set licence agreement formatted text with hyperlinks
setTextViewHTML(binding.contentRegister.licenceAgreement, getString(R.string.description_privacy_with_link))
// set listener on form elements, error handling
binding.contentRegister.etName.onFocusChangeListener = emptyInputValidationListener(
binding.contentRegister.etName,
binding.contentRegister.tilName,
getString(R.string.error_empty_name)
)
binding.contentRegister.etLastName.onFocusChangeListener = emptyInputValidationListener(
binding.contentRegister.etLastName,
binding.contentRegister.tilLastName,
getString(R.string.error_empty_last_name)
)
binding.contentRegister.etBirthDate.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
when(isBirthDateValid(binding.contentRegister.etBirthDate.text.toString())) {
false -> binding.contentRegister.tilBirthDate.error = getString(R.string.error_date_not_valid)
true -> binding.contentRegister.tilBirthDate.isErrorEnabled = false
}
}
}
binding.contentRegister.etEmail.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
when(!android.util.Patterns.EMAIL_ADDRESS.matcher(binding.contentRegister.etEmail.text!!.trim()).matches()) {
true -> binding.contentRegister.tilEmail.error = getString(R.string.error_email_not_valid)
false -> binding.contentRegister.tilEmail.isErrorEnabled = false
}
}
}
binding.contentRegister.etPassword.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
when (binding.contentRegister.etPassword.text!!.trim().length < 6) {
true -> binding.contentRegister.tilPassword.error =
getString(R.string.error_password_not_valid)
false -> binding.contentRegister.tilPassword.isErrorEnabled = false
}
}
}
binding.contentRegister.registerButton.setOnClickListener{
validateInputs(binding)
}
// set observables
vm.userResponse.observe(viewLifecycleOwner, Observer { updateRegisterSuccess(binding, it) })
}
/**
* update on success / failure
* **/
private fun updateRegisterSuccess(
binding: FragmentRegisterBinding,
resource: Resource<BaseResponseEntity>?
) {
resource?.let {
when (it.state) {
ResourceState.LOADING -> {
binding.contentProgress.isLoading = true
setViewAndChildrenEnabled(binding.rootLayout, false)
}
ResourceState.SUCCESS -> {
binding.contentProgress.isLoading = false
setViewAndChildrenEnabled(binding.rootLayout, true)
}
ResourceState.ERROR -> {
binding.contentProgress.isLoading = false
setViewAndChildrenEnabled(binding.rootLayout, true)
}
}
it.data?.let {
when(it.responseCode) {
RESPONSE_CODE_SUCCESS -> {
binding.contentSuccess.isSucceeded = true
setViewAndChildrenEnabled(binding.rootLayout, true)
}
RESPONSE_CODE_ERROR -> {
if (it.message.isNotEmpty()) {
showSnackbar(it.message, Snackbar.LENGTH_SHORT)
} else {
showSnackbar(getString(R.string.error_unknown), Snackbar.LENGTH_SHORT)
}
}
}
}
it.message?.let {
showSnackbar(getString(R.string.error_unknown), Snackbar.LENGTH_SHORT)
}
}
}
/**
* disable ui elements while loading
* **/
private fun setViewAndChildrenEnabled(view: View, enabled: Boolean) {
view.isEnabled = enabled
if (view is ViewGroup) {
for (i in 0 until view.childCount) {
val child = view.getChildAt(i)
setViewAndChildrenEnabled(child, enabled)
}
}
}
/**
* validate all inputs
* **/
private fun validateInputs(binding: FragmentRegisterBinding) {
// check if all inputs are valid
if(binding.contentRegister.etName.text!!.trim().isEmpty()) {
binding.contentRegister.etName.requestFocus()
binding.contentRegister.tilName.error = getString(R.string.error_empty_name)
return
}
if(binding.contentRegister.etLastName.text!!.trim().isEmpty()) {
binding.contentRegister.etLastName.requestFocus()
binding.contentRegister.tilLastName.error = getString(R.string.error_empty_last_name)
return
}
if (binding.contentRegister.etBirthDate.rawText.isNotEmpty()) {
if (!isBirthDateValid(binding.contentRegister.etBirthDate.text.toString())) {
binding.contentRegister.etBirthDate.requestFocus()
binding.contentRegister.tilBirthDate.error =
getString(R.string.error_date_not_valid)
return
}
}
if(!android.util.Patterns.EMAIL_ADDRESS.matcher(binding.contentRegister.etEmail.text!!.trim()).matches()) {
binding.contentRegister.etEmail.requestFocus()
binding.contentRegister.tilEmail.error = getString(R.string.error_date_not_valid)
return
}
if(binding.contentRegister.etPassword.text!!.trim().length < PASSWORD_MINIMUM_LENGHT) {
binding.contentRegister.etPassword.requestFocus()
binding.contentRegister.tilPassword.error = getString(R.string.error_password_not_valid)
return
}
if(!binding.contentRegister.checkBox.isChecked) {
showSnackbar(getString(R.string.error_terms_and_conditions), Snackbar.LENGTH_SHORT)
return
}
// handle date of birth
val dateOfBirth = if (binding.contentRegister.etBirthDate.rawText.trim().isNotEmpty()
&& isBirthDateValid(binding.contentRegister.etBirthDate.rawText)) {
binding.contentRegister.etBirthDate.text.toString().replace("/", "-")
} else {
""
}
binding.rootLayout.hideKeyboard()
vm.register(
username = binding.contentRegister.etEmail.text.toString(),
password = binding.contentRegister.etPassword.text.toString(),
name = binding.contentRegister.etName.text.toString(),
lastName = binding.contentRegister.etLastName.text.toString(),
phoneNumber = binding.contentRegister.etPhoneNumber.text.toString(),
dateOfBirth = dateOfBirth)
Timber.d(dateOfBirth)
}
//todo handle this and move to util class
@Suppress("DEPRECATION")
private fun setTextViewHTML(text: TextView, html: String) {
// replace n new line so android can show new line for text which we previously fetchCompanies from server
val hmtlFormatted = html.replace("n", "<br>")
val sequence = Html.fromHtml(hmtlFormatted)
val strBuilder = SpannableStringBuilder(sequence)
val urls = strBuilder.getSpans(0, sequence.length, URLSpan::class.java)
for (span in urls) {
makeLinkClickable(strBuilder, span)
}
text.text = strBuilder
text.movementMethod = LinkMovementMethod.getInstance()
}
private fun makeLinkClickable(strBuilder: SpannableStringBuilder, span: URLSpan) {
val start = strBuilder.getSpanStart(span)
val end = strBuilder.getSpanEnd(span)
val flags = strBuilder.getSpanFlags(span)
val clickable = object : ClickableSpan() {
override fun onClick(view: View) {
// Do something with span.getURL() to handle the link click...
val webURL = span.url
vm.navigate(RegisterFragmentDirections.actionRegisterFragmentToWebViewFragment(webURL))
}
}
strBuilder.setSpan(clickable, start, end, flags)
strBuilder.removeSpan(span)
}
// PUBLIC ACTIONS ---
fun onRegisterDoneClick() {
// navigate to welcome activity and finish it
onRegisterSuccess()
}

/**
* on register success
* **/
private fun onRegisterSuccess() {
// navigate to welcome activity and finish it
val returnIntent = Intent()
(activity as LoginActivity).setResult(Activity.RESULT_OK, returnIntent)
(activity as LoginActivity).finish()
}

只有当片段附加到活动时,才能获得上下文
当调用onCreateView时,您还没有上下文,它返回:

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentRegisterBinding.inflate(inflater, container, false)
context ?: return binding.root
// ...
}

您应该将设置逻辑移动到onViewCreated:

lateinit var binding: FragmentRegisterBinding 
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentRegisterBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
injectFeature()
setToolbar(binding)
subscribeUi(binding)
}

相关内容

  • 没有找到相关文章

最新更新