Skip to content
StateBinder is a tiny library for view state management
Branch: master
Clone or download
Latest commit 62b201d Apr 11, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app
gradle/wrapper no message Mar 22, 2019
state-binder
.gitignore
README.md
build.gradle renamed artifact Mar 25, 2019
gradle.properties
gradlew
gradlew.bat
settings.gradle

README.md

StateBinder

Download

StateBinder is a tiny library for view state management.

If you use the MVI pattern or any other pattern using the concept of states to develop your applications, you may have encountered the problem of frequently updating widgets, which leads to poor performance especially when you perform frequent screen state updates. StateBinder eliminates redundant view rendering when the state changes.

Download

dependencies {
  impelentation 'com.olegsheliakin:statebinder:latest'
}

How to use?

  1. Create State class for View:
data class MainState(
    val label: String,
    val errorText: String?
) : State
  1. Create StateBinder:
private val stateBinder: StateBinder<MainState> = StateBinder.create()
  1. Bind state's properties to actions:
stateBinder.apply {
            bind(MainState::label) {
                tvLabel.text = it
            }
            bindNullable(MainState::errorText) {
                etText.error = it
            }
        }

Actions will be called only when properties change.

  1. Create ViewModel/Presenter or any other class that is responsible for changing and emitting State:

    class MainViewModel : ViewModel() {
    
        private val internalState = MutableLiveData<MainState>()
    
        val state: LiveData<MainState> = internalState
    
        init {
            internalState.value = MainState("", null)
        }
    
        fun loadText() {
            internalState.value = MainState("Text", null)
        }
    
        fun initError() {
            internalState.value = MainState("", "Error")
        }
    
    }
  2. Update state by calling:

stateBinder.newState(newState)

Full code:

class MainFragment : Fragment() {

    private val viewModel: MainViewModel by lazy {
        return@lazy ViewModelProviders.of(this@MainFragment)[MainViewModel::class.java]
    }

    //creates StateBinder
    private val stateBinder: StateBinder<MainState> = StateBinder.create()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //refreshes the current state when view is created
        stateBinder.applyCurrentState() 
      
        //binds properties to actions
        stateBinder.apply {
            bind(MainState::label) {
                tvLabel.text = it
            }
            bindNullable(MainState::errorText) {
                etText.error = it
            }
        }
        
        //observers MainState
        viewModel.state.observe(viewLifecycleOwner, Observer {
            it?.let(stateBinder::newState)
        })

    }
}

License

The MIT License (MIT)
=====================

Copyright © 2019 Oleg Sheliakin

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the “Software”), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
You can’t perform that action at this time.