From 4096aaf47ea6f0341274e82fc14c5a3960a83f5f Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Sat, 11 Feb 2023 19:04:14 +0100 Subject: Convert subscriptions screen to cards (#6261) --- .../de/danoeh/antennapod/adapter/CoverLoader.java | 100 +++++---------- .../adapter/SubscriptionsRecyclerAdapter.java | 108 ++++++++-------- .../antennapod/fragment/SubscriptionFragment.java | 3 +- app/src/main/res/layout/subscription_item.xml | 141 ++++++++++++++------- 4 files changed, 182 insertions(+), 170 deletions(-) (limited to 'app') diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java index dc82e3adc..1d06bf07c 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java @@ -1,40 +1,28 @@ package de.danoeh.antennapod.adapter; -import android.content.Context; import android.graphics.drawable.Drawable; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.ColorUtils; -import androidx.palette.graphics.Palette; - import android.view.View; import android.widget.ImageView; import android.widget.TextView; - +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.CustomViewTarget; - -import java.lang.ref.WeakReference; - import com.bumptech.glide.request.transition.Transition; - -import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.storage.preferences.UserPreferences; -import de.danoeh.antennapod.ui.common.ThemeUtils; -import de.danoeh.antennapod.ui.glide.PaletteBitmap; + +import java.lang.ref.WeakReference; public class CoverLoader { private int resource = 0; private String uri; private String fallbackUri; - private TextView txtvPlaceholder; private ImageView imgvCover; private boolean textAndImageCombined; private MainActivity activity; + private TextView fallbackTitle; public CoverLoader(MainActivity activity) { this.activity = activity; @@ -60,31 +48,30 @@ public class CoverLoader { return this; } - public CoverLoader withPlaceholderView(TextView placeholderView) { - txtvPlaceholder = placeholderView; + public CoverLoader withPlaceholderView(TextView title) { + this.fallbackTitle = title; return this; } /** * Set cover text and if it should be shown even if there is a cover image. - * - * @param placeholderView Cover text. + * @param fallbackTitle Fallback title text * @param textAndImageCombined Show cover text even if there is a cover image? */ @NonNull - public CoverLoader withPlaceholderView(@NonNull TextView placeholderView, boolean textAndImageCombined) { - this.txtvPlaceholder = placeholderView; + public CoverLoader withPlaceholderView(TextView fallbackTitle, boolean textAndImageCombined) { + this.fallbackTitle = fallbackTitle; this.textAndImageCombined = textAndImageCombined; return this; } public void load() { - CoverTarget coverTarget = new CoverTarget(txtvPlaceholder, imgvCover, textAndImageCombined); + CoverTarget coverTarget = new CoverTarget(fallbackTitle, imgvCover, textAndImageCombined); if (resource != 0) { Glide.with(activity).clear(coverTarget); imgvCover.setImageResource(resource); - CoverTarget.setPlaceholderVisibility(txtvPlaceholder, textAndImageCombined, null); + CoverTarget.setTitleVisibility(fallbackTitle, textAndImageCombined); return; } @@ -92,14 +79,14 @@ public class CoverLoader { .fitCenter() .dontAnimate(); - RequestBuilder builder = Glide.with(activity) - .as(PaletteBitmap.class) + RequestBuilder builder = Glide.with(activity) + .as(Drawable.class) .load(uri) .apply(options); - if (fallbackUri != null && txtvPlaceholder != null && imgvCover != null) { + if (fallbackUri != null) { builder = builder.error(Glide.with(activity) - .as(PaletteBitmap.class) + .as(Drawable.class) .load(fallbackUri) .apply(options)); } @@ -107,64 +94,41 @@ public class CoverLoader { builder.into(coverTarget); } - static class CoverTarget extends CustomViewTarget { - private final WeakReference placeholder; + static class CoverTarget extends CustomViewTarget { + private final WeakReference fallbackTitle; private final WeakReference cover; - private boolean textAndImageCombined; + private final boolean textAndImageCombined; - public CoverTarget(TextView txtvPlaceholder, ImageView imgvCover, boolean textAndImageCombined) { - super(imgvCover); - if (txtvPlaceholder != null) { - txtvPlaceholder.setVisibility(View.VISIBLE); - } - placeholder = new WeakReference<>(txtvPlaceholder); - cover = new WeakReference<>(imgvCover); + public CoverTarget(TextView fallbackTitle, ImageView coverImage, boolean textAndImageCombined) { + super(coverImage); + this.fallbackTitle = new WeakReference<>(fallbackTitle); + this.cover = new WeakReference<>(coverImage); this.textAndImageCombined = textAndImageCombined; } @Override public void onLoadFailed(Drawable errorDrawable) { - setPlaceholderVisibility(this.placeholder.get(), true, null); + setTitleVisibility(fallbackTitle.get(), true); } @Override - public void onResourceReady(@NonNull PaletteBitmap resource, - @Nullable Transition transition) { + public void onResourceReady(@NonNull Drawable resource, + @Nullable Transition transition) { ImageView ivCover = cover.get(); - ivCover.setImageBitmap(resource.bitmap); - setPlaceholderVisibility(placeholder.get(), textAndImageCombined, resource.palette); + ivCover.setImageDrawable(resource); + setTitleVisibility(fallbackTitle.get(), textAndImageCombined); } @Override protected void onResourceCleared(@Nullable Drawable placeholder) { ImageView ivCover = cover.get(); ivCover.setImageDrawable(placeholder); - setPlaceholderVisibility(this.placeholder.get(), textAndImageCombined, null); + setTitleVisibility(fallbackTitle.get(), textAndImageCombined); } - static void setPlaceholderVisibility(TextView placeholder, boolean textAndImageCombined, Palette palette) { - boolean showTitle = UserPreferences.shouldShowSubscriptionTitle(); - if (placeholder != null) { - if (textAndImageCombined || showTitle) { - final Context context = placeholder.getContext(); - placeholder.setVisibility(View.VISIBLE); - int bgColor = ContextCompat.getColor(context, R.color.feed_text_bg); - if (palette == null || !showTitle) { - placeholder.setBackgroundColor(bgColor); - placeholder.setTextColor(ThemeUtils.getColorFromAttr(placeholder.getContext(), - android.R.attr.textColorPrimary)); - return; - } - int dominantColor = palette.getDominantColor(bgColor); - int textColor = ContextCompat.getColor(context, R.color.white); - if (ColorUtils.calculateLuminance(dominantColor) > 0.5) { - textColor = ContextCompat.getColor(context, R.color.black); - } - placeholder.setTextColor(textColor); - placeholder.setBackgroundColor(dominantColor); - } else { - placeholder.setVisibility(View.INVISIBLE); - } + static void setTitleVisibility(TextView fallbackTitle, boolean textAndImageCombined) { + if (fallbackTitle != null) { + fallbackTitle.setVisibility(textAndImageCombined ? View.VISIBLE : View.GONE); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java index 7be417984..bfa37b600 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java @@ -5,7 +5,6 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; -import android.text.TextUtils; import android.view.ContextMenu; import android.view.InputDevice; import android.view.LayoutInflater; @@ -17,20 +16,19 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.content.res.AppCompatResources; -import androidx.core.content.ContextCompat; +import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; 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 java.util.Locale; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; @@ -39,7 +37,6 @@ import de.danoeh.antennapod.core.storage.NavDrawerData; import de.danoeh.antennapod.fragment.FeedItemlistFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.ui.common.TriangleLabelView; /** * Adapter for subscriptions @@ -52,6 +49,7 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter listItems; private NavDrawerData.DrawerItem selectedItem = null; int longPressedPosition = 0; // used to init actionMode + private int columnCount = 3; public SubscriptionsRecyclerAdapter(MainActivity mainActivity) { super(mainActivity); @@ -60,6 +58,10 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter setSelected(holder.getBindingAdapterPosition(), isChecked)); - holder.imageView.setAlpha(0.6f); + holder.coverImage.setAlpha(0.6f); holder.count.setVisibility(View.GONE); } else { holder.selectView.setVisibility(View.GONE); - holder.imageView.setAlpha(1.0f); + holder.coverImage.setAlpha(1.0f); } holder.itemView.setOnLongClickListener(v -> { @@ -224,55 +209,74 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter 0) { - count.setPrimaryText(NumberFormat.getInstance().format(drawerItem.getCounter())); + count.setText(NumberFormat.getInstance().format(drawerItem.getCounter())); count.setVisibility(View.VISIBLE); } else { count.setVisibility(View.GONE); } + CoverLoader coverLoader = new CoverLoader(mainActivityRef.get()); + boolean textAndImageCombined; if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) { Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed; - boolean textAndImageCombind = feed.isLocalFeed() - && feed.getImageUrl() != null && feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER); - new CoverLoader(mainActivityRef.get()) - .withUri(feed.getImageUrl()) - .withPlaceholderView(feedTitle, textAndImageCombind) - .withCoverView(imageView) - .load(); + textAndImageCombined = feed.isLocalFeed() && feed.getImageUrl() != null + && feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER); + coverLoader.withUri(feed.getImageUrl()); } else { - new CoverLoader(mainActivityRef.get()) - .withResource(R.drawable.ic_tag) - .withPlaceholderView(feedTitle, true) - .withCoverView(imageView) - .load(); + textAndImageCombined = true; + coverLoader.withResource(R.drawable.ic_tag); + } + 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); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 15886cf9a..cc13f4ce3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -142,7 +142,6 @@ public class SubscriptionFragment extends Fragment } subscriptionRecycler = root.findViewById(R.id.subscriptions_grid); - setColumnNumber(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns())); subscriptionRecycler.addItemDecoration(new SubscriptionsRecyclerAdapter.GridDividerItemDecorator()); registerForContextMenu(subscriptionRecycler); subscriptionRecycler.addOnScrollListener(new LiftOnScrollListener(root.findViewById(R.id.appbar))); @@ -153,6 +152,7 @@ public class SubscriptionFragment extends Fragment MenuItemUtils.setOnClickListeners(menu, SubscriptionFragment.this::onContextItemSelected); } }; + setColumnNumber(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns())); subscriptionAdapter.setOnSelectModeListener(this); subscriptionRecycler.setAdapter(subscriptionAdapter); setupEmptyView(); @@ -251,6 +251,7 @@ public class SubscriptionFragment extends Fragment private void setColumnNumber(int columns) { GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), columns, RecyclerView.VERTICAL, false); + subscriptionAdapter.setColumnCount(columns); subscriptionRecycler.setLayoutManager(gridLayoutManager); prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply(); refreshToolbarState(); diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml index 50cb9745f..0b689fa28 100644 --- a/app/src/main/res/layout/subscription_item.xml +++ b/app/src/main/res/layout/subscription_item.xml @@ -1,64 +1,107 @@ - + android:padding="4dp"> - + android:clickable="false" + android:foreground="?attr/selectableItemBackground" + app:cardCornerRadius="12dp" + app:cardElevation="0dp"> - - - - - - - + + + + + + + + + + + + + + + + + + + + + android:clickable="false"> + + + + - + - + -- cgit v1.2.3