alternative global layout

This commit is contained in:
Bnyro 2022-10-29 17:33:12 +02:00
parent 2efa4de778
commit d756a1fb0c
15 changed files with 231 additions and 250 deletions

View File

@ -33,7 +33,7 @@ object PreferenceKeys {
const val APP_ICON = "icon_change" const val APP_ICON = "icon_change"
const val LEGACY_SUBSCRIPTIONS = "legacy_subscriptions" const val LEGACY_SUBSCRIPTIONS = "legacy_subscriptions"
const val LEGACY_SUBSCRIPTIONS_COLUMNS = "legacy_subscriptions_columns" const val LEGACY_SUBSCRIPTIONS_COLUMNS = "legacy_subscriptions_columns"
const val ALTERNATIVE_TRENDING_LAYOUT = "trending_layout" const val ALTERNATIVE_VIDEOS_LAYOUT = "alternative_videos_layout"
const val NEW_VIDEOS_BADGE = "new_videos_badge" const val NEW_VIDEOS_BADGE = "new_videos_badge"
const val PLAYLISTS_ORDER = "playlists_order" const val PLAYLISTS_ORDER = "playlists_order"

View File

@ -1,92 +0,0 @@
package com.github.libretube.ui.adapters
import android.annotation.SuppressLint
import android.text.format.DateUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.databinding.VideoRowBinding
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.setWatchProgressLength
import com.github.libretube.extensions.toID
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
import com.github.libretube.ui.viewholders.ChannelViewHolder
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper
class ChannelAdapter(
private val videoFeed: MutableList<StreamItem>,
private val childFragmentManager: FragmentManager,
private val showChannelInfo: Boolean = false
) :
RecyclerView.Adapter<ChannelViewHolder>() {
override fun getItemCount(): Int {
return videoFeed.size
}
fun updateItems(newItems: List<StreamItem>) {
val feedSize = videoFeed.size
videoFeed.addAll(newItems)
notifyItemRangeInserted(feedSize, newItems.size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = VideoRowBinding.inflate(layoutInflater, parent, false)
return ChannelViewHolder(binding)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ChannelViewHolder, position: Int) {
val video = videoFeed[position]
// hide the item if there was an extractor error
if (video.title == null) {
holder.itemView.visibility = View.GONE
holder.itemView.layoutParams = RecyclerView.LayoutParams(0, 0)
return
}
holder.binding.apply {
videoTitle.text = video.title
videoInfo.text =
video.views.formatShort() + " " +
root.context.getString(R.string.views_placeholder) +
"" + video.uploaded?.let { DateUtils.getRelativeTimeSpanString(it) }
thumbnailDuration.text =
video.duration?.let { DateUtils.formatElapsedTime(it) }
ImageHelper.loadImage(video.thumbnail, thumbnail)
if (showChannelInfo) {
ImageHelper.loadImage(video.uploaderAvatar, channelImage)
channelName.text = video.uploaderName
}
root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, video.url)
}
val videoId = video.url?.toID()
val videoName = video.title
root.setOnLongClickListener {
if (videoId == null || videoName == null) return@setOnLongClickListener true
VideoOptionsBottomSheet(videoId, videoName)
.show(childFragmentManager, VideoOptionsBottomSheet::class.java.name)
true
}
if (videoId != null) {
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
}
}
}
}

View File

@ -1,93 +0,0 @@
package com.github.libretube.ui.adapters
import android.annotation.SuppressLint
import android.text.format.DateUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.setFormattedDuration
import com.github.libretube.extensions.setWatchProgressLength
import com.github.libretube.extensions.toID
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
import com.github.libretube.ui.viewholders.SubscriptionViewHolder
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper
class TrendingAdapter(
private val streamItems: List<com.github.libretube.api.obj.StreamItem>,
private val childFragmentManager: FragmentManager,
private val showAllAtOne: Boolean = true
) : RecyclerView.Adapter<SubscriptionViewHolder>() {
var index = 10
override fun getItemCount(): Int {
return if (showAllAtOne) {
streamItems.size
} else if (index >= streamItems.size) {
streamItems.size - 1
} else {
index
}
}
fun updateItems() {
val oldSize = index
index += 10
notifyItemRangeInserted(oldSize, index)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = TrendingRowBinding.inflate(layoutInflater, parent, false)
return SubscriptionViewHolder(binding)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) {
val video = streamItems[position]
// hide the item if there was an extractor error
if (video.title == null) {
holder.itemView.visibility = View.GONE
holder.itemView.layoutParams = RecyclerView.LayoutParams(0, 0)
return
}
holder.binding.apply {
textViewTitle.text = video.title
textViewChannel.text =
video.uploaderName + "" +
video.views.formatShort() + " " +
root.context.getString(R.string.views_placeholder) +
"" + video.uploaded?.let { DateUtils.getRelativeTimeSpanString(it) }
video.duration?.let { thumbnailDuration.setFormattedDuration(it) }
channelImage.setOnClickListener {
NavigationHelper.navigateChannel(root.context, video.uploaderUrl)
}
ImageHelper.loadImage(video.thumbnail, thumbnail)
ImageHelper.loadImage(video.uploaderAvatar, channelImage)
root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, video.url)
}
val videoId = video.url?.toID()
val videoName = video.title
root.setOnLongClickListener {
if (videoId == null || videoName == null) return@setOnLongClickListener true
VideoOptionsBottomSheet(videoId, videoName)
.show(childFragmentManager, VideoOptionsBottomSheet::class.java.name)
true
}
if (videoId != null) {
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
}
}
}
}

View File

@ -0,0 +1,155 @@
package com.github.libretube.ui.adapters
import android.annotation.SuppressLint
import android.text.format.DateUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.databinding.VideoRowBinding
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.setFormattedDuration
import com.github.libretube.extensions.setWatchProgressLength
import com.github.libretube.extensions.toID
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
import com.github.libretube.ui.viewholders.VideosViewHolder
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.PreferenceHelper
class VideosAdapter(
private val streamItems: MutableList<StreamItem>,
private val childFragmentManager: FragmentManager,
private val showAllAtOnce: Boolean = true,
private val forceType: Int = FORCE_NONE
) : RecyclerView.Adapter<VideosViewHolder>() {
var index = 10
override fun getItemCount(): Int {
return when {
showAllAtOnce -> streamItems.size
index >= streamItems.size -> streamItems.size - 1
else -> index
}
}
fun updateItems() {
val oldSize = index
index += 10
notifyItemRangeInserted(oldSize, index)
}
fun insertItems(newItems: List<StreamItem>) {
val feedSize = streamItems.size
streamItems.addAll(newItems)
notifyItemRangeInserted(feedSize, newItems.size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideosViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return when {
forceType == FORCE_TRENDING -> VideosViewHolder(TrendingRowBinding.inflate(layoutInflater, parent, false))
forceType == FORCE_CHANNEL -> VideosViewHolder(VideoRowBinding.inflate(layoutInflater, parent, false))
PreferenceHelper.getBoolean(
PreferenceKeys.ALTERNATIVE_VIDEOS_LAYOUT,
false
) -> VideosViewHolder(VideoRowBinding.inflate(layoutInflater, parent, false))
else -> VideosViewHolder(TrendingRowBinding.inflate(layoutInflater, parent, false))
}
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: VideosViewHolder, position: Int) {
val video = streamItems[position]
// hide the item if there was an extractor error
if (video.title == null) {
holder.itemView.visibility = View.GONE
holder.itemView.layoutParams = RecyclerView.LayoutParams(0, 0)
return
}
// Trending layout
holder.trendingRowBinding?.apply {
textViewTitle.text = video.title
textViewChannel.text =
video.uploaderName + "" +
video.views.formatShort() + " " +
root.context.getString(R.string.views_placeholder) +
"" + video.uploaded?.let { DateUtils.getRelativeTimeSpanString(it) }
video.duration?.let { thumbnailDuration.setFormattedDuration(it) }
channelImage.setOnClickListener {
NavigationHelper.navigateChannel(root.context, video.uploaderUrl)
}
ImageHelper.loadImage(video.thumbnail, thumbnail)
ImageHelper.loadImage(video.uploaderAvatar, channelImage)
root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, video.url)
}
val videoId = video.url?.toID()
val videoName = video.title
root.setOnLongClickListener {
if (videoId == null || videoName == null) return@setOnLongClickListener true
VideoOptionsBottomSheet(videoId, videoName)
.show(childFragmentManager, VideoOptionsBottomSheet::class.java.name)
true
}
if (videoId != null) {
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
}
}
// Normal videos row layout
holder.videoRowBinding?.apply {
videoTitle.text = video.title
videoInfo.text =
video.views.formatShort() + " " +
root.context.getString(R.string.views_placeholder) +
"" + video.uploaded?.let { DateUtils.getRelativeTimeSpanString(it) }
thumbnailDuration.text =
video.duration?.let { DateUtils.formatElapsedTime(it) }
ImageHelper.loadImage(video.thumbnail, thumbnail)
if (forceType != FORCE_CHANNEL) {
ImageHelper.loadImage(video.uploaderAvatar, channelImage)
channelName.text = video.uploaderName
}
root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, video.url)
}
val videoId = video.url?.toID()
val videoName = video.title
root.setOnLongClickListener {
if (videoId == null || videoName == null) return@setOnLongClickListener true
VideoOptionsBottomSheet(videoId, videoName)
.show(childFragmentManager, VideoOptionsBottomSheet::class.java.name)
true
}
if (videoId != null) {
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
}
}
}
companion object {
const val FORCE_NONE = 0
const val FORCE_TRENDING = 1
const val FORCE_NORMAL = 2
const val FORCE_CHANNEL = 3
}
}

View File

@ -20,8 +20,8 @@ import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.formatShort import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.obj.ShareData import com.github.libretube.obj.ShareData
import com.github.libretube.ui.adapters.ChannelAdapter
import com.github.libretube.ui.adapters.SearchAdapter import com.github.libretube.ui.adapters.SearchAdapter
import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.base.BaseFragment import com.github.libretube.ui.base.BaseFragment
import com.github.libretube.ui.dialogs.ShareDialog import com.github.libretube.ui.dialogs.ShareDialog
import com.github.libretube.util.ImageHelper import com.github.libretube.util.ImageHelper
@ -38,7 +38,7 @@ class ChannelFragment : BaseFragment() {
private var channelId: String? = null private var channelId: String? = null
private var channelName: String? = null private var channelName: String? = null
private var nextPage: String? = null private var nextPage: String? = null
private var channelAdapter: ChannelAdapter? = null private var channelAdapter: VideosAdapter? = null
private var isLoading = true private var isLoading = true
private var isSubscribed: Boolean? = false private var isSubscribed: Boolean? = false
@ -184,9 +184,10 @@ class ChannelFragment : BaseFragment() {
ImageHelper.loadImage(response.avatarUrl, binding.channelImage) ImageHelper.loadImage(response.avatarUrl, binding.channelImage)
// recyclerview of the videos by the channel // recyclerview of the videos by the channel
channelAdapter = ChannelAdapter( channelAdapter = VideosAdapter(
response.relatedStreams.orEmpty().toMutableList(), response.relatedStreams.orEmpty().toMutableList(),
childFragmentManager childFragmentManager,
forceType = VideosAdapter.FORCE_CHANNEL
) )
binding.channelRecView.adapter = channelAdapter binding.channelRecView.adapter = channelAdapter
} }
@ -272,7 +273,7 @@ class ChannelFragment : BaseFragment() {
return@launchWhenCreated return@launchWhenCreated
} }
nextPage = response.nextpage nextPage = response.nextpage
channelAdapter?.updateItems(response.relatedStreams!!) channelAdapter?.insertItems(response.relatedStreams.orEmpty())
isLoading = false isLoading = false
binding.channelRefresh.isRefreshing = false binding.channelRefresh.isRefreshing = false
} }

View File

@ -8,17 +8,15 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.FragmentHomeBinding import com.github.libretube.databinding.FragmentHomeBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.ui.activities.SettingsActivity import com.github.libretube.ui.activities.SettingsActivity
import com.github.libretube.ui.adapters.ChannelAdapter import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.adapters.TrendingAdapter
import com.github.libretube.ui.base.BaseFragment import com.github.libretube.ui.base.BaseFragment
import com.github.libretube.util.LayoutHelper
import com.github.libretube.util.LocaleHelper import com.github.libretube.util.LocaleHelper
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@ -104,30 +102,12 @@ class HomeFragment : BaseFragment() {
return@runOnUiThread return@runOnUiThread
} }
if ( binding.recview.adapter = VideosAdapter(
PreferenceHelper.getBoolean( response.toMutableList(),
PreferenceKeys.ALTERNATIVE_TRENDING_LAYOUT, childFragmentManager
false )
)
) {
binding.recview.layoutManager = LinearLayoutManager(context)
binding.recview.adapter = ChannelAdapter( binding.recview.layoutManager = LayoutHelper.getVideoLayout(requireContext())
response.toMutableList(),
childFragmentManager,
true
)
} else {
binding.recview.layoutManager = GridLayoutManager(
context,
PreferenceHelper.getString(
PreferenceKeys.GRID_COLUMNS,
resources.getInteger(R.integer.grid_items).toString()
).toInt()
)
binding.recview.adapter = TrendingAdapter(response, childFragmentManager)
}
} }
} }
} }

View File

@ -63,7 +63,7 @@ import com.github.libretube.services.DownloadService
import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.activities.MainActivity
import com.github.libretube.ui.adapters.ChaptersAdapter import com.github.libretube.ui.adapters.ChaptersAdapter
import com.github.libretube.ui.adapters.CommentsAdapter import com.github.libretube.ui.adapters.CommentsAdapter
import com.github.libretube.ui.adapters.TrendingAdapter import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.base.BaseFragment import com.github.libretube.ui.base.BaseFragment
import com.github.libretube.ui.dialogs.AddToPlaylistDialog import com.github.libretube.ui.dialogs.AddToPlaylistDialog
import com.github.libretube.ui.dialogs.DownloadDialog import com.github.libretube.ui.dialogs.DownloadDialog
@ -903,9 +903,10 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
} }
if (PlayerHelper.relatedStreamsEnabled) { if (PlayerHelper.relatedStreamsEnabled) {
// only show related streams if enabled // only show related streams if enabled
binding.relatedRecView.adapter = TrendingAdapter( binding.relatedRecView.adapter = VideosAdapter(
response.relatedStreams!!, response.relatedStreams.orEmpty().toMutableList(),
childFragmentManager childFragmentManager,
forceType = VideosAdapter.FORCE_TRENDING
) )
} }
// set video description // set video description

View File

@ -15,16 +15,17 @@ import com.github.libretube.databinding.FragmentSubscriptionsBinding
import com.github.libretube.models.SubscriptionsViewModel import com.github.libretube.models.SubscriptionsViewModel
import com.github.libretube.ui.adapters.LegacySubscriptionAdapter import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
import com.github.libretube.ui.adapters.SubscriptionChannelAdapter import com.github.libretube.ui.adapters.SubscriptionChannelAdapter
import com.github.libretube.ui.adapters.TrendingAdapter import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.base.BaseFragment import com.github.libretube.ui.base.BaseFragment
import com.github.libretube.ui.views.BottomSheet import com.github.libretube.ui.views.BottomSheet
import com.github.libretube.util.LayoutHelper
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
class SubscriptionsFragment : BaseFragment() { class SubscriptionsFragment : BaseFragment() {
private lateinit var binding: FragmentSubscriptionsBinding private lateinit var binding: FragmentSubscriptionsBinding
private val viewModel: SubscriptionsViewModel by activityViewModels() private val viewModel: SubscriptionsViewModel by activityViewModels()
private var subscriptionAdapter: TrendingAdapter? = null private var subscriptionAdapter: VideosAdapter? = null
private var sortOrder = 0 private var sortOrder = 0
override fun onCreateView( override fun onCreateView(
@ -48,12 +49,7 @@ class SubscriptionsFragment : BaseFragment() {
binding.subProgress.visibility = View.VISIBLE binding.subProgress.visibility = View.VISIBLE
val grid = PreferenceHelper.getString( binding.subFeed.layoutManager = LayoutHelper.getVideoLayout(requireContext())
PreferenceKeys.GRID_COLUMNS,
resources.getInteger(R.integer.grid_items).toString()
)
binding.subFeed.layoutManager = GridLayoutManager(view.context, grid.toInt())
if (viewModel.videoFeed.value == null || !loadFeedInBackground) { if (viewModel.videoFeed.value == null || !loadFeedInBackground) {
viewModel.videoFeed.value = null viewModel.videoFeed.value = null
@ -158,7 +154,11 @@ class SubscriptionsFragment : BaseFragment() {
if (viewModel.videoFeed.value!!.isEmpty()) View.VISIBLE else View.GONE if (viewModel.videoFeed.value!!.isEmpty()) View.VISIBLE else View.GONE
binding.subProgress.visibility = View.GONE binding.subProgress.visibility = View.GONE
subscriptionAdapter = TrendingAdapter(sortedFeed, childFragmentManager, false) subscriptionAdapter = VideosAdapter(
sortedFeed.toMutableList(),
childFragmentManager,
showAllAtOnce = false
)
binding.subFeed.adapter = subscriptionAdapter binding.subFeed.adapter = subscriptionAdapter
} }

View File

@ -1,8 +0,0 @@
package com.github.libretube.ui.viewholders
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.VideoRowBinding
class ChannelViewHolder(
val binding: VideoRowBinding
) : RecyclerView.ViewHolder(binding.root)

View File

@ -1,8 +0,0 @@
package com.github.libretube.ui.viewholders
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.TrendingRowBinding
class SubscriptionViewHolder(
val binding: TrendingRowBinding
) : RecyclerView.ViewHolder(binding.root)

View File

@ -0,0 +1,18 @@
package com.github.libretube.ui.viewholders
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.databinding.VideoRowBinding
class VideosViewHolder : RecyclerView.ViewHolder {
var trendingRowBinding: TrendingRowBinding? = null
var videoRowBinding: VideoRowBinding? = null
constructor(binding: TrendingRowBinding) : super(binding.root) {
trendingRowBinding = binding
}
constructor(binding: VideoRowBinding) : super(binding.root) {
videoRowBinding = binding
}
}

View File

@ -0,0 +1,26 @@
package com.github.libretube.util
import android.content.Context
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.constants.PreferenceKeys
object LayoutHelper {
fun getVideoLayout(context: Context) = if (
PreferenceHelper.getBoolean(
PreferenceKeys.ALTERNATIVE_VIDEOS_LAYOUT,
false
)
) {
LinearLayoutManager(context)
} else {
GridLayoutManager(
context,
PreferenceHelper.getString(
PreferenceKeys.GRID_COLUMNS,
context.resources.getInteger(R.integer.grid_items).toString()
).toInt()
)
}
}

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"> android:background="@drawable/rounded_ripple">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/thumbnailcard" android:id="@+id/thumbnailcard"

View File

@ -353,6 +353,7 @@
<string name="sb_markers">Markers</string> <string name="sb_markers">Markers</string>
<string name="sb_markers_summary">Mark the segments on the time bar.</string> <string name="sb_markers_summary">Mark the segments on the time bar.</string>
<string name="livestreams">Livestreams</string> <string name="livestreams">Livestreams</string>
<string name="alternative_videos_layout">Alternative videos layout</string>
<!-- Notification channel strings --> <!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string> <string name="download_channel_name">Download Service</string>

View File

@ -103,8 +103,8 @@
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:icon="@drawable/ic_trending" android:icon="@drawable/ic_trending"
app:defaultValue="false" app:defaultValue="false"
app:key="trending_layout" app:key="alternative_videos_layout"
app:title="@string/trending_layout" /> app:title="@string/alternative_videos_layout" />
<ListPreference <ListPreference
android:defaultValue="recent" android:defaultValue="recent"