Skip to content

Instantly share code, notes, and snippets.

@pardom-zz
Created August 30, 2016 20:55
Show Gist options
  • Save pardom-zz/aef4c18f1eb5dfff6f8bca08344c06ef to your computer and use it in GitHub Desktop.
Save pardom-zz/aef4c18f1eb5dfff6f8bca08344c06ef to your computer and use it in GitHub Desktop.
package clean.news.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import clean.news.R
import clean.news.core.entity.Item.ListType
import clean.news.inject.ModuleContext
import clean.news.ui.item.list.ItemListKey.ItemListModule
import clean.news.ui.item.list.ItemListView
class ItemListPagerAdapter(context: Context) : ViewStatePagerAdapter() {
val inflater = LayoutInflater.from(context)
private val items = arrayListOf(
ItemListModule(ListType.TOP),
ItemListModule(ListType.NEW),
ItemListModule(ListType.SHOW),
ItemListModule(ListType.ASK),
ItemListModule(ListType.JOB)
)
override fun createView(container: ViewGroup, position: Int): View {
val inflater = inflater.cloneInContext(ModuleContext(inflater.context, items[position]))
val view = inflater.inflate(R.layout.item_list_view, container, false) as ItemListView
container.addView(view)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, obj: Any) {
super.destroyItem(container, position, obj)
val view = obj as View
container.removeView(view)
}
override fun getPageTitle(position: Int): CharSequence? {
return items[position].listType().name
}
override fun getCount(): Int {
return items.size
}
}
package clean.news.ui.item.list
import android.content.Context
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import clean.news.adapter.ItemAdapter
import clean.news.app.util.addTo
import clean.news.flow.service.DaggerService
import clean.news.inject.ModuleContext
import clean.news.presentation.model.item.ItemListViewModel
import clean.news.presentation.model.item.ItemListViewModel.Action
import clean.news.ui.item.list.ItemListKey.ItemListModule
import clean.news.ui.main.MainKey.MainComponent
import redux.asObservable
import rx.subscriptions.CompositeSubscription
import javax.inject.Inject
class ItemListView : RecyclerView {
@Inject
lateinit var model: ItemListViewModel
private val adapter: ItemAdapter
private val subscriptions = CompositeSubscription()
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : super(context, attrs, defStyle) {
DaggerService.get<MainComponent>(context)
?.plus((ModuleContext.get<ItemListModule>(context)))
?.inject(this)
layoutManager = LinearLayoutManager(context)
adapter = ItemAdapter(context)
}
override fun onFinishInflate() {
super.onFinishInflate()
adapter.itemUrlClickListener = { model.dispatch(Action.GoToUrl(it)) }
adapter.itemDetailClickListener = { model.dispatch(Action.GoToDetail(it)) }
setAdapter(adapter)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val stateChanges = model.asObservable()
.startWith(model.getState())
.publish()
stateChanges
.map { it.items }
.distinctUntilChanged()
.subscribe { adapter.setItems(it) }
.addTo(subscriptions)
stateChanges
.connect()
.addTo(subscriptions)
}
override fun onDetachedFromWindow() {
subscriptions.unsubscribe()
super.onDetachedFromWindow()
}
}
package clean.news.inject
import android.content.Context
import android.content.ContextWrapper
class ModuleContext<T : Any>(context: Context, val module: T) : ContextWrapper(context) {
companion object {
inline fun <reified T : Any> get(context: Context): T {
var currentContext = context
while (currentContext is ContextWrapper) {
if (currentContext is ModuleContext<*> && currentContext.module is T) {
return currentContext.module as T
}
currentContext = currentContext.baseContext
}
throw IllegalArgumentException("Context hierarchy contains no module of type ${T::class.java}")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment