ganfra / MaterialSpinner

Spinner with Material Design - Down to API 14
Apache License 2.0
946 stars 214 forks source link

App crashes when I want to set error after rotating layout from fragment #145

Open fabrizziocht opened 5 years ago

fabrizziocht commented 5 years ago

Hello, I'm using Viewmodel to get the errorstate after rotating the device but app crashes, it occurs only with this material spinner, using Edittext there is no problem. Here the error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.jgm90.neumaticos, PID: 15814
    java.lang.IllegalArgumentException: Layout: -126 < 0
        at android.text.Layout.<init>(Layout.java:250)
        at android.text.StaticLayout.<init>(StaticLayout.java:509)
        at android.text.StaticLayout.<init>(StaticLayout.java:493)
        at android.text.StaticLayout.<init>(StaticLayout.java:479)
        at android.text.StaticLayout.<init>(StaticLayout.java:466)
        at fr.ganfra.materialspinner.MaterialSpinner.prepareBottomPadding(MaterialSpinner.java:380)
        at fr.ganfra.materialspinner.MaterialSpinner.setError(MaterialSpinner.java:760)
        at com.jgm90.neumaticos.ui.Main.Control.ControlInfoBasicaFragment$initView$6.onChanged(ControlInfoBasicaFragment.kt:62)
        at com.jgm90.neumaticos.ui.Main.Control.ControlInfoBasicaFragment$initView$6.onChanged(ControlInfoBasicaFragment.kt:23)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:424)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:376)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:293)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:333)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
        at androidx.fragment.app.Fragment.performStart(Fragment.java:2486)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:919)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStart(FragmentManagerImpl.java:2571)
        at androidx.fragment.app.Fragment.performStart(Fragment.java:2484)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:919)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStart(FragmentManagerImpl.java:2571)
        at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:256)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:533)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:179)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
        at android.app.Activity.performStart(Activity.java:7157)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

It only happens when I'm trying to set the error message again after rotating with this line:


override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initView()
    }
    private fun initView() {
        vehiculosAdapter = ArrayAdapter(context, R.layout.spinner_item, ArrayList<Vehiculo>()).apply { setDropDownViewResource(R.layout.spinner_dropdown_item) }
        tiposControlAdapter = ArrayAdapter(context, R.layout.spinner_item, ArrayList<Tipo>()).apply { setDropDownViewResource(R.layout.spinner_dropdown_item) }

        sp_vehiculo.apply { adapter = vehiculosAdapter }.onItemSelectedListener = this
        sp_tipocontrol.apply { adapter = tiposControlAdapter }.onItemSelectedListener = this
         // vm is a viewmodel restoring the data
        vehiculosAdapter.apply { clear() }.addAll(vm.getVehiculos())
        sp_vehiculo.setSelection(vehiculosAdapter.getPosition(vm.vehiculo.value) + 1)
        vm.errorVehiculo.observe(this, Observer {
            sp_vehiculo.error = it <- HERE CRASHES
        })

        tiposControlAdapter.apply { clear() }.addAll(vm.getTiposControl())
        sp_tipocontrol.setSelection(tiposControlAdapter.getPosition(vm.tipoControl.value) + 1)
        vm.errorTipo.observe(this, Observer {
            sp_tipocontrol.error = it <- HERE CRASHES TOO
        })
        }
    }```
fabrizziocht commented 5 years ago

I found a workaround solution, using a delay works well:


Handler().postDelayed({ sp_tipocontrol.error = it }, 200)