Created
November 3, 2017 15:22
-
-
Save bitsydarel/52188f08139c1b163ed7b3832a9ac311 to your computer and use it in GitHub Desktop.
MVP RecyclerView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 Darel Bitsy | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License | |
*/ | |
package com.dbeginc.dbweather.config.managesources.adapter.presenter | |
import com.dbeginc.dbweather.config.managesources.adapter.SourceContract | |
import com.dbeginc.dbweather.viewmodels.news.SourceModel | |
import com.dbeginc.dbweather.viewmodels.news.toDomain | |
import com.dbeginc.dbweatherdomain.entities.requests.news.SourceRequest | |
import com.dbeginc.dbweatherdomain.usecases.news.SubscribeToSource | |
import com.dbeginc.dbweatherdomain.usecases.news.UnSubscribeToSource | |
/** | |
* Created by darel on 27.10.17. | |
* | |
* Source Presenter Implementation | |
*/ | |
class SourcePresenterImpl(private val source: SourceModel, | |
private val subscribeToSource: SubscribeToSource, | |
private val unSubscribeToSource: UnSubscribeToSource) : SourceContract.SourcePresenter { | |
private lateinit var view: SourceContract.SourceView | |
override fun bind(view: SourceContract.SourceView) { | |
this.view = view | |
this.view.setupView() | |
} | |
override fun unBind() { | |
subscribeToSource.clean() | |
unSubscribeToSource.clean() | |
} | |
override fun loadSource() { | |
view.displaySource(source) | |
} | |
override fun onAction() { | |
view.goToSourceDetail() | |
} | |
override fun onSubscribe() { | |
if (source.subscribed) { | |
unSubscribeToSource.execute(SourceRequest(source.id, source.apply { subscribed = false }.toDomain())) | |
.doOnSubscribe { view.showUpdateStatus() } | |
.doOnTerminate { view.hideUpdateStatus() } | |
.subscribe( | |
{ view.showUnSubscribed() }, | |
{ error -> view.showError(error.localizedMessage) } | |
) | |
} else { | |
subscribeToSource.execute(SourceRequest(source.id, source.apply { subscribed = true }.toDomain())) | |
.doOnSubscribe { view.showUpdateStatus() } | |
.doOnTerminate { view.hideUpdateStatus() } | |
.subscribe( | |
{ view.showSubscribed() }, | |
{ error -> view.showError(error.localizedMessage) } | |
) | |
} | |
} | |
override fun getData(): SourceModel = source | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 Darel Bitsy | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License | |
*/ | |
package com.dbeginc.dbweather.config.managesources.adapter | |
import com.dbeginc.dbweather.base.IPresenter | |
import com.dbeginc.dbweather.base.IView | |
import com.dbeginc.dbweather.viewmodels.news.SourceModel | |
/** | |
* Created by darel on 27.10.17. | |
* | |
* Source Contract | |
*/ | |
interface SourceContract { | |
interface SourceView : IView { | |
fun displaySource(source: SourceModel) | |
fun definePresenter(presenter: SourcePresenter) | |
fun showSubscribed() | |
fun showUnSubscribed() | |
fun showUpdateStatus() | |
fun hideUpdateStatus() | |
fun goToSourceDetail() | |
fun showError(message: String) | |
} | |
interface SourcePresenter: IPresenter<SourceView> { | |
fun loadSource() | |
fun onAction() | |
fun onSubscribe() | |
fun getData(): SourceModel | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 Darel Bitsy | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License | |
*/ | |
package com.dbeginc.dbweather.config.managesources.adapter | |
import android.support.v7.util.DiffUtil | |
import com.dbeginc.dbweather.viewmodels.news.SourceModel | |
/** | |
* Created by darel on 27.10.17. | |
* | |
* Source Difference Util | |
*/ | |
class SourceDiffUtil(private val old: List<SourceContract.SourcePresenter>, private val new: List<SourceModel>) : DiffUtil.Callback() { | |
override fun getOldListSize(): Int = old.size | |
override fun getNewListSize(): Int = new.size | |
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { | |
return old[oldItemPosition].getData().id == new[newItemPosition].id | |
} | |
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { | |
return old[oldItemPosition].getData() == new[newItemPosition] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 Darel Bitsy | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License | |
*/ | |
package com.dbeginc.dbweather.config.managesources.adapter | |
import android.databinding.DataBindingUtil | |
import android.support.v7.util.DiffUtil | |
import android.support.v7.widget.RecyclerView | |
import android.view.LayoutInflater | |
import android.view.ViewGroup | |
import com.dbeginc.dbweather.R | |
import com.dbeginc.dbweather.config.managesources.adapter.presenter.SourcePresenterImpl | |
import com.dbeginc.dbweather.config.managesources.adapter.view.SourceViewHolder | |
import com.dbeginc.dbweather.viewmodels.news.SourceModel | |
import com.dbeginc.dbweatherdomain.usecases.news.SubscribeToSource | |
import com.dbeginc.dbweatherdomain.usecases.news.UnSubscribeToSource | |
import kotlinx.coroutines.experimental.android.UI | |
import kotlinx.coroutines.experimental.async | |
import org.jetbrains.anko.coroutines.experimental.bg | |
import java.util.* | |
/** | |
* Created by darel on 27.10.17. | |
* | |
* Sources Adapter | |
*/ | |
class SourcesAdapter(sources: List<SourceModel>, | |
private val subscribeToSource: SubscribeToSource, | |
private val unSubscribeToSource: UnSubscribeToSource) : RecyclerView.Adapter<SourceViewHolder>() { | |
private var container: RecyclerView? = null | |
private val presenters: LinkedList<SourceContract.SourcePresenter> | |
init { | |
presenters = LinkedList( | |
sources.map { source -> SourcePresenterImpl(source, subscribeToSource, unSubscribeToSource) } | |
.sortedBy { presenter -> presenter.getData().name } | |
) | |
} | |
override fun onAttachedToRecyclerView(recyclerView: RecyclerView?) { | |
super.onAttachedToRecyclerView(recyclerView) | |
container = recyclerView | |
} | |
override fun getItemCount(): Int = presenters.size | |
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): SourceViewHolder { | |
return SourceViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent?.context), R.layout.source_item, parent, false)) | |
} | |
override fun onBindViewHolder(holder: SourceViewHolder, position: Int) { | |
val presenter = presenters[position] | |
// cleaning state of view holder before binding it to new data | |
holder.cleanState() | |
holder.definePresenter(presenter) | |
presenter.bind(holder) | |
presenter.loadSource() | |
} | |
fun update(newData: List<SourceModel>) { | |
async(UI) { | |
val result = bg { DiffUtil.calculateDiff(SourceDiffUtil(presenters, newData.sortedBy { source -> source.name })) }.await() | |
container?.post { | |
presenters.clear() | |
newData.mapTo(presenters) { source -> SourcePresenterImpl(source, subscribeToSource, unSubscribeToSource) } | |
presenters.sortBy { presenter -> presenter.getData().name } | |
result.dispatchUpdatesTo(this@SourcesAdapter) | |
} | |
} | |
} | |
fun getData(): List<SourceModel> = presenters.map { presenter -> presenter.getData() } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 Darel Bitsy | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License | |
*/ | |
package com.dbeginc.dbweather.config.managesources.adapter.view | |
import android.support.v7.widget.RecyclerView | |
import com.dbeginc.dbweather.R | |
import com.dbeginc.dbweather.config.managesources.adapter.SourceContract | |
import com.dbeginc.dbweather.databinding.SourceItemBinding | |
import com.dbeginc.dbweather.utils.utility.remove | |
import com.dbeginc.dbweather.utils.utility.show | |
import com.dbeginc.dbweather.utils.utility.toast | |
import com.dbeginc.dbweather.viewmodels.news.SourceModel | |
/** | |
* Created by darel on 27.10.17. | |
* | |
* Source View Holder | |
*/ | |
class SourceViewHolder(private val binding: SourceItemBinding): RecyclerView.ViewHolder(binding.root), SourceContract.SourceView { | |
private var presenter: SourceContract.SourcePresenter? = null | |
override fun setupView() {/*** Not needed here ****/} | |
override fun cleanState() { | |
presenter?.unBind() | |
} | |
override fun displaySource(source: SourceModel) { | |
binding.source = source | |
binding.sourceSubscribed.setImageResource(if (source.subscribed) R.drawable.follow_icon else R.drawable.un_follow_icon) | |
binding.executePendingBindings() | |
} | |
override fun showSubscribed() = binding.sourceSubscribed.setImageResource(R.drawable.follow_icon) | |
override fun showUnSubscribed() = binding.sourceSubscribed.setImageResource(R.drawable.un_follow_icon) | |
override fun goToSourceDetail() = binding.sourceLayout.toast("Going to Detail for ${binding.source?.name}") | |
override fun showUpdateStatus() = binding.sourceUpdatingStatus.show() | |
override fun hideUpdateStatus() = binding.sourceUpdatingStatus.remove() | |
override fun showError(message: String) = binding.sourceLayout.toast(message) | |
override fun definePresenter(presenter: SourceContract.SourcePresenter) { | |
this.presenter = presenter | |
binding.sourceLayout.setOnClickListener { this.presenter?.onAction() } | |
binding.sourceSubscribed.setOnClickListener { this.presenter?.onSubscribe() } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment