Fix grid span count calculation; remove duplicate methods
This commit is contained in:
parent
b795c5f017
commit
a7dd3af4e5
|
@ -1,7 +1,6 @@
|
||||||
package org.schabi.newpipe.local;
|
package org.schabi.newpipe.local;
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -26,6 +25,7 @@ import org.schabi.newpipe.fragments.list.ListViewContract;
|
||||||
|
|
||||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||||
|
import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This fragment is design to be used with persistent data such as
|
* This fragment is design to be used with persistent data such as
|
||||||
|
@ -77,7 +77,7 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (updateFlags != 0) {
|
if (updateFlags != 0) {
|
||||||
if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) {
|
if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) {
|
||||||
final boolean useGrid = isGridLayout();
|
final boolean useGrid = shouldUseGridLayout(requireContext());
|
||||||
itemsList.setLayoutManager(
|
itemsList.setLayoutManager(
|
||||||
useGrid ? getGridLayoutManager() : getListLayoutManager());
|
useGrid ? getGridLayoutManager() : getListLayoutManager());
|
||||||
itemListAdapter.setUseGridVariant(useGrid);
|
itemListAdapter.setUseGridVariant(useGrid);
|
||||||
|
@ -121,7 +121,7 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||||
|
|
||||||
itemListAdapter = new LocalItemListAdapter(activity);
|
itemListAdapter = new LocalItemListAdapter(activity);
|
||||||
|
|
||||||
final boolean useGrid = isGridLayout();
|
final boolean useGrid = shouldUseGridLayout(requireContext());
|
||||||
itemsList = rootView.findViewById(R.id.items_list);
|
itemsList = rootView.findViewById(R.id.items_list);
|
||||||
itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager());
|
itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager());
|
||||||
|
|
||||||
|
@ -260,17 +260,4 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||||
updateFlags |= LIST_MODE_UPDATE_FLAG;
|
updateFlags |= LIST_MODE_UPDATE_FLAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isGridLayout() {
|
|
||||||
final String listMode = PreferenceManager.getDefaultSharedPreferences(activity)
|
|
||||||
.getString(getString(R.string.list_view_mode_key),
|
|
||||||
getString(R.string.list_view_mode_value));
|
|
||||||
if ("auto".equals(listMode)) {
|
|
||||||
final Configuration configuration = getResources().getConfiguration();
|
|
||||||
return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
|
||||||
&& configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
|
|
||||||
} else {
|
|
||||||
return "grid".equals(listMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -74,10 +73,10 @@ import org.schabi.newpipe.player.helper.PlayerHolder
|
||||||
import org.schabi.newpipe.util.Localization
|
import org.schabi.newpipe.util.Localization
|
||||||
import org.schabi.newpipe.util.NavigationHelper
|
import org.schabi.newpipe.util.NavigationHelper
|
||||||
import org.schabi.newpipe.util.StreamDialogEntry
|
import org.schabi.newpipe.util.StreamDialogEntry
|
||||||
|
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCount
|
||||||
|
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import kotlin.math.floor
|
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
class FeedFragment : BaseStateFragment<FeedState>() {
|
class FeedFragment : BaseStateFragment<FeedState>() {
|
||||||
private var _feedBinding: FragmentFeedBinding? = null
|
private var _feedBinding: FragmentFeedBinding? = null
|
||||||
|
@ -161,7 +160,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||||
|
|
||||||
fun setupListViewMode() {
|
fun setupListViewMode() {
|
||||||
// does everything needed to setup the layouts for grid or list modes
|
// does everything needed to setup the layouts for grid or list modes
|
||||||
groupAdapter.spanCount = if (shouldUseGridLayout()) getGridSpanCount() else 1
|
groupAdapter.spanCount = if (shouldUseGridLayout(context)) getGridSpanCount(context) else 1
|
||||||
feedBinding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
|
feedBinding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
|
||||||
spanSizeLookup = groupAdapter.spanSizeLookup
|
spanSizeLookup = groupAdapter.spanSizeLookup
|
||||||
}
|
}
|
||||||
|
@ -384,7 +383,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||||
@SuppressLint("StringFormatMatches")
|
@SuppressLint("StringFormatMatches")
|
||||||
private fun handleLoadedState(loadedState: FeedState.LoadedState) {
|
private fun handleLoadedState(loadedState: FeedState.LoadedState) {
|
||||||
|
|
||||||
val itemVersion = if (shouldUseGridLayout()) {
|
val itemVersion = if (shouldUseGridLayout(context)) {
|
||||||
StreamItem.ItemVersion.GRID
|
StreamItem.ItemVersion.GRID
|
||||||
} else {
|
} else {
|
||||||
StreamItem.ItemVersion.NORMAL
|
StreamItem.ItemVersion.NORMAL
|
||||||
|
@ -528,35 +527,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||||
listState = null
|
listState = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
|
||||||
// Grid Mode
|
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// TODO: Move these out of this class, as it can be reused
|
|
||||||
|
|
||||||
private fun shouldUseGridLayout(): Boolean {
|
|
||||||
val listMode = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
|
||||||
.getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value))
|
|
||||||
|
|
||||||
return when (listMode) {
|
|
||||||
getString(R.string.list_view_mode_auto_key) -> {
|
|
||||||
val configuration = resources.configuration
|
|
||||||
|
|
||||||
(
|
|
||||||
configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&
|
|
||||||
configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
getString(R.string.list_view_mode_grid_key) -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGridSpanCount(): Int {
|
|
||||||
val minWidth = resources.getDimensionPixelSize(R.dimen.video_item_grid_thumbnail_image_width)
|
|
||||||
return max(1, floor(resources.displayMetrics.widthPixels / minWidth.toDouble()).toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_GROUP_ID = "ARG_GROUP_ID"
|
const val KEY_GROUP_ID = "ARG_GROUP_ID"
|
||||||
const val KEY_GROUP_NAME = "ARG_GROUP_NAME"
|
const val KEY_GROUP_NAME = "ARG_GROUP_NAME"
|
||||||
|
|
|
@ -68,6 +68,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject;
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||||
|
import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout;
|
||||||
|
|
||||||
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
|
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
|
||||||
// Save the list 10 seconds after the last change occurred
|
// Save the list 10 seconds after the last change occurred
|
||||||
|
@ -678,7 +679,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
||||||
|
|
||||||
private ItemTouchHelper.SimpleCallback getItemTouchCallback() {
|
private ItemTouchHelper.SimpleCallback getItemTouchCallback() {
|
||||||
int directions = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
int directions = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
||||||
if (isGridLayout()) {
|
if (shouldUseGridLayout(requireContext())) {
|
||||||
directions |= ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
|
directions |= ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
|
||||||
}
|
}
|
||||||
return new ItemTouchHelper.SimpleCallback(directions,
|
return new ItemTouchHelper.SimpleCallback(directions,
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -20,7 +19,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.xwray.groupie.Group
|
import com.xwray.groupie.Group
|
||||||
import com.xwray.groupie.GroupAdapter
|
import com.xwray.groupie.GroupAdapter
|
||||||
|
@ -60,12 +58,12 @@ import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
|
||||||
import org.schabi.newpipe.streams.io.StoredFileHelper
|
import org.schabi.newpipe.streams.io.StoredFileHelper
|
||||||
import org.schabi.newpipe.util.NavigationHelper
|
import org.schabi.newpipe.util.NavigationHelper
|
||||||
import org.schabi.newpipe.util.OnClickGesture
|
import org.schabi.newpipe.util.OnClickGesture
|
||||||
|
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCount
|
||||||
|
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
|
||||||
import org.schabi.newpipe.util.external_communication.ShareUtils
|
import org.schabi.newpipe.util.external_communication.ShareUtils
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.floor
|
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||||
private var _binding: FragmentSubscriptionBinding? = null
|
private var _binding: FragmentSubscriptionBinding? = null
|
||||||
|
@ -279,8 +277,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||||
super.initViews(rootView, savedInstanceState)
|
super.initViews(rootView, savedInstanceState)
|
||||||
_binding = FragmentSubscriptionBinding.bind(rootView)
|
_binding = FragmentSubscriptionBinding.bind(rootView)
|
||||||
|
|
||||||
val shouldUseGridLayout = shouldUseGridLayout()
|
groupAdapter.spanCount = if (shouldUseGridLayout(context)) getGridSpanCount(context) else 1
|
||||||
groupAdapter.spanCount = if (shouldUseGridLayout) getGridSpanCount() else 1
|
|
||||||
binding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
|
binding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
|
||||||
spanSizeLookup = groupAdapter.spanSizeLookup
|
spanSizeLookup = groupAdapter.spanSizeLookup
|
||||||
}
|
}
|
||||||
|
@ -359,7 +356,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||||
override fun handleResult(result: SubscriptionState) {
|
override fun handleResult(result: SubscriptionState) {
|
||||||
super.handleResult(result)
|
super.handleResult(result)
|
||||||
|
|
||||||
val shouldUseGridLayout = shouldUseGridLayout()
|
val shouldUseGridLayout = shouldUseGridLayout(context)
|
||||||
when (result) {
|
when (result) {
|
||||||
is SubscriptionState.LoadedState -> {
|
is SubscriptionState.LoadedState -> {
|
||||||
result.subscriptions.forEach {
|
result.subscriptions.forEach {
|
||||||
|
@ -420,30 +417,4 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||||
super.hideLoading()
|
super.hideLoading()
|
||||||
binding.itemsList.animate(true, 200)
|
binding.itemsList.animate(true, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
|
||||||
// Grid Mode
|
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// TODO: Move these out of this class, as it can be reused
|
|
||||||
|
|
||||||
private fun shouldUseGridLayout(): Boolean {
|
|
||||||
val listMode = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
|
||||||
.getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value))
|
|
||||||
|
|
||||||
return when (listMode) {
|
|
||||||
getString(R.string.list_view_mode_auto_key) -> {
|
|
||||||
val configuration = resources.configuration
|
|
||||||
configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&
|
|
||||||
configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE)
|
|
||||||
}
|
|
||||||
getString(R.string.list_view_mode_grid_key) -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGridSpanCount(): Int {
|
|
||||||
val minWidth = resources.getDimensionPixelSize(R.dimen.channel_item_grid_min_width)
|
|
||||||
return max(1, floor(resources.displayMetrics.widthPixels / minWidth.toDouble()).toInt())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,4 +298,43 @@ public final class ThemeHelper {
|
||||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the grid layout or the list layout should be used. If the user set "auto"
|
||||||
|
* mode in settings, decides based on screen orientation (landscape) and size.
|
||||||
|
*
|
||||||
|
* @param context the context to use
|
||||||
|
* @return true:use grid layout, false:use list layout
|
||||||
|
*/
|
||||||
|
public static boolean shouldUseGridLayout(final Context context) {
|
||||||
|
final String listMode = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
.getString(context.getString(R.string.list_view_mode_key),
|
||||||
|
context.getString(R.string.list_view_mode_value));
|
||||||
|
|
||||||
|
if (listMode.equals(context.getString(R.string.list_view_mode_list_key))) {
|
||||||
|
return false;
|
||||||
|
} else if (listMode.equals(context.getString(R.string.list_view_mode_grid_key))) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
final Configuration configuration = context.getResources().getConfiguration();
|
||||||
|
return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
&& configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the number of grid items that can fit horizontally on the screen. The width of a
|
||||||
|
* grid item is obtained from the thumbnail width plus the right and left paddings.
|
||||||
|
*
|
||||||
|
* @param context the context to use
|
||||||
|
* @return the span count of grid list items
|
||||||
|
*/
|
||||||
|
public static int getGridSpanCount(final Context context) {
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
final int minWidth
|
||||||
|
= res.getDimensionPixelSize(R.dimen.video_item_grid_thumbnail_image_width)
|
||||||
|
+ res.getDimensionPixelSize(R.dimen.video_item_search_padding) * 2;
|
||||||
|
return Math.max(1, res.getDisplayMetrics().widthPixels / minWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue