Skip to content

Instantly share code, notes, and snippets.

@alashow
Created April 4, 2018 21:36
Show Gist options
  • Save alashow/8d449d91f70e6693c38011840845e492 to your computer and use it in GitHub Desktop.
Save alashow/8d449d91f70e6693c38011840845e492 to your computer and use it in GitHub Desktop.
package tm.alashow.x.ui.base
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.databinding.DataBindingUtil
import android.databinding.ViewDataBinding
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.support.annotation.StringRes
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.MenuItem
import dagger.android.support.DaggerAppCompatActivity
import tm.alashow.x.R
import tm.alashow.x.base.interfaces.OnBackPressedListener
import tm.alashow.x.base.interfaces.OnToolbarClickedListener
import javax.inject.Inject
abstract class BaseActivity<VDB : ViewDataBinding, VM : ViewModel> : DaggerAppCompatActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
internal lateinit var binding: VDB
internal lateinit var viewModel: VM
protected lateinit var toolbarView: Toolbar
private val onToolbarClickedListeners = HashSet<OnToolbarClickedListener>()
private val onBackPressedListeners = HashSet<OnBackPressedListener>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, getLayout())
viewModel = ViewModelProviders.of(this, viewModelFactory).get(getVmClass())
binding.setLifecycleOwner(this)
initViews()
}
override fun onBackPressed() {
for (onBackPressedListener in onBackPressedListeners) {
if (onBackPressedListener.onBackPressed()) {
return
}
}
super.onBackPressed()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
}
}
return false
}
/**
* Initializes views
*/
private fun initViews() {
setupToolbar(findViewById(R.id.toolbar)!!)
setTitle(getDefaultTitle())
}
/**
* Setup given toolbar.
*/
private fun setupToolbar(toolbar: Toolbar) {
this.toolbarView = toolbar
setSupportActionBar(this.toolbarView)
// showing back button on toolbar if child activity
if (isChildActivity() && supportActionBar != null) {
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
toolbar.setOnClickListener({
for (listener in onToolbarClickedListeners) listener.scrollUp()
})
}
override fun setTitle(@StringRes stringRes: Int) = setTitle(getString(stringRes))
/**
* Sets title to actionbar, falling back to toolbarView if getSupportActionBar is null
*
* @param title string
*/
fun setTitle(title: String?) {
if (supportActionBar != null) {
supportActionBar!!.title = title
} else {
toolbarView.title = title
}
}
/**
* @return current activity, for god object :)
*/
protected fun getActivity(): AppCompatActivity {
return this
}
/**
* @return viewModel class for base to setup.
*/
protected abstract fun getVmClass(): Class<VM>
/**
* @return layout to setup data binding.
*/
@LayoutRes
protected abstract fun getLayout(): Int
/**
* @return Default actionbar title
*/
@StringRes
protected abstract fun getDefaultTitle(): Int
abstract fun isChildActivity(): Boolean
// Some listeners
fun addOnToolbarClickedListener(listener: OnToolbarClickedListener) = onToolbarClickedListeners.add(listener)
fun removeOnToolbarClickedListener(listener: OnToolbarClickedListener) = onToolbarClickedListeners.remove(listener)
fun addOnBackPressedListener(listener: OnBackPressedListener) = onBackPressedListeners.add(listener)
fun removeOnBackPressedListener(listener: OnBackPressedListener) = onBackPressedListeners.remove(listener)
}
package tm.alashow.x.ui.base
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.databinding.DataBindingUtil
import android.databinding.ViewDataBinding
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.support.annotation.StringRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import tm.alashow.x.R
import javax.inject.Inject
abstract class BaseFragment<VDB : ViewDataBinding, VM : ViewModel> : DaggerFragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
internal lateinit var binding: VDB
internal lateinit var viewModel: VM
protected var fragmentNavigator: FragmentNavigator? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this, viewModelFactory).get(getVmClass())
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, getLayout(), container, false)
binding.setLifecycleOwner(this)
return binding.root
}
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context is FragmentNavigator) {
fragmentNavigator = context
}
}
/**
* Setting title to BaseActivity safer
*/
fun setTitle(title: String?) {
try {
if (activity is BaseActivity<*, *>) {
(activity as BaseActivity<*, *>).setTitle(title)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* @return viewModel class for base to setup.
*/
protected abstract fun getVmClass(): Class<VM>
/**
* @return layout to setup data binding.
*/
@LayoutRes
protected abstract fun getLayout(): Int
/**
* @return default title for fragment
*/
@StringRes
open fun getTitle(): Int {
return R.string.app_name
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment