diff options
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/view')
8 files changed, 196 insertions, 6 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java index 58d562616..83d90f98b 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java +++ b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.view; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.util.AttributeSet; import android.view.View; import androidx.appcompat.view.ContextThemeWrapper; @@ -39,6 +40,14 @@ public class EpisodeItemListRecyclerView extends RecyclerView { setLayoutManager(layoutManager); setHasFixedSize(true); addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext()).build()); + setClipToPadding(false); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing); + setPadding(horizontalSpacing, getPaddingTop(), horizontalSpacing, getPaddingBottom()); } public void saveScrollPosition(String tag) { diff --git a/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java b/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java new file mode 100644 index 000000000..4a1267d81 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java @@ -0,0 +1,24 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.graphics.Rect; +import android.view.View; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +/** + * Source: https://stackoverflow.com/a/30794046 + */ +public class ItemOffsetDecoration extends RecyclerView.ItemDecoration { + private final int itemOffset; + + public ItemOffsetDecoration(@NonNull Context context, int itemOffsetDp) { + itemOffset = (int) (itemOffsetDp * context.getResources().getDisplayMetrics().density); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + outRect.set(itemOffset, itemOffset, itemOffset, itemOffset); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java b/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java index a4daa9109..0e1846f1c 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java +++ b/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java @@ -54,7 +54,7 @@ class NestedScrollableHost extends FrameLayout { touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } - private int touchSlop = 0; + private int touchSlop; private float initialX = 0f; private float initialY = 0f; diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java new file mode 100644 index 000000000..47797e4a4 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java @@ -0,0 +1,86 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.SeekBar; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.util.Consumer; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.VariableSpeedDialog; + +public class PlaybackSpeedSeekBar extends FrameLayout { + private SeekBar seekBar; + private PlaybackController controller; + private Consumer<Float> progressChangedListener; + + public PlaybackSpeedSeekBar(@NonNull Context context) { + super(context); + setup(); + } + + public PlaybackSpeedSeekBar(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + setup(); + } + + public PlaybackSpeedSeekBar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setup(); + } + + private void setup() { + View.inflate(getContext(), R.layout.playback_speed_seek_bar, this); + seekBar = findViewById(R.id.playback_speed); + findViewById(R.id.butDecSpeed).setOnClickListener(v -> seekBar.setProgress(seekBar.getProgress() - 2)); + findViewById(R.id.butIncSpeed).setOnClickListener(v -> seekBar.setProgress(seekBar.getProgress() + 2)); + + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (controller != null && controller.canSetPlaybackSpeed()) { + float playbackSpeed = (progress + 10) / 20.0f; + controller.setPlaybackSpeed(playbackSpeed); + + if (progressChangedListener != null) { + progressChangedListener.accept(playbackSpeed); + } + } else if (fromUser) { + seekBar.post(() -> updateSpeed()); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + if (controller != null && !controller.canSetPlaybackSpeed()) { + VariableSpeedDialog.showGetPluginDialog(getContext()); + } + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + } + + public void updateSpeed() { + if (controller != null) { + seekBar.setProgress(Math.round((20 * controller.getCurrentPlaybackSpeedMultiplier()) - 10)); + } + } + + public void setController(PlaybackController controller) { + this.controller = controller; + updateSpeed(); + if (progressChangedListener != null && controller != null) { + progressChangedListener.accept(controller.getCurrentPlaybackSpeedMultiplier()); + } + } + + public void setProgressChangedListener(Consumer<Float> progressChangedListener) { + this.progressChangedListener = progressChangedListener; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java b/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java new file mode 100644 index 000000000..ee5e7c51d --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java @@ -0,0 +1,67 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import java.util.ArrayList; + +/** + * An alternative to {@link android.widget.RadioGroup} that allows to nest children. + * Basend on https://stackoverflow.com/a/14309274. + */ +public class RecursiveRadioGroup extends LinearLayout { + private final ArrayList<RadioButton> radioButtons = new ArrayList<>(); + private RadioButton checkedButton = null; + + public RecursiveRadioGroup(Context context) { + super(context); + } + + public RecursiveRadioGroup(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RecursiveRadioGroup(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + super.addView(child, index, params); + parseChild(child); + } + + public void parseChild(final View child) { + if (child instanceof RadioButton) { + RadioButton button = (RadioButton) child; + radioButtons.add(button); + button.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (!isChecked) { + return; + } + checkedButton = (RadioButton) buttonView; + + for (RadioButton view : radioButtons) { + if (view != buttonView) { + view.setChecked(false); + } + } + }); + } else if (child instanceof ViewGroup) { + parseChildren((ViewGroup) child); + } + } + + public void parseChildren(final ViewGroup child) { + for (int i = 0; i < child.getChildCount(); i++) { + parseChild(child.getChildAt(i)); + } + } + + public RadioButton getCheckedButton() { + return checkedButton; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java index 99c8900ba..9355c0c15 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java +++ b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java @@ -68,7 +68,7 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (Timeline.isTimecodeLink(url) && timecodeSelectedListener != null) { - timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(selectedUrl)); + timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(url)); } else { IntentUtils.openInBrowser(getContext(), url); } diff --git a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java b/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java index dcf8ff20d..163100fff 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java +++ b/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java @@ -33,11 +33,15 @@ public abstract class ToolbarIconTintManager implements AppBarLayout.OnOffsetCha public void updateTint() { if (isTinted) { doTint(new ContextThemeWrapper(context, R.style.Theme_AntennaPod_Dark)); - toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP); + if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon + toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP); + } toolbar.getOverflowIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP); } else { doTint(context); - toolbar.getNavigationIcon().clearColorFilter(); + if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon + toolbar.getNavigationIcon().clearColorFilter(); + } toolbar.getOverflowIcon().clearColorFilter(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java index b7e1728b5..902e5094b 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java +++ b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java @@ -39,7 +39,7 @@ import de.danoeh.antennapod.view.CircularProgressBar; public class EpisodeItemViewHolder extends RecyclerView.ViewHolder { private static final String TAG = "EpisodeItemViewHolder"; - private final View container; + public final View container; public final ImageView dragHandle; private final TextView placeholder; private final ImageView cover; @@ -102,7 +102,7 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder { isNew.setVisibility(item.isNew() ? View.VISIBLE : View.GONE); isFavorite.setVisibility(item.isTagged(FeedItem.TAG_FAVORITE) ? View.VISIBLE : View.GONE); isInQueue.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE); - itemView.setAlpha(item.isPlayed() ? 0.6f : 1.0f); + itemView.setAlpha(item.isPlayed() ? 0.5f : 1.0f); ItemActionButton actionButton = ItemActionButton.forItem(item, true, true); actionButton.configure(secondaryActionButton, secondaryActionIcon, activity); |