Add preference to show subscription title (#5538)

This commit is contained in:
vbh 2021-12-01 21:17:37 +00:00 committed by GitHub
parent 561141cfff
commit d4769620b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 175 additions and 9 deletions

View File

@ -133,6 +133,7 @@ dependencies {
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation "androidx.work:work-runtime:$workManagerVersion"
implementation "com.google.android.material:material:$googleMaterialVersion"
implementation 'androidx.palette:palette:1.0.0'
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation "commons-io:commons-io:$commonsioVersion"

View File

@ -3,6 +3,9 @@ package de.danoeh.antennapod.adapter;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import androidx.palette.graphics.Palette;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@ -19,6 +22,9 @@ import com.bumptech.glide.request.transition.Transition;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.glide.PaletteBitmap;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.ui.common.ThemeUtils;
public class CoverLoader {
private int resource = 0;
@ -77,7 +83,7 @@ public class CoverLoader {
if (resource != 0) {
Glide.with(activity).clear(coverTarget);
imgvCover.setImageResource(resource);
CoverTarget.setPlaceholderVisibility(txtvPlaceholder, textAndImageCombined);
CoverTarget.setPlaceholderVisibility(txtvPlaceholder, textAndImageCombined, null);
return;
}
@ -86,12 +92,14 @@ public class CoverLoader {
.fitCenter()
.dontAnimate();
RequestBuilder<Drawable> builder = Glide.with(activity)
RequestBuilder<PaletteBitmap> builder = Glide.with(activity)
.as(PaletteBitmap.class)
.load(uri)
.apply(options);
if (fallbackUri != null && txtvPlaceholder != null && imgvCover != null) {
builder = builder.error(Glide.with(activity)
.as(PaletteBitmap.class)
.load(fallbackUri)
.apply(options));
}
@ -99,7 +107,7 @@ public class CoverLoader {
builder.into(coverTarget);
}
static class CoverTarget extends CustomViewTarget<ImageView, Drawable> {
static class CoverTarget extends CustomViewTarget<ImageView, PaletteBitmap> {
private final WeakReference<TextView> placeholder;
private final WeakReference<ImageView> cover;
private boolean textAndImageCombined;
@ -120,23 +128,38 @@ public class CoverLoader {
}
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
setPlaceholderVisibility(placeholder.get(), textAndImageCombined);
public void onResourceReady(@NonNull PaletteBitmap resource,
@Nullable Transition<? super PaletteBitmap> transition) {
ImageView ivCover = cover.get();
ivCover.setImageDrawable(resource);
ivCover.setImageBitmap(resource.bitmap);
setPlaceholderVisibility(placeholder.get(), textAndImageCombined, resource.palette);
}
@Override
protected void onResourceCleared(@Nullable Drawable placeholder) {
ImageView ivCover = cover.get();
ivCover.setImageDrawable(placeholder);
setPlaceholderVisibility(this.placeholder.get(), textAndImageCombined, null);
}
static void setPlaceholderVisibility(TextView placeholder, boolean textAndImageCombined) {
static void setPlaceholderVisibility(TextView placeholder, boolean textAndImageCombined, Palette palette) {
boolean showTitle = UserPreferences.shouldShowSubscriptionTitle();
if (placeholder != null) {
if (textAndImageCombined) {
if (textAndImageCombined || showTitle) {
int bgColor = placeholder.getContext().getResources().getColor(R.color.feed_text_bg);
placeholder.setBackgroundColor(bgColor);
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 = placeholder.getContext().getResources().getColor(R.color.white);
if (ColorUtils.calculateLuminance(dominantColor) > 0.5) {
textColor = placeholder.getContext().getResources().getColor(R.color.black);
}
placeholder.setTextColor(textColor);
placeholder.setBackgroundColor(dominantColor);
} else {
placeholder.setVisibility(View.INVISIBLE);
}

View File

@ -13,6 +13,7 @@ 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;
@ -31,6 +32,7 @@ import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
@ -42,6 +44,8 @@ import jp.shts.android.library.TriangleLabelView;
*/
public class SubscriptionsRecyclerAdapter extends SelectableAdapter<SubscriptionsRecyclerAdapter.SubscriptionViewHolder>
implements View.OnCreateContextMenuListener {
private static final int COVER_WITH_TITLE = 1;
private final WeakReference<MainActivity> mainActivityRef;
private List<NavDrawerData.DrawerItem> listItems;
private Feed selectedFeed = null;
@ -66,6 +70,23 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
@Override
public SubscriptionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mainActivityRef.get()).inflate(R.layout.subscription_item, parent, false);
TextView feedTitle = itemView.findViewById(R.id.txtvTitle);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) feedTitle.getLayoutParams();
int topAndBottomItemId = R.id.imgvCover;
int belowItemId = 0;
if (viewType == COVER_WITH_TITLE) {
topAndBottomItemId = 0;
belowItemId = R.id.imgvCover;
feedTitle.setBackgroundColor(feedTitle.getContext().getResources().getColor(R.color.feed_text_bg));
int padding = (int) convertDpToPixel(feedTitle.getContext(), 6);
feedTitle.setPadding(padding, padding, padding, padding);
}
params.addRule(RelativeLayout.BELOW, belowItemId);
params.addRule(RelativeLayout.ALIGN_TOP, topAndBottomItemId);
params.addRule(RelativeLayout.ALIGN_BOTTOM, topAndBottomItemId);
feedTitle.setLayoutParams(params);
feedTitle.setSingleLine(viewType == COVER_WITH_TITLE);
return new SubscriptionViewHolder(itemView);
}
@ -173,6 +194,11 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
}
}
@Override
public int getItemViewType(int position) {
return UserPreferences.shouldShowSubscriptionTitle() ? COVER_WITH_TITLE : 0;
}
public class SubscriptionViewHolder extends RecyclerView.ViewHolder {
private final TextView feedTitle;
private final ImageView imageView;

View File

@ -44,6 +44,11 @@
android:title="@string/pref_filter_feed_title"
android:key="prefSubscriptionsFilter"
android:summary="@string/pref_filter_feed_sum" />
<SwitchPreferenceCompat
android:title="@string/pref_show_subscription_title"
android:key="prefSubscriptionTitle"
android:summary="@string/pref_show_subscription_title_summary"
android:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/external_elements">
<SwitchPreferenceCompat

View File

@ -42,6 +42,7 @@ dependencies {
implementation "androidx.preference:preference:$preferenceVersion"
implementation "androidx.work:work-runtime:$workManagerVersion"
implementation "com.google.android.material:material:$googleMaterialVersion"
implementation 'androidx.palette:palette:1.0.0'
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation "commons-io:commons-io:$commonsioVersion"

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.glide;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import androidx.annotation.NonNull;
@ -45,5 +46,6 @@ public class ApGlideModule extends AppGlideModule {
registry.append(String.class, InputStream.class, new NoHttpStringLoader.StreamFactory());
registry.append(EmbeddedChapterImage.class, ByteBuffer.class, new ChapterImageModelLoader.Factory());
registry.register(Bitmap.class, PaletteBitmap.class, new PaletteBitmapTranscoder());
}
}

View File

@ -0,0 +1,20 @@
/*
* Source: https://github.com/bumptech/glide/wiki/Custom-targets#palette-example
*/
package de.danoeh.antennapod.core.glide;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.palette.graphics.Palette;
public class PaletteBitmap {
public final Palette palette;
public final Bitmap bitmap;
public PaletteBitmap(@NonNull Bitmap bitmap, Palette palette) {
this.bitmap = bitmap;
this.palette = palette;
}
}

View File

@ -0,0 +1,40 @@
/*
* Source: https://github.com/bumptech/glide/wiki/Custom-targets#palette-example
*/
package de.danoeh.antennapod.core.glide;
import androidx.annotation.NonNull;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.util.Util;
public class PaletteBitmapResource implements Resource<PaletteBitmap> {
private final PaletteBitmap paletteBitmap;
public PaletteBitmapResource(@NonNull PaletteBitmap paletteBitmap) {
this.paletteBitmap = paletteBitmap;
}
@NonNull
@Override
public Class<PaletteBitmap> getResourceClass() {
return PaletteBitmap.class;
}
@NonNull
@Override
public PaletteBitmap get() {
return paletteBitmap;
}
@Override
public int getSize() {
return Util.getBitmapByteSize(paletteBitmap.bitmap);
}
@Override
public void recycle() {
paletteBitmap.bitmap.recycle();
}
}

View File

@ -0,0 +1,32 @@
/*
* Source: https://github.com/bumptech/glide/wiki/Custom-targets#palette-example
*/
package de.danoeh.antennapod.core.glide;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.palette.graphics.Palette;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import de.danoeh.antennapod.core.preferences.UserPreferences;
public class PaletteBitmapTranscoder implements ResourceTranscoder<Bitmap, PaletteBitmap> {
@Nullable
@Override
public Resource<PaletteBitmap> transcode(@NonNull Resource<Bitmap> toTranscode, @NonNull Options options) {
Bitmap bitmap = toTranscode.get();
Palette palette = null;
if (UserPreferences.shouldShowSubscriptionTitle()) {
palette = new Palette.Builder(bitmap).generate();
}
PaletteBitmap result = new PaletteBitmap(bitmap, palette);
return new PaletteBitmapResource(result);
}
}

View File

@ -69,6 +69,7 @@ public class UserPreferences {
public static final String PREF_BACK_BUTTON_BEHAVIOR = "prefBackButtonBehavior";
private static final String PREF_BACK_BUTTON_GO_TO_PAGE = "prefBackButtonGoToPage";
public static final String PREF_FILTER_FEED = "prefSubscriptionsFilter";
public static final String PREF_SUBSCRIPTION_TITLE = "prefSubscriptionTitle";
public static final String PREF_QUEUE_KEEP_SORTED = "prefQueueKeepSorted";
public static final String PREF_QUEUE_KEEP_SORTED_ORDER = "prefQueueKeepSortedOrder";
@ -1090,4 +1091,13 @@ public class UserPreferences {
public static void unsetUsageCountingDate() {
setUsageCountingDateMillis(-1);
}
public static boolean shouldShowSubscriptionTitle() {
return prefs.getBoolean(PREF_SUBSCRIPTION_TITLE, false);
}
public static void setSubscriptionTitleSetting(boolean showTitle) {
prefs.edit().putBoolean(PREF_SUBSCRIPTION_TITLE, showTitle).apply();
}
}

View File

@ -539,6 +539,8 @@
<string name="new_episode_notification_disabled">Notification disabled</string>
<string name="pref_feed_settings_dialog_msg">This setting is unique to each podcast. You can change it by opening the podcast page.</string>
<string name="pref_contribute">Contribute</string>
<string name="pref_show_subscription_title">Show Subscription Title</string>
<string name="pref_show_subscription_title_summary">Display the subscription title below the cover image.</string>
<!-- About screen -->
<string name="about_pref">About</string>

View File

@ -5,6 +5,7 @@ import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import android.util.TypedValue;
import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;
public class ThemeUtils {
private ThemeUtils() {
@ -14,6 +15,9 @@ public class ThemeUtils {
public static @ColorInt int getColorFromAttr(Context context, @AttrRes int attr) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attr, typedValue, true);
if (typedValue.resourceId != 0) {
return ContextCompat.getColor(context, typedValue.resourceId);
}
return typedValue.data;
}