Optionally display subscriptions as a simple list (#7087)

This commit is contained in:
ByteHamster 2024-04-14 11:45:12 +02:00 committed by GitHub
parent d6b2a49caa
commit e9b3cc34fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 278 additions and 125 deletions

View File

@ -64,8 +64,9 @@ public class SubscriptionFragment extends Fragment
private static final String KEY_UP_ARROW = "up_arrow"; private static final String KEY_UP_ARROW = "up_arrow";
private static final String ARGUMENT_FOLDER = "folder"; private static final String ARGUMENT_FOLDER = "folder";
private static final int MIN_NUM_COLUMNS = 2; private static final int MIN_NUM_COLUMNS = 1;
private static final int[] COLUMN_CHECKBOX_IDS = { private static final int[] COLUMN_CHECKBOX_IDS = {
R.id.subscription_display_list,
R.id.subscription_num_columns_2, R.id.subscription_num_columns_2,
R.id.subscription_num_columns_3, R.id.subscription_num_columns_3,
R.id.subscription_num_columns_4, R.id.subscription_num_columns_4,
@ -85,9 +86,8 @@ public class SubscriptionFragment extends Fragment
private SharedPreferences prefs; private SharedPreferences prefs;
private FloatingActionButton subscriptionAddButton; private FloatingActionButton subscriptionAddButton;
private SpeedDialView speedDialView; private SpeedDialView speedDialView;
private RecyclerView.ItemDecoration itemDecoration;
private List<NavDrawerData.DrawerItem> listItems; private List<NavDrawerData.DrawerItem> listItems;
public static SubscriptionFragment newInstance(String folderTitle) { public static SubscriptionFragment newInstance(String folderTitle) {
@ -121,7 +121,7 @@ public class SubscriptionFragment extends Fragment
} }
((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
toolbar.inflateMenu(R.menu.subscriptions); toolbar.inflateMenu(R.menu.subscriptions);
for (int i = 0; i < COLUMN_CHECKBOX_IDS.length; i++) { for (int i = 1; i < COLUMN_CHECKBOX_IDS.length; i++) {
// Do this in Java to localize numbers // Do this in Java to localize numbers
toolbar.getMenu().findItem(COLUMN_CHECKBOX_IDS[i]) toolbar.getMenu().findItem(COLUMN_CHECKBOX_IDS[i])
.setTitle(String.format(Locale.getDefault(), "%d", i + MIN_NUM_COLUMNS)); .setTitle(String.format(Locale.getDefault(), "%d", i + MIN_NUM_COLUMNS));
@ -136,7 +136,6 @@ public class SubscriptionFragment extends Fragment
} }
subscriptionRecycler = root.findViewById(R.id.subscriptions_grid); subscriptionRecycler = root.findViewById(R.id.subscriptions_grid);
subscriptionRecycler.addItemDecoration(new SubscriptionsRecyclerAdapter.GridDividerItemDecorator());
registerForContextMenu(subscriptionRecycler); registerForContextMenu(subscriptionRecycler);
subscriptionRecycler.addOnScrollListener(new LiftOnScrollListener(root.findViewById(R.id.appbar))); subscriptionRecycler.addOnScrollListener(new LiftOnScrollListener(root.findViewById(R.id.appbar)));
subscriptionAdapter = new SubscriptionsRecyclerAdapter((MainActivity) getActivity()) { subscriptionAdapter = new SubscriptionsRecyclerAdapter((MainActivity) getActivity()) {
@ -209,6 +208,9 @@ public class SubscriptionFragment extends Fragment
} else if (itemId == R.id.subscriptions_sort) { } else if (itemId == R.id.subscriptions_sort) {
FeedSortDialog.showDialog(requireContext()); FeedSortDialog.showDialog(requireContext());
return true; return true;
} else if (itemId == R.id.subscription_display_list) {
setColumnNumber(1);
return true;
} else if (itemId == R.id.subscription_num_columns_2) { } else if (itemId == R.id.subscription_num_columns_2) {
setColumnNumber(2); setColumnNumber(2);
return true; return true;
@ -232,10 +234,22 @@ public class SubscriptionFragment extends Fragment
} }
private void setColumnNumber(int columns) { private void setColumnNumber(int columns) {
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), if (itemDecoration != null) {
columns, RecyclerView.VERTICAL, false); subscriptionRecycler.removeItemDecoration(itemDecoration);
itemDecoration = null;
}
RecyclerView.LayoutManager layoutManager;
if (columns == 1 && getDefaultNumOfColumns() == 5) { // Tablet
layoutManager = new GridLayoutManager(getContext(), 2, RecyclerView.VERTICAL, false);
} else if (columns == 1) {
layoutManager = new GridLayoutManager(getContext(), 1, RecyclerView.VERTICAL, false);
} else {
layoutManager = new GridLayoutManager(getContext(), columns, RecyclerView.VERTICAL, false);
itemDecoration = new SubscriptionsRecyclerAdapter.GridDividerItemDecorator();
subscriptionRecycler.addItemDecoration(itemDecoration);
}
subscriptionAdapter.setColumnCount(columns); subscriptionAdapter.setColumnCount(columns);
subscriptionRecycler.setLayoutManager(gridLayoutManager); subscriptionRecycler.setLayoutManager(layoutManager);
prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply(); prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply();
refreshToolbarState(); refreshToolbarState();
} }

View File

@ -0,0 +1,104 @@
package de.danoeh.antennapod.ui.screen.subscriptions;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.elevation.SurfaceColors;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.database.NavDrawerData;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.CoverLoader;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
public class SubscriptionViewHolder extends RecyclerView.ViewHolder {
public final TextView title;
public final ImageView coverImage;
public final TextView count;
public final TextView fallbackTitle;
public final FrameLayout selectView;
public final CheckBox selectCheckbox;
public final CardView card;
public final View errorIcon;
public final WeakReference<MainActivity> mainActivityRef;
public SubscriptionViewHolder(@NonNull View itemView, MainActivity mainActivity) {
super(itemView);
title = itemView.findViewById(R.id.titleLabel);
coverImage = itemView.findViewById(R.id.coverImage);
count = itemView.findViewById(R.id.countViewPill);
fallbackTitle = itemView.findViewById(R.id.fallbackTitleLabel);
selectView = itemView.findViewById(R.id.selectContainer);
selectCheckbox = itemView.findViewById(R.id.selectCheckBox);
card = itemView.findViewById(R.id.outerContainer);
errorIcon = itemView.findViewById(R.id.errorIcon);
this.mainActivityRef = new WeakReference<>(mainActivity);
}
public void bind(NavDrawerData.DrawerItem drawerItem, int columnCount) {
if (selectView != null) {
Drawable drawable = AppCompatResources.getDrawable(selectView.getContext(),
R.drawable.ic_checkbox_background);
selectView.setBackground(drawable); // Setting this in XML crashes API <= 21
}
title.setText(drawerItem.getTitle());
fallbackTitle.setText(drawerItem.getTitle());
coverImage.setContentDescription(drawerItem.getTitle());
if (drawerItem.getCounter() > 0) {
count.setText(NumberFormat.getInstance().format(drawerItem.getCounter()));
count.setVisibility(View.VISIBLE);
} else {
count.setVisibility(View.GONE);
}
CoverLoader coverLoader = new CoverLoader();
boolean textAndImageCombined;
if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed;
textAndImageCombined = feed.isLocalFeed() && feed.getImageUrl() != null
&& feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER);
coverLoader.withUri(feed.getImageUrl());
errorIcon.setVisibility(feed.hasLastUpdateFailed() ? View.VISIBLE : View.GONE);
} else {
textAndImageCombined = true;
coverLoader.withResource(R.drawable.ic_tag);
errorIcon.setVisibility(View.GONE);
}
if (UserPreferences.shouldShowSubscriptionTitle() || columnCount == 1) {
// No need for fallback title when already showing title
fallbackTitle.setVisibility(View.GONE);
} else {
coverLoader.withPlaceholderView(fallbackTitle, textAndImageCombined);
}
coverLoader.withCoverView(coverImage);
coverLoader.load();
if (card != null) {
float density = mainActivityRef.get().getResources().getDisplayMetrics().density;
card.setCardBackgroundColor(SurfaceColors.getColorForElevation(mainActivityRef.get(), 1 * density));
}
int textPadding = columnCount <= 3 ? 16 : 8;
title.setPadding(textPadding, textPadding, textPadding, textPadding);
fallbackTitle.setPadding(textPadding, textPadding, textPadding, textPadding);
int textSize = 14;
if (columnCount == 3) {
textSize = 15;
} else if (columnCount == 2) {
textSize = 16;
}
title.setTextSize(textSize);
fallbackTitle.setTextSize(textSize);
}
}

View File

@ -3,7 +3,6 @@ package de.danoeh.antennapod.ui.screen.subscriptions;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.InputDevice; import android.view.InputDevice;
@ -13,39 +12,27 @@ import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.elevation.SurfaceColors;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.ui.CoverLoader;
import de.danoeh.antennapod.ui.SelectableAdapter;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.database.NavDrawerData;
import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.database.NavDrawerData;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.SelectableAdapter;
import de.danoeh.antennapod.ui.common.ThemeUtils;
import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
/** /**
* Adapter for subscriptions * Adapter for subscriptions
*/ */
public class SubscriptionsRecyclerAdapter extends SelectableAdapter<SubscriptionsRecyclerAdapter.SubscriptionViewHolder> public class SubscriptionsRecyclerAdapter extends SelectableAdapter<SubscriptionViewHolder>
implements View.OnCreateContextMenuListener { implements View.OnCreateContextMenuListener {
private static final int COVER_WITH_TITLE = 1;
private final WeakReference<MainActivity> mainActivityRef; private final WeakReference<MainActivity> mainActivityRef;
private List<NavDrawerData.DrawerItem> listItems; private List<NavDrawerData.DrawerItem> listItems;
private NavDrawerData.DrawerItem selectedItem = null; private NavDrawerData.DrawerItem selectedItem = null;
@ -74,30 +61,49 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
@NonNull @NonNull
@Override @Override
public SubscriptionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public SubscriptionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mainActivityRef.get()).inflate(R.layout.subscription_item, parent, false); if (viewType == R.id.view_type_subscription_list) {
itemView.findViewById(R.id.titleLabel).setVisibility(viewType == COVER_WITH_TITLE ? View.VISIBLE : View.GONE); View itemView = LayoutInflater.from(mainActivityRef.get())
return new SubscriptionViewHolder(itemView); .inflate(R.layout.subscription_list_item, parent, false);
return new SubscriptionViewHolder(itemView, mainActivityRef.get());
}
View itemView = LayoutInflater.from(mainActivityRef.get())
.inflate(R.layout.subscription_grid_item, parent, false);
itemView.findViewById(R.id.titleLabel).setVisibility(
viewType == R.id.view_type_subscription_grid_with_title ? View.VISIBLE : View.GONE);
return new SubscriptionViewHolder(itemView, mainActivityRef.get());
} }
@Override @Override
public void onBindViewHolder(@NonNull SubscriptionViewHolder holder, int position) { public void onBindViewHolder(@NonNull SubscriptionViewHolder holder, int position) {
NavDrawerData.DrawerItem drawerItem = listItems.get(position); NavDrawerData.DrawerItem drawerItem = listItems.get(position);
boolean isFeed = drawerItem.type == NavDrawerData.DrawerItem.Type.FEED; boolean isFeed = drawerItem.type == NavDrawerData.DrawerItem.Type.FEED;
holder.bind(drawerItem); holder.bind(drawerItem, columnCount);
holder.itemView.setOnCreateContextMenuListener(this); holder.itemView.setOnCreateContextMenuListener(this);
if (inActionMode()) { if (inActionMode()) {
if (isFeed) { if (holder.selectView != null) {
holder.selectCheckbox.setVisibility(View.VISIBLE); if (isFeed) {
holder.selectView.setVisibility(View.VISIBLE); holder.selectCheckbox.setVisibility(View.VISIBLE);
}
holder.selectView.setVisibility(isFeed ? View.VISIBLE : View.GONE);
holder.coverImage.setAlpha(0.6f);
holder.selectCheckbox.setChecked((isSelected(position)));
holder.selectCheckbox.setOnCheckedChangeListener((buttonView, isChecked)
-> setSelected(holder.getBindingAdapterPosition(), isChecked));
holder.count.setVisibility(View.GONE);
} else {
holder.itemView.setBackgroundResource(android.R.color.transparent);
if (isSelected(position)) {
holder.itemView.setBackgroundColor(0x88000000
+ (0xffffff & ThemeUtils.getColorFromAttr(mainActivityRef.get(), R.attr.colorAccent)));
}
} }
holder.selectCheckbox.setChecked((isSelected(position)));
holder.selectCheckbox.setOnCheckedChangeListener((buttonView, isChecked)
-> setSelected(holder.getBindingAdapterPosition(), isChecked));
holder.coverImage.setAlpha(0.6f);
holder.count.setVisibility(View.GONE);
} else { } else {
holder.selectView.setVisibility(View.GONE); holder.itemView.setBackgroundResource(android.R.color.transparent);
holder.coverImage.setAlpha(1.0f); if (holder.selectView != null) {
holder.selectCheckbox.setVisibility(View.GONE);
holder.selectView.setVisibility(View.GONE);
holder.coverImage.setAlpha(1.0f);
}
} }
holder.itemView.setOnLongClickListener(v -> { holder.itemView.setOnLongClickListener(v -> {
@ -127,7 +133,8 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
holder.itemView.setOnClickListener(v -> { holder.itemView.setOnClickListener(v -> {
if (isFeed) { if (isFeed) {
if (inActionMode()) { if (inActionMode()) {
holder.selectCheckbox.setChecked(!isSelected(holder.getBindingAdapterPosition())); setSelected(holder.getBindingAdapterPosition(), !isSelected(holder.getBindingAdapterPosition()));
notifyItemChanged(holder.getBindingAdapterPosition());
} else { } else {
Fragment fragment = FeedItemlistFragment Fragment fragment = FeedItemlistFragment
.newInstance(((NavDrawerData.FeedDrawerItem) drawerItem).feed.getId()); .newInstance(((NavDrawerData.FeedDrawerItem) drawerItem).feed.getId());
@ -206,82 +213,12 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
return UserPreferences.shouldShowSubscriptionTitle() ? COVER_WITH_TITLE : 0; if (columnCount == 1) {
} return R.id.view_type_subscription_list;
} else if (UserPreferences.shouldShowSubscriptionTitle()) {
public class SubscriptionViewHolder extends RecyclerView.ViewHolder { return R.id.view_type_subscription_grid_with_title;
private final TextView title; } else {
private final ImageView coverImage; return R.id.view_type_subscription_grid_without_title;
private final TextView count;
private final TextView fallbackTitle;
private final FrameLayout selectView;
private final CheckBox selectCheckbox;
private final CardView card;
private final View errorIcon;
public SubscriptionViewHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.titleLabel);
coverImage = itemView.findViewById(R.id.coverImage);
count = itemView.findViewById(R.id.countViewPill);
fallbackTitle = itemView.findViewById(R.id.fallbackTitleLabel);
selectView = itemView.findViewById(R.id.selectContainer);
selectCheckbox = itemView.findViewById(R.id.selectCheckBox);
card = itemView.findViewById(R.id.outerContainer);
errorIcon = itemView.findViewById(R.id.errorIcon);
}
public void bind(NavDrawerData.DrawerItem drawerItem) {
Drawable drawable = AppCompatResources.getDrawable(selectView.getContext(),
R.drawable.ic_checkbox_background);
selectView.setBackground(drawable); // Setting this in XML crashes API <= 21
title.setText(drawerItem.getTitle());
fallbackTitle.setText(drawerItem.getTitle());
coverImage.setContentDescription(drawerItem.getTitle());
if (drawerItem.getCounter() > 0) {
count.setText(NumberFormat.getInstance().format(drawerItem.getCounter()));
count.setVisibility(View.VISIBLE);
} else {
count.setVisibility(View.GONE);
}
CoverLoader coverLoader = new CoverLoader();
boolean textAndImageCombined;
if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed;
textAndImageCombined = feed.isLocalFeed() && feed.getImageUrl() != null
&& feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER);
coverLoader.withUri(feed.getImageUrl());
errorIcon.setVisibility(feed.hasLastUpdateFailed() ? View.VISIBLE : View.GONE);
} else {
textAndImageCombined = true;
coverLoader.withResource(R.drawable.ic_tag);
errorIcon.setVisibility(View.GONE);
}
if (UserPreferences.shouldShowSubscriptionTitle()) {
// No need for fallback title when already showing title
fallbackTitle.setVisibility(View.GONE);
} else {
coverLoader.withPlaceholderView(fallbackTitle, textAndImageCombined);
}
coverLoader.withCoverView(coverImage);
coverLoader.load();
float density = mainActivityRef.get().getResources().getDisplayMetrics().density;
card.setCardBackgroundColor(SurfaceColors.getColorForElevation(mainActivityRef.get(), 1 * density));
int textPadding = columnCount <= 3 ? 16 : 8;
title.setPadding(textPadding, textPadding, textPadding, textPadding);
fallbackTitle.setPadding(textPadding, textPadding, textPadding, textPadding);
int textSize = 14;
if (columnCount == 3) {
textSize = 15;
} else if (columnCount == 2) {
textSize = 16;
}
title.setTextSize(textSize);
fallbackTitle.setTextSize(textSize);
} }
} }

View File

@ -61,7 +61,7 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:paddingBottom="88dp" android:paddingBottom="88dp"
tools:itemCount="2" tools:itemCount="2"
tools:listitem="@layout/subscription_item" /> tools:listitem="@layout/subscription_grid_item" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -26,7 +26,6 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="1px"
android:clickable="false" android:clickable="false"
app:cardBackgroundColor="@color/non_square_icon_background" app:cardBackgroundColor="@color/non_square_icon_background"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
@ -34,7 +33,8 @@
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_margin="1px">
<de.danoeh.antennapod.ui.common.SquareImageView <de.danoeh.antennapod.ui.common.SquareImageView
android:id="@+id/coverImage" android:id="@+id/coverImage"

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:squareImageView="http://schemas.android.com/apk/de.danoeh.antennapod"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="56dp"
android:layout_height="56dp"
android:clickable="false"
app:cardBackgroundColor="@color/non_square_icon_background"
app:cardCornerRadius="12dp"
app:cardElevation="0dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1px">
<de.danoeh.antennapod.ui.common.SquareImageView
android:id="@+id/coverImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:outlineProvider="background"
squareImageView:direction="width"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/fallbackTitleLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/coverImage"
android:layout_alignLeft="@+id/coverImage"
android:layout_alignTop="@+id/coverImage"
android:layout_alignEnd="@+id/coverImage"
android:layout_alignRight="@+id/coverImage"
android:layout_alignBottom="@+id/coverImage"
android:background="@color/feed_text_bg"
android:gravity="center"
android:ellipsize="end"
android:padding="6dp"
android:textColor="#fff"
tools:text="@sample/episodes.json/data/title" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/titleLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="start"
android:maxLines="2"
android:importantForAccessibility="no"
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
tools:text="@sample/episodes.json/data/title" />
<TextView
android:id="@+id/countViewPill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="3"
android:textColor="?android:attr/textColorTertiary"
android:textSize="14sp" />
<ImageView
android:id="@+id/errorIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="8dp"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:contentDescription="@string/refresh_failed_msg"
app:srcCompat="@drawable/ic_error"
tools:visibility="visible" />
</LinearLayout>

View File

@ -31,6 +31,9 @@
<menu> <menu>
<group <group
android:checkableBehavior="single"> android:checkableBehavior="single">
<item
android:id="@+id/subscription_display_list"
android:title="@string/subscription_display_list"/>
<item <item
android:id="@+id/subscription_num_columns_2" android:id="@+id/subscription_num_columns_2"
android:title="2"/> android:title="2"/>

View File

@ -14,4 +14,7 @@
<!-- View types --> <!-- View types -->
<item name="view_type_episode_item" type="id"/> <item name="view_type_episode_item" type="id"/>
<item name="view_type_subscription_grid_with_title" type="id"/>
<item name="view_type_subscription_grid_without_title" type="id"/>
<item name="view_type_subscription_list" type="id"/>
</resources> </resources>

View File

@ -823,6 +823,7 @@
<!-- Subscriptions fragment --> <!-- Subscriptions fragment -->
<string name="subscription_num_columns">Number of columns</string> <string name="subscription_num_columns">Number of columns</string>
<string name="subscription_display_list">List</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_group_errors">Errors</string> <string name="notification_group_errors">Errors</string>