Created
January 3, 2020 15:39
-
-
Save PollyGlot/576806af99492a865d9de5cefd85ce11 to your computer and use it in GitHub Desktop.
RecyclerView adapter to show several recyclerviews with different orientations and types of headers
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.kinomap.trainingapps.helper | |
import android.content.Intent | |
import android.os.Bundle | |
import android.preference.PreferenceManager | |
import android.util.Log | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.widget.ImageView | |
import android.widget.ProgressBar | |
import android.widget.TextView | |
import androidx.navigation.findNavController | |
import androidx.recyclerview.widget.LinearLayoutManager | |
import androidx.recyclerview.widget.RecyclerView | |
import com.bumptech.glide.request.RequestOptions | |
import com.kinomap.api.helper.GlideApp | |
import com.kinomap.api.helper.constants.PreferencesConstants | |
import com.kinomap.api.helper.model.VideoCoaching | |
import com.kinomap.api.helper.model.VideoObject | |
import com.kinomap.api.helper.model.VideoSection | |
import com.kinomap.api.helper.util.UnitHelper | |
import com.kinomap.kinomapcommon.util.setSafeOnClickListener | |
import com.kinomap.trainingapps.equipment.helper.Util | |
import com.kinomap.trainingapps.helper.FilterActivity.Companion.VIDEOS_FILTER | |
import kotlinx.android.synthetic.main.header_filter.view.* | |
class VideosListAdapter( | |
val hasHeader: Boolean | |
) : RecyclerView.Adapter<VideosListAdapter.ViewHolder>() { | |
val videosList: MutableList<VideoObject> = mutableListOf() | |
private lateinit var linearItemDecoration: LinearItemHorizontalOffsetDecoration | |
val recommendedVideosAdapter = VideosAdapter( | |
VideosAdapter.From.LIST_VIDEOS, | |
hasHeader = false, | |
headerType = null, | |
isRecommended = true, | |
isGrid = false | |
) | |
override fun getItemViewType(position: Int): Int { | |
return when (hasHeader) { | |
position == 0 -> HEADER_TITLE_SUBTITLE | |
position == 1 -> LIST_RECOMMENDED | |
position == 2 -> HEADER_FILTER | |
position >= 3 -> { | |
when (videosList[position - 3]) { | |
is VideoSection -> VIDEO_ITEM_DYNAMIC | |
is VideoCoaching -> VIDEO_COACHING_DYNAMIC | |
else -> 0 | |
} | |
} | |
else -> 0 | |
} | |
} | |
fun hasHeader(position: Int) = position <= 2 | |
override fun getItemCount() = videosList.size + 3 | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
var view: View? = null | |
when (viewType) { | |
HEADER_FILTER -> view = LayoutInflater.from(parent.context).inflate(R.layout.header_filter, parent, false) | |
LIST_RECOMMENDED -> view = LayoutInflater.from(parent.context).inflate(R.layout.list_recommended, parent, false) | |
VIDEO_ITEM_DYNAMIC -> view = LayoutInflater.from(parent.context).inflate(R.layout.item_video_dynamic, parent, false) | |
HEADER_TITLE_SUBTITLE -> view = LayoutInflater.from(parent.context).inflate(R.layout.header_title_subtitle, parent, false) | |
VIDEO_COACHING_DYNAMIC -> view = LayoutInflater.from(parent.context).inflate(R.layout.item_video_coaching, parent, false) | |
} | |
val holder = ViewHolder(view!!) | |
when (viewType) { | |
LIST_RECOMMENDED -> { | |
linearItemDecoration = when (holder.itemView.context.resources.getBoolean(R.bool.isTablet)) { | |
true -> LinearItemHorizontalOffsetDecoration(holder.itemView.context, R.dimen.item_offset_24) | |
false -> LinearItemHorizontalOffsetDecoration(holder.itemView.context, R.dimen.item_offset_16) | |
} | |
holder.listRecommendedRecyclerView.addItemDecoration(linearItemDecoration) | |
} | |
HEADER_FILTER -> { | |
view.headerFilterBtn.setSafeOnClickListener { | |
val intent = Intent(view.context, FilterActivity::class.java) | |
intent.putExtra(FilterActivity.ARGS_TYPE_FILTER, VIDEOS_FILTER) | |
(view.context as BottomNavigationActivity).startActivityForResult(intent, FilterActivity.REQUEST_CODE) | |
} | |
} | |
} | |
return ViewHolder(view) | |
} | |
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
val image = itemView.findViewById<ImageView>(R.id.videoImage) | |
val authorImage = itemView.findViewById<ImageView>(R.id.videoAuthorAvatar) | |
val authorUsername = itemView.findViewById<TextView>(R.id.videoAuthorUsername) | |
val title = itemView.findViewById<TextView>(R.id.videoTitle) | |
val sport = itemView.findViewById<ImageView>(R.id.videoSportIcon) | |
val country = itemView.findViewById<ImageView>(R.id.videoStartCountry) | |
val languageCoaching = itemView.findViewById<TextView>(R.id.videoCoachingLanguage) | |
val distance = itemView.findViewById<TextView>(R.id.distance) | |
val distanceUnit = itemView.findViewById<TextView>(R.id.distanceUnit) | |
val duration = itemView.findViewById<TextView>(R.id.duration) | |
val durationCoaching = itemView.findViewById<TextView>(R.id.videoCoachingStatisticsDuration) | |
val durationUnit = itemView.findViewById<TextView>(R.id.durationUnit) | |
var durationCoachingUnit = itemView.findViewById<TextView>(R.id.videoCoachingStatisticsDurationUnit) | |
val elevation = itemView.findViewById<TextView>(R.id.elevationAscent) | |
val elevationUnit = itemView.findViewById<TextView>(R.id.elevationUnit) | |
val averageInfo = itemView.findViewById<TextView>(R.id.averageInfoData) | |
val averageInfoUnit = itemView.findViewById<TextView>(R.id.averageInfoUnit) | |
val averageInfoIcon = itemView.findViewById<ImageView>(R.id.averageInfoIcon) | |
val difficulty = itemView.findViewById<ImageView>(R.id.difficulty) | |
val quality = itemView.findViewById<ImageView>(R.id.quality) | |
val progress: ProgressBar? = itemView.findViewById(R.id.videoProgressBar) | |
/* Headers */ | |
val headerTitleSubtitleTitle = itemView.findViewById<TextView>(R.id.headerTitleSubtitleTitle) | |
val headerTitleSubtitleSubtitle = itemView.findViewById<TextView>(R.id.headerTitleSubtitleSubtitle) | |
var headerFilterTitle = itemView.findViewById<TextView>(R.id.headerFilterTitle) | |
var headerFilterButton = itemView.findViewById<TextView>(R.id.headerFilterBtn) | |
val listRecommendedRecyclerView = itemView.findViewById<RecyclerView>(R.id.listRecommendedRecyclerView) | |
} | |
override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
when (holder.itemViewType) { | |
HEADER_TITLE_SUBTITLE -> { | |
holder.headerTitleSubtitleTitle.text = holder.itemView.resources.getString(R.string.menu_recommended_for_you) | |
holder.headerTitleSubtitleSubtitle.text = holder.itemView.resources.getString(R.string.train_recommended_videos_description) | |
} | |
LIST_RECOMMENDED -> { | |
val recommendedVideosLayoutManager = LinearLayoutManager(holder.itemView.context, LinearLayoutManager.HORIZONTAL, false) | |
holder.listRecommendedRecyclerView.layoutManager = recommendedVideosLayoutManager | |
holder.listRecommendedRecyclerView.adapter = recommendedVideosAdapter | |
} | |
HEADER_FILTER -> { | |
val preferences = PreferenceManager.getDefaultSharedPreferences(holder.itemView.context) | |
holder.headerFilterTitle.text = holder.itemView.resources.getString(R.string.videosList_all_videos_title) | |
holder.headerFilterButton.setBackgroundResource( | |
when (preferences.getBoolean(PreferencesConstants.FILTER_VIDEOS_BUTTON_FILTERED, false)) { | |
true -> R.drawable.btn_circle_filtered_yellow | |
false -> R.drawable.btn_circle_filter_default | |
} | |
) | |
} | |
VIDEO_ITEM_DYNAMIC -> { | |
val videoSectionList = videosList[position - 3] as VideoSection | |
// Image | |
GlideApp.with(holder.image.context) | |
.load(videoSectionList.thumbnailLarge) | |
.apply(RequestOptions().placeholder(R.drawable.ic_placeholder_flux)) | |
.into(holder.image) | |
// Profile image | |
GlideApp.with(holder.authorImage.context) | |
.load(videoSectionList.user.avatarUrl) | |
.apply(RequestOptions().circleCrop()) | |
.apply(RequestOptions().placeholder(R.drawable.ic_profile_placeholder)) | |
.into(holder.authorImage) | |
// Author name | |
when (videoSectionList.user.username.isNotEmpty()) { | |
true -> holder.authorUsername.text = videoSectionList.user.username | |
false -> holder.authorUsername.text = holder.itemView.context.getString(R.string.dash_long) | |
} | |
// Video title | |
when (videoSectionList.name.isNotEmpty()) { | |
true -> holder.title.text = videoSectionList.name | |
false -> holder.title.text = holder.itemView.context.getString(R.string.dash) | |
} | |
// Sport type | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getIconSportType(videoSectionList.sport)) | |
.into(holder.sport) | |
// Country star | |
try { | |
val appPackage = holder.itemView.context.applicationContext.packageName | |
val resources = holder.itemView.resources | |
val flagCode = resources.getIdentifier(videoSectionList.countryStart.code, "drawable", appPackage) | |
Log.d("COUNTRY_CODE", videoSectionList.countryStart.code) | |
GlideApp.with(holder.country.context) | |
.load(flagCode) | |
.into(holder.country) | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
// Distance | |
val distance = UnitHelper.getInstance().getDistanceString(videoSectionList.distance, true) | |
val distanceUnit = UnitHelper.getInstance().getDistanceUnit(videoSectionList.distance) | |
holder.distance.text = distance.toString() | |
holder.distanceUnit.text = distanceUnit | |
// Duration | |
holder.duration.text = UnitHelper.getInstance().getDurationString(videoSectionList.duration) | |
holder.durationUnit.text = UnitHelper.getInstance().getDurationUnit(videoSectionList.duration) | |
// Elevation | |
val elevation = UnitHelper.getInstance().getElevationString(videoSectionList.elevationAscent.toInt()) | |
val elevationUnit = UnitHelper.getInstance().elevationUnit | |
holder.elevation.text = elevation | |
holder.elevationUnit.text = elevationUnit | |
// Average Info | |
when (videoSectionList.sport) { | |
FeedAdapter.ActivityType.CYCLING.activityType -> { | |
if (UnitHelper.unitModeCycling == UnitHelper.UNIT_MODE_CYCLING.REGULAR_MODE) { | |
holder.averageInfo.text = UnitHelper.getInstance().getSpeedString(videoSectionList.avgSpeed.toFloat(), true) | |
holder.averageInfoUnit.text = UnitHelper.getInstance().getUnit(UnitHelper.UNIT_STRING.SPEED) | |
holder.averageInfoIcon.setImageResource(R.drawable.ic_speed_avg) | |
} else { | |
holder.averageInfo.text = videoSectionList.avgPower.toString() | |
holder.averageInfoUnit.text = holder.itemView.resources.getString(R.string.misc_watts) | |
holder.averageInfoIcon.setImageResource(R.drawable.ic_watts) | |
} | |
} | |
FeedAdapter.ActivityType.RUNNING.activityType -> { | |
if (UnitHelper.unitModeRunning == UnitHelper.UNIT_MODE_RUNNING.REGULAR_MODE) { | |
holder.averageInfo.text = UnitHelper.getInstance().getSpeedString(videoSectionList.avgSpeed.toFloat(), true) | |
holder.averageInfoUnit.text = UnitHelper.getInstance().getUnit(UnitHelper.UNIT_STRING.SPEED) | |
holder.averageInfoIcon.setImageResource(R.drawable.ic_speed_avg) | |
} else { | |
holder.averageInfo.text = UnitHelper.getRunningAverageSpeedString(videoSectionList.avgSpeed.toFloat()) | |
holder.averageInfoUnit.text = "/${UnitHelper.getInstance().getUnit(UnitHelper.UNIT_STRING.DISTANCE_K)}" | |
holder.averageInfoIcon.setImageResource(R.drawable.ic_speed_avg) | |
} | |
} | |
FeedAdapter.ActivityType.ROWING.activityType -> { | |
holder.averageInfo.text = UnitHelper.getRowingAverageSpeedString(videoSectionList.avgSpeed.toFloat()) | |
holder.averageInfoUnit.text = UnitHelper.getInstance().getUnit(UnitHelper.UNIT_STRING.SPEED_ROWING) | |
holder.averageInfoIcon.setImageResource(R.drawable.ic_speed_avg) | |
} | |
} | |
// Difficulty | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getDifficultBanner(videoSectionList.difficultyLevel)) | |
.into(holder.difficulty) | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getQualityIcon(videoSectionList.quality)) | |
.into(holder.quality!!) | |
if (videoSectionList.completionPercent > 0) { | |
holder.progress?.progress = videoSectionList.completionPercent | |
holder.progress?.visibility = View.VISIBLE | |
} | |
// Click listener | |
holder.itemView.setOnClickListener { | |
val data = Bundle() | |
data.putInt(Constants.VIDEO_ID_KEY, videosList[holder.adapterPosition - 3].id) | |
data.putString(Constants.VIDEO_TYPE_KEY, Constants.VIDEO_TYPE_SECTION) | |
holder.itemView.findNavController().navigate(R.id.action_list_video_playlist_fragment_to_video_details_fragment, data) | |
} | |
} | |
VIDEO_COACHING_DYNAMIC -> { | |
val videoCoachingList = videosList[position - 3] as VideoCoaching | |
// Image | |
GlideApp.with(holder.image.context) | |
.load(videoCoachingList.thumbnailLarge) | |
.apply(RequestOptions().placeholder(R.drawable.ic_placeholder_flux)) | |
.into(holder.image) | |
// Profile image | |
GlideApp.with(holder.authorImage.context) | |
.load(videoCoachingList.user.avatarUrl) | |
.apply(RequestOptions().circleCrop()) | |
.apply(RequestOptions().placeholder(R.drawable.ic_profile_placeholder)) | |
.into(holder.authorImage) | |
// Author name | |
when (videoCoachingList.user.username.isNotEmpty()) { | |
true -> holder.authorUsername.text = videoCoachingList.user.username | |
false -> holder.authorUsername.text = holder.itemView.context.getString(R.string.dash_long) | |
} | |
// Video title | |
when (videoCoachingList.name.isNotEmpty()) { | |
true -> holder.title.text = videoCoachingList.name | |
false -> holder.title.text = holder.itemView.context.getString(R.string.dash) | |
} | |
// Sport type | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getBlackIconEquipmentType(videoCoachingList.equipmentType)) | |
.into(holder.sport) | |
// Duration | |
holder.durationCoaching.text = UnitHelper.getInstance().getDurationString(videoCoachingList.duration) | |
holder.durationCoachingUnit.text = UnitHelper.getInstance().getDurationUnit(videoCoachingList.duration) | |
// Difficulty | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getDifficultBanner(videoCoachingList.difficultyLevel)) | |
.into(holder.difficulty) | |
GlideApp.with(holder.itemView.context) | |
.load(Util.getQualityIcon(videoCoachingList.quality)) | |
.into(holder.quality) | |
// Language | |
holder.languageCoaching.text = videoCoachingList.langNativeName | |
if (videoCoachingList.completionPercent > 0) { | |
holder.progress?.progress = videoCoachingList.completionPercent | |
holder.progress?.visibility = View.VISIBLE | |
} | |
// Click listener | |
holder.itemView.setOnClickListener { | |
val data = Bundle() | |
data.putInt(Constants.VIDEO_ID_KEY, videosList[holder.adapterPosition - 3].id) | |
data.putString(Constants.VIDEO_TYPE_KEY, Constants.VIDEO_TYPE_COACHING) | |
holder.itemView.findNavController().navigate(R.id.action_list_video_playlist_fragment_to_video_details_fragment, data) | |
} | |
} | |
} | |
} | |
companion object { | |
const val LIST_RECOMMENDED = 0 | |
const val LIST_ALL_VIDEOS = 1 | |
const val HEADER_TITLE = 2 | |
const val HEADER_TITLE_SUBTITLE = 3 | |
const val HEADER_FILTER = 4 | |
const val VIDEO_ITEM = 5 | |
const val VIDEO_ITEM_DYNAMIC = 6 | |
const val VIDEO_COACHING = 6 | |
const val VIDEO_COACHING_DYNAMIC = 7 | |
const val PLACEHOLDER = 8 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment