Created
May 15, 2019 07:33
-
-
Save effe-megna/8b6be2b8550052b4cdad3413aa5a4269 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| package com.bepower.becharge.ui | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.View.OnClickListener | |
| import android.view.ViewGroup | |
| import androidx.databinding.DataBindingUtil | |
| import androidx.databinding.ViewDataBinding | |
| import androidx.recyclerview.widget.DiffUtil | |
| import androidx.recyclerview.widget.LinearLayoutManager | |
| import androidx.recyclerview.widget.RecyclerView | |
| import com.bepower.becharge.MainActivity | |
| import com.bepower.becharge.R | |
| import com.bepower.becharge.databinding.ActivityHeaderRowBinding | |
| import com.bepower.becharge.databinding.CardUserActivityBinding | |
| import com.bepower.becharge.databinding.CardUserRateplanBinding | |
| import com.bepower.becharge.databinding.FragmentActivitiesHistoryBinding | |
| import com.bepower.becharge.extensions.AnimationType | |
| import com.bepower.becharge.extensions.tryCatchLifecycleAware | |
| import com.bepower.becharge.net.models.ActivitiesResponse | |
| import com.bepower.becharge.net.models.Activity | |
| import com.bepower.becharge.net.models.ActivityRow | |
| import com.bepower.becharge.net.models.ActivityType | |
| import com.bepower.becharge.viewModels.ActivitiesHistoryViewModel | |
| import jp.wasabeef.recyclerview.animators.SlideInDownAnimator | |
| import kotlinx.android.synthetic.main.fragment_country_selection.* | |
| import kotlinx.coroutines.launch | |
| import kotlin.properties.Delegates | |
| data class ActivityHeader( | |
| val date: String, | |
| val totalEnergy: String | |
| ): ActivityRow | |
| class ActivitiesHistoryFragment : BaseFragment() { | |
| val mViewModel: ActivitiesHistoryViewModel by lazy { | |
| constructViewModel(ActivitiesHistoryViewModel(applicationComponent, application)) | |
| } | |
| val adapter = ActivitiesAdapter { [email protected](it) } | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| launch { | |
| initRecyclerView() | |
| } | |
| // init with mock activities ** WORKAROUND ** | |
| adapter.activities = mViewModel.generateActivitiesRowFromActivityResponse(ActivitiesResponse( | |
| listOf( | |
| Activity(cp_id = "123", type = ActivityType.recharge, deactivation = true, date = null, description = null, end_date = null, energy = null, evc_address = null, evc_city = null, evc_id = null, invoice_data = null, invoice_pdf = null, payment_status = null, price = null, start_date = null), | |
| Activity(cp_id = "123", type = ActivityType.recharge_outbound, deactivation = true, date = null, description = null, end_date = null, energy = null, evc_address = null, evc_city = null, evc_id = null, invoice_data = null, invoice_pdf = null, payment_status = null, price = null, start_date = null), | |
| Activity(cp_id = "123", type = ActivityType.recharge_inbound, deactivation = true, date = null, description = null, end_date = null, energy = null, evc_address = null, evc_city = null, evc_id = null, invoice_data = null, invoice_pdf = null, payment_status = null, price = null, start_date = null) | |
| ), | |
| total_energy = 0f | |
| )) | |
| } | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, | |
| savedInstanceState: Bundle?): View? { | |
| return FragmentActivitiesHistoryBinding.inflate(LayoutInflater.from(context)).apply { | |
| onLoadMore = [email protected]() | |
| onCloseClick = [email protected]() | |
| footerText = [email protected] | |
| }.apply { | |
| lifecycleOwner = this@ActivitiesHistoryFragment | |
| }.root | |
| } | |
| override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | |
| super.onViewCreated(view, savedInstanceState) | |
| interactionListener!!.setTabBarVisibility(false) | |
| recyclerView.apply { | |
| layoutManager = LinearLayoutManager(this.context) | |
| setHasFixedSize(true) | |
| adapter = [email protected] | |
| } | |
| } | |
| private suspend fun initRecyclerView() { | |
| tryCatchLifecycleAware(context, { | |
| (activity as MainActivity).setVisibilityOfIndicator(false) | |
| }) { | |
| (activity as MainActivity).setVisibilityOfIndicator(true) | |
| adapter.activities = mViewModel.loadActivities() ?: return@tryCatchLifecycleAware | |
| } | |
| } | |
| private fun onActivityClick(activityRow: ActivityRow) { | |
| navigationListener!!.pushFragment( | |
| UserActivityFragment.newInstance(activityRow as Activity), | |
| true, | |
| AnimationType.DETAIL | |
| ) | |
| } | |
| private fun onLoadMore() = OnClickListener { | |
| launch { | |
| tryCatchLifecycleAware(context, { | |
| (activity as MainActivity).setVisibilityOfIndicator(false) | |
| }) { | |
| (activity as MainActivity).setVisibilityOfIndicator(true) | |
| adapter.activities += mViewModel.loadMore() ?: return@tryCatchLifecycleAware | |
| } | |
| } | |
| } | |
| class ItemWithId<T>( | |
| val id: Int, | |
| val item: T | |
| ) | |
| class ActivitiesAdapter( | |
| private val handleActivityClick: (activity: ActivityRow) -> Unit | |
| ): RecyclerView.Adapter<ActivitiesAdapter.ViewHolder>(), AutoUpdatableAdapter { | |
| var activities: List<ActivityRow> by Delegates.observable(emptyList()) { _, oldList, newList -> | |
| val oldList = oldList.foldIndexed(emptyList<ItemWithId<ActivityRow>>()) { index, acc, activityRow -> | |
| acc + ItemWithId(index, activityRow) | |
| } | |
| val newList = newList.foldIndexed(emptyList<ItemWithId<ActivityRow>>()) { index, acc, activityRow -> | |
| acc + ItemWithId(index, activityRow) | |
| } | |
| autoNotify(oldList, newList) { o, n -> | |
| o.id == n.id | |
| } | |
| } | |
| inner class ViewHolder(val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) | |
| override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
| val inflater = LayoutInflater.from(parent.context) | |
| val layout = when(viewType) { | |
| 0 -> R.layout.card_user_rateplan | |
| 1 -> R.layout.card_user_activity | |
| 2 -> R.layout.activity_header_row | |
| else -> R.layout.card_user_activity | |
| } | |
| val binding = DataBindingUtil.inflate<ViewDataBinding>( | |
| inflater!!, | |
| layout, | |
| parent, | |
| false | |
| ) | |
| return ViewHolder(binding) | |
| } | |
| /** | |
| @return | |
| 0 -> rateplan card | |
| 1 -> recharge card | |
| 2 -> header | |
| 666 -> skip activity | |
| */ | |
| override fun getItemViewType(position: Int): Int { | |
| return when (val item = activities[position]) { | |
| is Activity -> when (item.type) { | |
| ActivityType.rateplan -> 0 | |
| ActivityType.recharge -> 1 | |
| ActivityType.recharge_inbound -> 1 | |
| ActivityType.recharge_outbound -> 1 | |
| else -> 666 | |
| } | |
| is ActivityHeader -> 2 | |
| else -> 2 | |
| } | |
| } | |
| override fun getItemCount(): Int = activities.size | |
| override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
| val item = activities[position] | |
| val onClick = OnClickListener { handleActivityClick(item) } | |
| when (getItemViewType(position)) { | |
| 0 -> { | |
| with (holder.binding as CardUserRateplanBinding) { | |
| this.activity = item as Activity | |
| this.onClick = onClick | |
| } | |
| } | |
| 1 -> { | |
| with (holder.binding as CardUserActivityBinding) { | |
| activity = item as Activity | |
| this.onClick = onClick | |
| } | |
| } | |
| 2 -> { | |
| with (holder.binding as ActivityHeaderRowBinding) { | |
| this.date = (item as ActivityHeader).date | |
| this.totalEnergy = item.totalEnergy | |
| } | |
| } | |
| } | |
| } | |
| } | |
| companion object { | |
| @JvmStatic | |
| fun newInstance() = ActivitiesHistoryFragment() | |
| } | |
| } | |
| interface AutoUpdatableAdapter { | |
| fun <T> RecyclerView.Adapter<*>.autoNotify(oldList: List<T>, newList: List<T>, compare: (T, T) -> Boolean) { | |
| val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback() { | |
| override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { | |
| return compare(oldList[oldItemPosition], newList[newItemPosition]) | |
| } | |
| override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { | |
| return oldList[oldItemPosition] == newList[newItemPosition] | |
| } | |
| override fun getOldListSize() = oldList.size | |
| override fun getNewListSize() = newList.size | |
| }) | |
| diff.dispatchUpdatesTo(this) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment