Merge pull request #3827 from ByteHamster/extract-queue-item-view
Rewrite list item display
|
@ -228,7 +228,7 @@ public class PlaybackTest {
|
|||
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10);
|
||||
Matcher<View> allEpisodesMatcher = allOf(withId(android.R.id.list), isDisplayed(), hasMinimumChildCount(2));
|
||||
onView(isRoot()).perform(waitForView(allEpisodesMatcher, 1000));
|
||||
onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction)));
|
||||
onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.secondaryActionButton)));
|
||||
|
||||
FeedMedia media = episodes.get(0).getMedia();
|
||||
Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
|
||||
|
@ -244,7 +244,7 @@ public class PlaybackTest {
|
|||
|
||||
Matcher<View> queueMatcher = allOf(withId(R.id.recyclerView), isDisplayed(), hasMinimumChildCount(2));
|
||||
onView(isRoot()).perform(waitForView(queueMatcher, 1000));
|
||||
onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction)));
|
||||
onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.secondaryActionButton)));
|
||||
|
||||
FeedMedia media = queue.get(itemIdx).getMedia();
|
||||
Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for adapters
|
||||
*/
|
||||
class AdapterUtils {
|
||||
|
||||
private static final String TAG = AdapterUtils.class.getSimpleName();
|
||||
|
||||
private AdapterUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the contents of the TextView that shows the current playback position and the ProgressBar.
|
||||
*/
|
||||
static void updateEpisodePlaybackProgress(FeedItem item, TextView txtvPos, ProgressBar episodeProgress) {
|
||||
FeedMedia media = item.getMedia();
|
||||
episodeProgress.setVisibility(View.GONE);
|
||||
if (media == null) {
|
||||
txtvPos.setVisibility(View.GONE);
|
||||
return;
|
||||
} else {
|
||||
txtvPos.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
FeedItem.State state = item.getState();
|
||||
if (state == FeedItem.State.PLAYING
|
||||
|| state == FeedItem.State.IN_PROGRESS) {
|
||||
if (media.getDuration() > 0) {
|
||||
episodeProgress.setVisibility(View.VISIBLE);
|
||||
episodeProgress.setProgress((int) (((double) media
|
||||
.getPosition()) / media.getDuration() * 100));
|
||||
txtvPos.setText(Converter.getDurationStringLong(media.getDuration()
|
||||
- media.getPosition()));
|
||||
}
|
||||
} else if (!media.isDownloaded()) {
|
||||
if (media.getSize() > 0) {
|
||||
txtvPos.setText(Converter.byteToString(media.getSize()));
|
||||
} else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
|
||||
txtvPos.setText("{fa-spinner}");
|
||||
Iconify.addIcons(txtvPos);
|
||||
NetworkUtils.getFeedMediaSizeObservable(media)
|
||||
.subscribe(
|
||||
size -> {
|
||||
if (size > 0) {
|
||||
txtvPos.setText(Converter.byteToString(size));
|
||||
} else {
|
||||
txtvPos.setText("");
|
||||
}
|
||||
}, error -> {
|
||||
txtvPos.setText("");
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
});
|
||||
} else {
|
||||
txtvPos.setText("");
|
||||
}
|
||||
} else {
|
||||
txtvPos.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,204 +1,73 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.os.Build;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import android.text.Layout;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.fragment.ItemFragment;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.fragment.ItemPagerFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* List adapter for the list of new episodes
|
||||
* List adapter for the list of new episodes.
|
||||
*/
|
||||
public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesRecycleAdapter.Holder> {
|
||||
|
||||
private static final String TAG = AllEpisodesRecycleAdapter.class.getSimpleName();
|
||||
public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<EpisodeItemViewHolder>
|
||||
implements View.OnCreateContextMenuListener {
|
||||
|
||||
private final WeakReference<MainActivity> mainActivityRef;
|
||||
private final ItemAccess itemAccess;
|
||||
private final boolean showOnlyNewEpisodes;
|
||||
private List<FeedItem> episodes = new ArrayList<>();
|
||||
|
||||
private FeedItem selectedItem;
|
||||
|
||||
private final int playingBackGroundColor;
|
||||
private final int normalBackGroundColor;
|
||||
|
||||
public AllEpisodesRecycleAdapter(MainActivity mainActivity,
|
||||
ItemAccess itemAccess,
|
||||
boolean showOnlyNewEpisodes) {
|
||||
public AllEpisodesRecycleAdapter(MainActivity mainActivity) {
|
||||
super();
|
||||
this.mainActivityRef = new WeakReference<>(mainActivity);
|
||||
this.itemAccess = itemAccess;
|
||||
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
|
||||
}
|
||||
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||
public void updateItems(List<FeedItem> items) {
|
||||
episodes = items;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public EpisodeItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
EpisodeItemViewHolder viewHolder = new EpisodeItemViewHolder(mainActivityRef.get(), parent);
|
||||
viewHolder.dragHandle.setVisibility(View.GONE);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.new_episodes_listitem, parent, false);
|
||||
Holder holder = new Holder(view);
|
||||
holder.container = view.findViewById(R.id.container);
|
||||
holder.content = view.findViewById(R.id.content);
|
||||
holder.placeholder = view.findViewById(R.id.txtvPlaceholder);
|
||||
holder.title = view.findViewById(R.id.txtvTitle);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
holder.pubDate = view
|
||||
.findViewById(R.id.txtvPublished);
|
||||
holder.statusUnread = view.findViewById(R.id.statusUnread);
|
||||
holder.butSecondary = view
|
||||
.findViewById(R.id.butSecondaryAction);
|
||||
holder.queueStatus = view
|
||||
.findViewById(R.id.imgvInPlaylist);
|
||||
holder.progress = view
|
||||
.findViewById(R.id.pbar_progress);
|
||||
holder.cover = view.findViewById(R.id.imgvCover);
|
||||
holder.txtvDuration = view.findViewById(R.id.txtvDuration);
|
||||
holder.item = null;
|
||||
holder.mainActivityRef = mainActivityRef;
|
||||
// so we can grab this later
|
||||
view.setTag(holder);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final Holder holder, int position) {
|
||||
final FeedItem item = itemAccess.getItem(position);
|
||||
if (item == null) return;
|
||||
public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) {
|
||||
FeedItem item = episodes.get(pos);
|
||||
holder.bind(item);
|
||||
holder.itemView.setOnLongClickListener(v -> {
|
||||
this.selectedItem = item;
|
||||
selectedItem = item;
|
||||
return false;
|
||||
});
|
||||
holder.item = item;
|
||||
holder.placeholder.setVisibility(View.VISIBLE);
|
||||
holder.placeholder.setText(item.getFeed().getTitle());
|
||||
holder.title.setText(item.getTitle());
|
||||
String pubDateStr = DateUtils.formatAbbrev(mainActivityRef.get(), item.getPubDate());
|
||||
holder.pubDate.setText(pubDateStr);
|
||||
if (showOnlyNewEpisodes || !item.isNew()) {
|
||||
holder.statusUnread.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
holder.statusUnread.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if(item.isPlayed()) {
|
||||
holder.content.setAlpha(0.5f);
|
||||
} else {
|
||||
holder.content.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
FeedMedia media = item.getMedia();
|
||||
if (media != null) {
|
||||
final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
|
||||
|
||||
if (media.getDuration() > 0) {
|
||||
holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
} else if (media.getSize() > 0) {
|
||||
holder.txtvDuration.setText(Converter.byteToString(media.getSize()));
|
||||
} else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
|
||||
holder.txtvDuration.setText("{fa-spinner}");
|
||||
Iconify.addIcons(holder.txtvDuration);
|
||||
NetworkUtils.getFeedMediaSizeObservable(media)
|
||||
.subscribe(
|
||||
size -> {
|
||||
if (size > 0) {
|
||||
holder.txtvDuration.setText(Converter.byteToString(size));
|
||||
} else {
|
||||
holder.txtvDuration.setText("");
|
||||
}
|
||||
}, error -> {
|
||||
holder.txtvDuration.setText("");
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
});
|
||||
} else {
|
||||
holder.txtvDuration.setText("");
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
MainActivity activity = mainActivityRef.get();
|
||||
if (activity != null) {
|
||||
long[] ids = FeedItemUtil.getIds(episodes);
|
||||
int position = ArrayUtils.indexOf(ids, item.getId());
|
||||
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
|
||||
}
|
||||
|
||||
FeedItem.State state = item.getState();
|
||||
if (isDownloadingMedia) {
|
||||
holder.progress.setVisibility(View.VISIBLE);
|
||||
// item is being downloaded
|
||||
holder.progress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
|
||||
} else if (state == FeedItem.State.PLAYING
|
||||
|| state == FeedItem.State.IN_PROGRESS) {
|
||||
if (media.getDuration() > 0) {
|
||||
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
|
||||
holder.progress.setProgress(progress);
|
||||
holder.progress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
holder.progress.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
if (media.isCurrentlyPlaying()) {
|
||||
holder.container.setBackgroundColor(playingBackGroundColor);
|
||||
} else {
|
||||
holder.container.setBackgroundColor(normalBackGroundColor);
|
||||
}
|
||||
} else {
|
||||
holder.progress.setVisibility(View.INVISIBLE);
|
||||
holder.txtvDuration.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
boolean isInQueue = itemAccess.isInQueue(item);
|
||||
if (isInQueue) {
|
||||
holder.queueStatus.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.queueStatus.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
ItemActionButton actionButton = ItemActionButton.forItem(item, isInQueue, true);
|
||||
actionButton.configure(holder.butSecondary, mainActivityRef.get());
|
||||
|
||||
holder.butSecondary.setFocusable(false);
|
||||
holder.butSecondary.setTag(item);
|
||||
|
||||
new CoverLoader(mainActivityRef.get())
|
||||
.withUri(ImageResourceUtils.getImageLocation(item))
|
||||
.withFallbackUri(item.getFeed().getImageLocation())
|
||||
.withPlaceholderView(holder.placeholder)
|
||||
.withCoverView(holder.cover)
|
||||
.load();
|
||||
});
|
||||
holder.itemView.setOnCreateContextMenuListener(this);
|
||||
holder.hideSeparatorIfNecessary();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -208,98 +77,21 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
FeedItem item = itemAccess.getItem(position);
|
||||
FeedItem item = episodes.get(position);
|
||||
return item != null ? item.getId() : RecyclerView.NO_POSITION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return itemAccess.getCount();
|
||||
return episodes.size();
|
||||
}
|
||||
|
||||
public class Holder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener,
|
||||
View.OnCreateContextMenuListener,
|
||||
ItemTouchHelperViewHolder {
|
||||
LinearLayout content;
|
||||
FrameLayout container;
|
||||
TextView placeholder;
|
||||
TextView title;
|
||||
TextView pubDate;
|
||||
View statusUnread;
|
||||
ImageView queueStatus;
|
||||
ImageView cover;
|
||||
ProgressBar progress;
|
||||
TextView txtvDuration;
|
||||
ImageButton butSecondary;
|
||||
FeedItem item;
|
||||
WeakReference<MainActivity> mainActivityRef;
|
||||
|
||||
public Holder(View itemView) {
|
||||
super(itemView);
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnCreateContextMenuListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MainActivity mainActivity = mainActivityRef.get();
|
||||
if (mainActivity != null) {
|
||||
LongList itemIds = itemAccess.getItemsIds();
|
||||
long[] ids = itemIds.toArray();
|
||||
mainActivity.loadChildFragment(ItemPagerFragment.newInstance(ids, itemIds.indexOf(item.getId())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected() {
|
||||
itemView.setAlpha(0.5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClear() {
|
||||
itemView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
public FeedItem getFeedItem() { return item; }
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
FeedItem item = itemAccess.getItem(getAdapterPosition());
|
||||
|
||||
MenuInflater inflater = mainActivityRef.get().getMenuInflater();
|
||||
inflater.inflate(R.menu.feeditemlist_context, menu);
|
||||
|
||||
if (item != null) {
|
||||
menu.setHeaderTitle(item.getTitle());
|
||||
}
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
}
|
||||
|
||||
public boolean isCurrentlyPlayingItem() {
|
||||
return item.getMedia() != null && item.getMedia().isCurrentlyPlaying();
|
||||
}
|
||||
|
||||
public void notifyPlaybackPositionUpdated(PlaybackPositionEvent event) {
|
||||
progress.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
|
||||
int getCount();
|
||||
|
||||
FeedItem getItem(int position);
|
||||
|
||||
LongList getItemsIds();
|
||||
|
||||
int getItemDownloadProgressPercent(FeedItem item);
|
||||
|
||||
boolean isInQueue(FeedItem item);
|
||||
|
||||
LongList getQueueIds();
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
MenuInflater inflater = mainActivityRef.get().getMenuInflater();
|
||||
inflater.inflate(R.menu.feeditemlist_context, menu);
|
||||
menu.setHeaderTitle(selectedItem.getTitle());
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, selectedItem, R.id.skip_episode_item);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,36 +1,26 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.text.Layout;
|
||||
import android.text.Selection;
|
||||
import android.text.Spannable;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.util.ChapterUtils;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
|
||||
public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
||||
|
||||
private static final String TAG = "ChapterListAdapter";
|
||||
|
||||
private Playable media;
|
||||
|
||||
private int defaultTextColor;
|
||||
private final Callback callback;
|
||||
private int currentChapterIndex = -1;
|
||||
|
||||
|
@ -59,11 +49,11 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||
convertView = inflater.inflate(R.layout.simplechapter_item, parent, false);
|
||||
holder.view = convertView;
|
||||
holder.title = convertView.findViewById(R.id.txtvTitle);
|
||||
defaultTextColor = holder.title.getTextColors().getDefaultColor();
|
||||
holder.start = convertView.findViewById(R.id.txtvStart);
|
||||
holder.link = convertView.findViewById(R.id.txtvLink);
|
||||
holder.duration = convertView.findViewById(R.id.txtvDuration);
|
||||
holder.butPlayChapter = convertView.findViewById(R.id.butPlayChapter);
|
||||
holder.secondaryActionButton = convertView.findViewById(R.id.secondaryActionButton);
|
||||
holder.secondaryActionIcon = convertView.findViewById(R.id.secondaryActionIcon);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
|
@ -83,60 +73,15 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||
holder.duration.setText(getContext().getString(R.string.chapter_duration,
|
||||
Converter.getDurationStringLong((int) duration)));
|
||||
|
||||
if (sc.getLink() != null) {
|
||||
if (sc.getLink() == null) {
|
||||
holder.link.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.link.setVisibility(View.VISIBLE);
|
||||
holder.link.setText(sc.getLink());
|
||||
Linkify.addLinks(holder.link, Linkify.WEB_URLS);
|
||||
} else {
|
||||
holder.link.setVisibility(View.GONE);
|
||||
holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), sc.getLink()));
|
||||
}
|
||||
holder.link.setMovementMethod(null);
|
||||
holder.link.setOnTouchListener((v, event) -> {
|
||||
// from
|
||||
// http://stackoverflow.com/questions/7236840/android-textview-linkify-intercepts-with-parent-view-gestures
|
||||
TextView widget = (TextView) v;
|
||||
Object text = widget.getText();
|
||||
if (text instanceof Spanned) {
|
||||
Spannable buffer = (Spannable) text;
|
||||
|
||||
int action = event.getAction();
|
||||
|
||||
if (action == MotionEvent.ACTION_UP
|
||||
|| action == MotionEvent.ACTION_DOWN) {
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
|
||||
x -= widget.getTotalPaddingLeft();
|
||||
y -= widget.getTotalPaddingTop();
|
||||
|
||||
x += widget.getScrollX();
|
||||
y += widget.getScrollY();
|
||||
|
||||
Layout layout = widget.getLayout();
|
||||
int line = layout.getLineForVertical(y);
|
||||
int off = layout.getOffsetForHorizontal(line, x);
|
||||
|
||||
ClickableSpan[] link = buffer.getSpans(off, off,
|
||||
ClickableSpan.class);
|
||||
|
||||
if (link.length != 0) {
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
link[0].onClick(widget);
|
||||
} else if (action == MotionEvent.ACTION_DOWN) {
|
||||
Selection.setSelection(buffer,
|
||||
buffer.getSpanStart(link[0]),
|
||||
buffer.getSpanEnd(link[0]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
holder.butPlayChapter.setOnClickListener(v -> {
|
||||
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(getContext(), R.attr.av_play));
|
||||
holder.secondaryActionButton.setOnClickListener(v -> {
|
||||
if (callback != null) {
|
||||
callback.onPlayChapterButtonClicked(position);
|
||||
}
|
||||
|
@ -147,8 +92,6 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||
holder.view.setBackgroundColor(playingBackGroundColor);
|
||||
} else {
|
||||
holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
|
||||
holder.title.setTextColor(defaultTextColor);
|
||||
holder.start.setTextColor(defaultTextColor);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
@ -160,7 +103,8 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||
TextView start;
|
||||
TextView link;
|
||||
TextView duration;
|
||||
ImageButton butPlayChapter;
|
||||
View secondaryActionButton;
|
||||
ImageView secondaryActionIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,171 +26,139 @@ import de.danoeh.antennapod.core.storage.DBReader;
|
|||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.viewholder.DownloadItemViewHolder;
|
||||
import de.danoeh.antennapod.view.viewholder.FeedViewHolder;
|
||||
|
||||
/** Displays a list of DownloadStatus entries. */
|
||||
/**
|
||||
* Displays a list of DownloadStatus entries.
|
||||
*/
|
||||
public class DownloadLogAdapter extends BaseAdapter {
|
||||
private static final String TAG = "DownloadLogAdapter";
|
||||
|
||||
private static final String TAG = "DownloadLogAdapter";
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final Context context;
|
||||
private final ItemAccess itemAccess;
|
||||
|
||||
public DownloadLogAdapter(Context context, ItemAccess itemAccess) {
|
||||
super();
|
||||
public DownloadLogAdapter(Context context, ItemAccess itemAccess) {
|
||||
super();
|
||||
this.itemAccess = itemAccess;
|
||||
this.context = context;
|
||||
}
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
DownloadStatus status = getItem(position);
|
||||
if (convertView == null) {
|
||||
holder = new Holder();
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.downloadlog_item, parent, false);
|
||||
holder.icon = convertView.findViewById(R.id.txtvIcon);
|
||||
holder.retry = convertView.findViewById(R.id.btnRetry);
|
||||
holder.date = convertView.findViewById(R.id.txtvDate);
|
||||
holder.title = convertView.findViewById(R.id.txtvTitle);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
holder.type = convertView.findViewById(R.id.txtvType);
|
||||
holder.reason = convertView.findViewById(R.id.txtvReason);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
|
||||
holder.type.setText(R.string.download_type_feed);
|
||||
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
holder.type.setText(R.string.download_type_media);
|
||||
}
|
||||
if (status.getTitle() != null) {
|
||||
holder.title.setText(status.getTitle());
|
||||
} else {
|
||||
holder.title.setText(R.string.download_log_title_unknown);
|
||||
}
|
||||
holder.date.setText(DateUtils.getRelativeTimeSpanString(
|
||||
status.getCompletionDate().getTime(),
|
||||
System.currentTimeMillis(), 0, 0));
|
||||
if (status.isSuccessful()) {
|
||||
holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(),
|
||||
R.color.download_success_green));
|
||||
holder.icon.setText("{fa-check-circle}");
|
||||
holder.retry.setVisibility(View.GONE);
|
||||
holder.reason.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(),
|
||||
R.color.download_failed_red));
|
||||
holder.icon.setText("{fa-times-circle}");
|
||||
String reasonText = status.getReason().getErrorString(context);
|
||||
if (status.getReasonDetailed() != null) {
|
||||
reasonText += ": " + status.getReasonDetailed();
|
||||
}
|
||||
holder.reason.setText(reasonText);
|
||||
holder.reason.setVisibility(View.VISIBLE);
|
||||
if(!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||
holder.retry.setVisibility(View.VISIBLE);
|
||||
holder.retry.setOnClickListener(clickListener);
|
||||
ButtonHolder btnHolder;
|
||||
if(holder.retry.getTag() != null) {
|
||||
btnHolder = (ButtonHolder) holder.retry.getTag();
|
||||
} else {
|
||||
btnHolder = new ButtonHolder();
|
||||
}
|
||||
btnHolder.typeId = status.getFeedfileType();
|
||||
btnHolder.id = status.getFeedfileId();
|
||||
holder.retry.setTag(btnHolder);
|
||||
} else {
|
||||
holder.retry.setVisibility(View.GONE);
|
||||
holder.retry.setOnClickListener(null);
|
||||
holder.retry.setTag(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
DownloadItemViewHolder holder;
|
||||
if (convertView == null) {
|
||||
holder = new DownloadItemViewHolder(context, parent);
|
||||
} else {
|
||||
holder = (DownloadItemViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
DownloadStatus status = getItem(position);
|
||||
if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
|
||||
holder.type.setText(R.string.download_type_feed);
|
||||
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
holder.type.setText(R.string.download_type_media);
|
||||
}
|
||||
|
||||
private final View.OnClickListener clickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ButtonHolder holder = (ButtonHolder) v.getTag();
|
||||
if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
|
||||
Feed feed = DBReader.getFeed(holder.id);
|
||||
if (feed != null) {
|
||||
try {
|
||||
DBTasks.forceRefreshFeed(context, feed);
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Log.wtf(TAG, "Could not find feed for feed id: " + holder.id);
|
||||
}
|
||||
} else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
FeedMedia media = DBReader.getFeedMedia(holder.id);
|
||||
if (media != null) {
|
||||
try {
|
||||
DownloadRequester.getInstance().downloadMedia(context, media.getItem());
|
||||
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
Log.wtf(TAG, "Could not find media for id: " + holder.id);
|
||||
}
|
||||
} else {
|
||||
Log.wtf(TAG, "Unexpected type id: " + holder.typeId);
|
||||
}
|
||||
v.setVisibility(View.GONE);
|
||||
}
|
||||
};
|
||||
if (status.getTitle() != null) {
|
||||
holder.title.setText(status.getTitle());
|
||||
} else {
|
||||
holder.title.setText(R.string.download_log_title_unknown);
|
||||
}
|
||||
holder.date.setText(DateUtils.getRelativeTimeSpanString(status.getCompletionDate().getTime(),
|
||||
System.currentTimeMillis(), 0, 0));
|
||||
|
||||
private boolean newerWasSuccessful(int position, int feedTypeId, long id) {
|
||||
for (int i = 0; i < position; i++) {
|
||||
DownloadStatus status = getItem(i);
|
||||
if (status.getFeedfileType() == feedTypeId && status.getFeedfileId() == id &&
|
||||
status.isSuccessful()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (status.isSuccessful()) {
|
||||
holder.icon.setTextColor(ContextCompat.getColor(context, R.color.download_success_green));
|
||||
holder.icon.setText("{fa-check-circle}");
|
||||
holder.secondaryActionButton.setVisibility(View.INVISIBLE);
|
||||
holder.reason.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.icon.setTextColor(ContextCompat.getColor(context, R.color.download_failed_red));
|
||||
holder.icon.setText("{fa-times-circle}");
|
||||
String reasonText = status.getReason().getErrorString(context);
|
||||
if (status.getReasonDetailed() != null) {
|
||||
reasonText += ": " + status.getReasonDetailed();
|
||||
}
|
||||
holder.reason.setText(reasonText);
|
||||
holder.reason.setVisibility(View.VISIBLE);
|
||||
|
||||
static class Holder {
|
||||
IconTextView icon;
|
||||
IconButton retry;
|
||||
TextView title;
|
||||
TextView type;
|
||||
TextView date;
|
||||
TextView reason;
|
||||
}
|
||||
if (newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||
holder.secondaryActionButton.setVisibility(View.INVISIBLE);
|
||||
holder.secondaryActionButton.setOnClickListener(null);
|
||||
holder.secondaryActionButton.setTag(null);
|
||||
} else {
|
||||
holder.secondaryActionIcon.setImageResource(
|
||||
ThemeUtils.getDrawableFromAttr(context, R.attr.navigation_refresh));
|
||||
holder.secondaryActionButton.setVisibility(View.VISIBLE);
|
||||
|
||||
static class ButtonHolder {
|
||||
int typeId;
|
||||
long id;
|
||||
}
|
||||
if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
|
||||
holder.secondaryActionButton.setOnClickListener(v -> {
|
||||
holder.secondaryActionButton.setVisibility(View.INVISIBLE);
|
||||
Feed feed = DBReader.getFeed(status.getFeedfileId());
|
||||
if (feed == null) {
|
||||
Log.e(TAG, "Could not find feed for feed id: " + status.getFeedfileId());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
DBTasks.forceRefreshFeed(context, feed);
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
holder.secondaryActionButton.setOnClickListener(v -> {
|
||||
holder.secondaryActionButton.setVisibility(View.INVISIBLE);
|
||||
FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId());
|
||||
if (media == null) {
|
||||
Log.e(TAG, "Could not find feed media for feed id: " + status.getFeedfileId());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
DownloadRequester.getInstance().downloadMedia(context, media.getItem());
|
||||
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return holder.itemView;
|
||||
}
|
||||
|
||||
private boolean newerWasSuccessful(int position, int feedTypeId, long id) {
|
||||
for (int i = 0; i < position; i++) {
|
||||
DownloadStatus status = getItem(i);
|
||||
if (status.getFeedfileType() == feedTypeId && status.getFeedfileId() == id && status.isSuccessful()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return itemAccess.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadStatus getItem(int position) {
|
||||
@Override
|
||||
public DownloadStatus getItem(int position) {
|
||||
return itemAccess.getItem(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
int getCount();
|
||||
DownloadStatus getItem(int position);
|
||||
int getCount();
|
||||
|
||||
DownloadStatus getItem(int position);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,37 +1,25 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
|
||||
/**
|
||||
* Shows a list of downloaded episodes
|
||||
* Shows a list of downloaded episodes.
|
||||
*/
|
||||
public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
||||
|
||||
private final Context context;
|
||||
private final MainActivity activity;
|
||||
private final ItemAccess itemAccess;
|
||||
|
||||
public DownloadedEpisodesListAdapter(Context context, ItemAccess itemAccess) {
|
||||
public DownloadedEpisodesListAdapter(MainActivity activity, ItemAccess itemAccess) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.activity = activity;
|
||||
this.itemAccess = itemAccess;
|
||||
}
|
||||
|
||||
|
@ -52,77 +40,21 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
|||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
final FeedItem item = getItem(position);
|
||||
if (item == null) return null;
|
||||
|
||||
EpisodeItemViewHolder holder;
|
||||
if (convertView == null) {
|
||||
holder = new Holder();
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.downloaded_episodeslist_item,
|
||||
parent, false);
|
||||
holder.imageView = convertView.findViewById(R.id.imgvImage);
|
||||
holder.title = convertView.findViewById(R.id.txtvTitle);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
holder.txtvSize = convertView.findViewById(R.id.txtvSize);
|
||||
holder.queueStatus = convertView.findViewById(R.id.imgvInPlaylist);
|
||||
holder.pubDate = convertView
|
||||
.findViewById(R.id.txtvPublished);
|
||||
holder.butSecondary = convertView
|
||||
.findViewById(R.id.butSecondaryAction);
|
||||
convertView.setTag(holder);
|
||||
holder = new EpisodeItemViewHolder(activity, parent);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
holder = (EpisodeItemViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
Glide.with(context)
|
||||
.load(ImageResourceUtils.getImageLocation(item))
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(holder.imageView);
|
||||
final FeedItem item = getItem(position);
|
||||
holder.bind(item);
|
||||
holder.dragHandle.setVisibility(View.GONE);
|
||||
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(activity, R.attr.content_discard));
|
||||
holder.secondaryActionButton.setOnClickListener(v -> itemAccess.onFeedItemSecondaryAction(item));
|
||||
holder.hideSeparatorIfNecessary();
|
||||
|
||||
if(item.isPlayed()) {
|
||||
convertView.setAlpha(0.5f);
|
||||
} else {
|
||||
convertView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
holder.title.setText(item.getTitle());
|
||||
holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize()));
|
||||
holder.queueStatus.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE);
|
||||
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
|
||||
holder.pubDate.setText(pubDateStr);
|
||||
|
||||
holder.butSecondary.setFocusable(false);
|
||||
holder.butSecondary.setTag(item);
|
||||
holder.butSecondary.setOnClickListener(secondaryActionListener);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
FeedItem item = (FeedItem) v.getTag();
|
||||
itemAccess.onFeedItemSecondaryAction(item);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static class Holder {
|
||||
ImageView imageView;
|
||||
TextView title;
|
||||
TextView txtvSize;
|
||||
ImageView queueStatus;
|
||||
TextView pubDate;
|
||||
ImageButton butSecondary;
|
||||
return holder.itemView;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
|
|
|
@ -5,23 +5,25 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.CircularProgressBar;
|
||||
|
||||
public class DownloadlistAdapter extends BaseAdapter {
|
||||
|
||||
private final ItemAccess itemAccess;
|
||||
private final Context context;
|
||||
|
||||
public DownloadlistAdapter(Context context,
|
||||
ItemAccess itemAccess) {
|
||||
public DownloadlistAdapter(Context context, ItemAccess itemAccess) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.itemAccess = itemAccess;
|
||||
|
@ -47,47 +49,44 @@ public class DownloadlistAdapter extends BaseAdapter {
|
|||
Holder holder;
|
||||
Downloader downloader = getItem(position);
|
||||
DownloadRequest request = downloader.getDownloadRequest();
|
||||
// Inflate layout
|
||||
if (convertView == null) {
|
||||
holder = new Holder();
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.downloadlist_item, parent, false);
|
||||
holder.title = convertView.findViewById(R.id.txtvTitle);
|
||||
holder.downloaded = convertView
|
||||
.findViewById(R.id.txtvDownloaded);
|
||||
holder.percent = convertView
|
||||
.findViewById(R.id.txtvPercent);
|
||||
holder.progbar = convertView
|
||||
.findViewById(R.id.progProgress);
|
||||
holder.butSecondary = convertView
|
||||
.findViewById(R.id.butSecondaryAction);
|
||||
|
||||
holder.status = convertView.findViewById(R.id.txtvStatus);
|
||||
holder.secondaryActionButton = convertView.findViewById(R.id.secondaryActionButton);
|
||||
holder.secondaryActionIcon = convertView.findViewById(R.id.secondaryActionIcon);
|
||||
holder.secondaryActionProgress = convertView.findViewById(R.id.secondaryActionProgress);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.title.setText(request.getTitle());
|
||||
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.navigation_cancel));
|
||||
holder.secondaryActionButton.setTag(downloader);
|
||||
holder.secondaryActionButton.setOnClickListener(butSecondaryListener);
|
||||
holder.secondaryActionProgress.setPercentage(0, request);
|
||||
|
||||
holder.progbar.setIndeterminate(request.getSoFar() <= 0);
|
||||
|
||||
String strDownloaded = Converter.byteToString(request.getSoFar());
|
||||
if (request.getSize() != DownloadStatus.SIZE_UNKNOWN) {
|
||||
strDownloaded += " / " + Converter.byteToString(request.getSize());
|
||||
holder.percent.setText(request.getProgressPercent() + "%");
|
||||
holder.progbar.setProgress(request.getProgressPercent());
|
||||
holder.percent.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.progbar.setProgress(0);
|
||||
holder.percent.setVisibility(View.INVISIBLE);
|
||||
String status = "";
|
||||
if (request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
|
||||
status += context.getString(R.string.download_type_feed);
|
||||
} else if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
status += context.getString(R.string.download_type_media);
|
||||
}
|
||||
|
||||
holder.downloaded.setText(strDownloaded);
|
||||
|
||||
holder.butSecondary.setFocusable(false);
|
||||
holder.butSecondary.setTag(downloader);
|
||||
holder.butSecondary.setOnClickListener(butSecondaryListener);
|
||||
status += " · ";
|
||||
if (request.getSoFar() <= 0) {
|
||||
status += context.getString(R.string.download_queued);
|
||||
} else {
|
||||
status += Converter.byteToString(request.getSoFar());
|
||||
if (request.getSize() != DownloadStatus.SIZE_UNKNOWN) {
|
||||
status += " / " + Converter.byteToString(request.getSize());
|
||||
holder.secondaryActionProgress.setPercentage(
|
||||
0.01f * Math.max(1, request.getProgressPercent()), request);
|
||||
}
|
||||
}
|
||||
holder.status.setText(status);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
@ -102,10 +101,10 @@ public class DownloadlistAdapter extends BaseAdapter {
|
|||
|
||||
static class Holder {
|
||||
TextView title;
|
||||
TextView downloaded;
|
||||
TextView percent;
|
||||
ProgressBar progbar;
|
||||
ImageButton butSecondary;
|
||||
TextView status;
|
||||
View secondaryActionButton;
|
||||
ImageView secondaryActionIcon;
|
||||
CircularProgressBar secondaryActionProgress;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
|
|
|
@ -1,33 +1,17 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Build;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.text.Layout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedComponent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import de.danoeh.antennapod.view.viewholder.FeedComponentViewHolder;
|
||||
import de.danoeh.antennapod.view.viewholder.FeedViewHolder;
|
||||
|
||||
/**
|
||||
* List adapter for items of feeds that the user has already subscribed to.
|
||||
|
@ -35,27 +19,19 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
|
|||
public class FeedItemlistAdapter extends BaseAdapter {
|
||||
|
||||
private final ItemAccess itemAccess;
|
||||
private final Context context;
|
||||
private final boolean showFeedtitle;
|
||||
/** true if played items should be made partially transparent */
|
||||
private final MainActivity activity;
|
||||
private final boolean makePlayedItemsTransparent;
|
||||
private final int playingBackGroundColor;
|
||||
private final int normalBackGroundColor;
|
||||
private final boolean showIcons;
|
||||
|
||||
private int currentlyPlayingItem = -1;
|
||||
|
||||
public FeedItemlistAdapter(Context context,
|
||||
ItemAccess itemAccess,
|
||||
boolean showFeedtitle,
|
||||
boolean makePlayedItemsTransparent) {
|
||||
public FeedItemlistAdapter(MainActivity activity, ItemAccess itemAccess,
|
||||
boolean showIcons, boolean makePlayedItemsTransparent) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.activity = activity;
|
||||
this.itemAccess = itemAccess;
|
||||
this.showFeedtitle = showFeedtitle;
|
||||
this.showIcons = showIcons;
|
||||
this.makePlayedItemsTransparent = makePlayedItemsTransparent;
|
||||
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,135 +46,56 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
public FeedComponent getItem(int position) {
|
||||
return itemAccess.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ResourceType")
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
final FeedItem item = getItem(position);
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new Holder();
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.feeditemlist_item, parent, false);
|
||||
holder.container = convertView
|
||||
.findViewById(R.id.container);
|
||||
holder.title = convertView.findViewById(R.id.txtvItemname);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
holder.lenSize = convertView
|
||||
.findViewById(R.id.txtvLenSize);
|
||||
holder.butAction = convertView
|
||||
.findViewById(R.id.butSecondaryAction);
|
||||
holder.published = convertView
|
||||
.findViewById(R.id.txtvPublished);
|
||||
holder.inPlaylist = convertView
|
||||
.findViewById(R.id.imgvInPlaylist);
|
||||
holder.type = convertView.findViewById(R.id.imgvType);
|
||||
holder.statusUnread = convertView
|
||||
.findViewById(R.id.statusUnread);
|
||||
holder.episodeProgress = convertView
|
||||
.findViewById(R.id.pbar_episode_progress);
|
||||
|
||||
convertView.setTag(holder);
|
||||
final FeedComponent item = getItem(position);
|
||||
if (item instanceof Feed) {
|
||||
return getView((Feed) item, convertView, parent);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
final FeedItem feeditem = (FeedItem) item;
|
||||
if (feeditem.getMedia() != null && feeditem.getMedia().isCurrentlyPlaying()) {
|
||||
currentlyPlayingItem = position;
|
||||
}
|
||||
return getView(feeditem, convertView, parent);
|
||||
}
|
||||
}
|
||||
|
||||
private View getView(Feed item, View convertView, ViewGroup parent) {
|
||||
FeedViewHolder holder;
|
||||
if (convertView == null || !(convertView.getTag() instanceof FeedViewHolder)) {
|
||||
holder = new FeedViewHolder(activity, parent);
|
||||
} else {
|
||||
holder = (FeedViewHolder) convertView.getTag();
|
||||
}
|
||||
holder.bind(item);
|
||||
return holder.itemView;
|
||||
}
|
||||
|
||||
private View getView(final FeedItem item, View convertView, ViewGroup parent) {
|
||||
EpisodeItemViewHolder holder;
|
||||
if (convertView == null || !(convertView.getTag() instanceof EpisodeItemViewHolder)) {
|
||||
holder = new EpisodeItemViewHolder(activity, parent);
|
||||
} else {
|
||||
holder = (EpisodeItemViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
if (!(getItemViewType(position) == Adapter.IGNORE_ITEM_VIEW_TYPE)) {
|
||||
convertView.setVisibility(View.VISIBLE);
|
||||
|
||||
StringBuilder buffer = new StringBuilder(item.getTitle());
|
||||
if (showFeedtitle) {
|
||||
buffer.append(" (");
|
||||
buffer.append(item.getFeed().getTitle());
|
||||
buffer.append(")");
|
||||
}
|
||||
holder.title.setText(buffer.toString());
|
||||
|
||||
if(item.isNew()) {
|
||||
holder.statusUnread.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.statusUnread.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
if(item.isPlayed() && makePlayedItemsTransparent) {
|
||||
convertView.setAlpha(0.5f);
|
||||
} else {
|
||||
convertView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
|
||||
holder.published.setText(pubDateStr);
|
||||
|
||||
boolean isInQueue = item.isTagged(FeedItem.TAG_QUEUE);
|
||||
|
||||
FeedMedia media = item.getMedia();
|
||||
if (media == null) {
|
||||
holder.episodeProgress.setVisibility(View.INVISIBLE);
|
||||
holder.inPlaylist.setVisibility(View.INVISIBLE);
|
||||
holder.type.setVisibility(View.INVISIBLE);
|
||||
holder.lenSize.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
|
||||
AdapterUtils.updateEpisodePlaybackProgress(item, holder.lenSize, holder.episodeProgress);
|
||||
|
||||
if (isInQueue) {
|
||||
holder.inPlaylist.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.inPlaylist.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
if (DownloadRequester.getInstance().isDownloadingFile(item.getMedia())) {
|
||||
holder.episodeProgress.setVisibility(View.VISIBLE);
|
||||
holder.episodeProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
|
||||
} else {
|
||||
if(media.getPosition() == 0) {
|
||||
holder.episodeProgress.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
TypedArray typeDrawables = context.obtainStyledAttributes(
|
||||
new int[]{R.attr.type_audio, R.attr.type_video});
|
||||
final int[] labels = new int[]{R.string.media_type_audio_label, R.string.media_type_video_label};
|
||||
|
||||
MediaType mediaType = item.getMedia().getMediaType();
|
||||
if (mediaType == MediaType.AUDIO) {
|
||||
holder.type.setImageDrawable(typeDrawables.getDrawable(0));
|
||||
holder.type.setContentDescription(context.getString(labels[0]));
|
||||
holder.type.setVisibility(View.VISIBLE);
|
||||
} else if (mediaType == MediaType.VIDEO) {
|
||||
holder.type.setImageDrawable(typeDrawables.getDrawable(1));
|
||||
holder.type.setContentDescription(context.getString(labels[1]));
|
||||
holder.type.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.type.setImageBitmap(null);
|
||||
holder.type.setVisibility(View.GONE);
|
||||
}
|
||||
typeDrawables.recycle();
|
||||
|
||||
if (media.isCurrentlyPlaying()) {
|
||||
holder.container.setBackgroundColor(playingBackGroundColor);
|
||||
currentlyPlayingItem = position;
|
||||
} else {
|
||||
holder.container.setBackgroundColor(normalBackGroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
ItemActionButton actionButton = ItemActionButton.forItem(item, isInQueue, true);
|
||||
actionButton.configure(holder.butAction, context);
|
||||
|
||||
holder.butAction.setFocusable(false);
|
||||
holder.butAction.setTag(item);
|
||||
|
||||
} else {
|
||||
convertView.setVisibility(View.GONE);
|
||||
if (!showIcons) {
|
||||
holder.coverHolder.setVisibility(View.GONE);
|
||||
}
|
||||
return convertView;
|
||||
|
||||
holder.bind(item);
|
||||
holder.dragHandle.setVisibility(View.GONE);
|
||||
|
||||
if (!makePlayedItemsTransparent) {
|
||||
holder.itemView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
holder.hideSeparatorIfNecessary();
|
||||
return holder.itemView;
|
||||
}
|
||||
|
||||
public void notifyCurrentlyPlayingItemChanged(PlaybackPositionEvent event, ListView listView) {
|
||||
|
@ -208,35 +105,15 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
Holder holder = (Holder) view.getTag();
|
||||
holder.episodeProgress.setVisibility(View.VISIBLE);
|
||||
holder.episodeProgress.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
|
||||
holder.lenSize.setText(Converter.getDurationStringLong(event.getDuration() - event.getPosition()));
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) view.getTag();
|
||||
holder.notifyPlaybackPositionUpdated(event);
|
||||
}
|
||||
}
|
||||
|
||||
static class Holder {
|
||||
LinearLayout container;
|
||||
TextView title;
|
||||
TextView published;
|
||||
TextView lenSize;
|
||||
ImageView type;
|
||||
ImageView inPlaylist;
|
||||
ImageButton butAction;
|
||||
View statusUnread;
|
||||
ProgressBar episodeProgress;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
|
||||
int getItemDownloadProgressPercent(FeedItem item);
|
||||
|
||||
int getCount();
|
||||
|
||||
FeedItem getItem(int position);
|
||||
|
||||
LongList getQueueIds();
|
||||
|
||||
FeedComponent getItem(int position);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,56 +1,34 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.os.Build;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.MotionEventCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import android.text.Layout;
|
||||
import android.text.TextUtils;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.MotionEventCompat;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.fragment.ItemPagerFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
|
||||
/**
|
||||
* List adapter for the queue.
|
||||
*/
|
||||
public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdapter.ViewHolder> {
|
||||
|
||||
private static final String TAG = QueueRecyclerAdapter.class.getSimpleName();
|
||||
public class QueueRecyclerAdapter extends RecyclerView.Adapter<EpisodeItemViewHolder> implements View.OnCreateContextMenuListener {
|
||||
private static final String TAG = "QueueRecyclerAdapter";
|
||||
|
||||
private final WeakReference<MainActivity> mainActivity;
|
||||
private final ItemAccess itemAccess;
|
||||
|
@ -60,9 +38,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
|
||||
private FeedItem selectedItem;
|
||||
|
||||
private final int playingBackGroundColor;
|
||||
private final int normalBackGroundColor;
|
||||
|
||||
public QueueRecyclerAdapter(MainActivity mainActivity,
|
||||
ItemAccess itemAccess,
|
||||
ItemTouchHelper itemTouchHelper) {
|
||||
|
@ -71,9 +46,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
this.itemAccess = itemAccess;
|
||||
this.itemTouchHelper = itemTouchHelper;
|
||||
locked = UserPreferences.isQueueLocked();
|
||||
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
|
@ -81,20 +53,49 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.queue_listitem, parent, false);
|
||||
return new ViewHolder(view);
|
||||
public EpisodeItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new EpisodeItemViewHolder(mainActivity.get(), parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int pos) {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) {
|
||||
FeedItem item = itemAccess.getItem(pos);
|
||||
holder.bind(item);
|
||||
holder.dragHandle.setVisibility(locked ? View.GONE : View.VISIBLE);
|
||||
holder.itemView.setOnLongClickListener(v -> {
|
||||
selectedItem = item;
|
||||
return false;
|
||||
});
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
MainActivity activity = mainActivity.get();
|
||||
if (activity != null) {
|
||||
long[] ids = itemAccess.getQueueIds().toArray();
|
||||
int position = ArrayUtils.indexOf(ids, item.getId());
|
||||
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
|
||||
}
|
||||
});
|
||||
|
||||
View.OnTouchListener startDragTouchListener = (v1, event) -> {
|
||||
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
|
||||
Log.d(TAG, "startDrag()");
|
||||
itemTouchHelper.startDrag(holder);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (!locked) {
|
||||
holder.dragHandle.setOnTouchListener(startDragTouchListener);
|
||||
holder.coverHolder.setOnTouchListener(startDragTouchListener);
|
||||
} else {
|
||||
holder.dragHandle.setOnTouchListener(null);
|
||||
holder.coverHolder.setOnTouchListener(null);
|
||||
}
|
||||
|
||||
holder.itemView.setOnCreateContextMenuListener(this);
|
||||
holder.isInQueue.setVisibility(View.GONE);
|
||||
holder.hideSeparatorIfNecessary();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -112,211 +113,30 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
return itemAccess.getCount();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener,
|
||||
View.OnCreateContextMenuListener,
|
||||
ItemTouchHelperViewHolder {
|
||||
@Override
|
||||
public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
MenuInflater inflater = mainActivity.get().getMenuInflater();
|
||||
inflater.inflate(R.menu.queue_context, menu); // queue-specific menu items
|
||||
inflater.inflate(R.menu.feeditemlist_context, menu); // generic menu items for item feeds
|
||||
|
||||
private final FrameLayout container;
|
||||
private final ImageView dragHandle;
|
||||
private final TextView placeholder;
|
||||
private final ImageView cover;
|
||||
private final TextView title;
|
||||
private final TextView pubDate;
|
||||
private final TextView progressLeft;
|
||||
private final TextView progressRight;
|
||||
private final ProgressBar progressBar;
|
||||
private final ImageButton butSecondary;
|
||||
|
||||
private FeedItem item;
|
||||
|
||||
public ViewHolder(View v) {
|
||||
super(v);
|
||||
container = v.findViewById(R.id.container);
|
||||
dragHandle = v.findViewById(R.id.drag_handle);
|
||||
placeholder = v.findViewById(R.id.txtvPlaceholder);
|
||||
cover = v.findViewById(R.id.imgvCover);
|
||||
title = v.findViewById(R.id.txtvTitle);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
pubDate = v.findViewById(R.id.txtvPubDate);
|
||||
progressLeft = v.findViewById(R.id.txtvProgressLeft);
|
||||
progressRight = v.findViewById(R.id.txtvProgressRight);
|
||||
butSecondary = v.findViewById(R.id.butSecondaryAction);
|
||||
progressBar = v.findViewById(R.id.progressBar);
|
||||
v.setTag(this);
|
||||
v.setOnClickListener(this);
|
||||
v.setOnCreateContextMenuListener(this);
|
||||
dragHandle.setOnTouchListener((v1, event) -> {
|
||||
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
|
||||
Log.d(TAG, "startDrag()");
|
||||
itemTouchHelper.startDrag(ViewHolder.this);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
menu.setHeaderTitle(selectedItem.getTitle());
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, selectedItem, R.id.skip_episode_item);
|
||||
// Queue-specific menu preparation
|
||||
final boolean keepSorted = UserPreferences.isQueueKeepSorted();
|
||||
final LongList queueAccess = itemAccess.getQueueIds();
|
||||
if (queueAccess.size() == 0 || queueAccess.get(0) == selectedItem.getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_top_item).setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MainActivity activity = mainActivity.get();
|
||||
if (activity != null) {
|
||||
long[] ids = itemAccess.getQueueIds().toArray();
|
||||
int position = ArrayUtils.indexOf(ids, item.getId());
|
||||
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
FeedItem item = itemAccess.getItem(getAdapterPosition());
|
||||
|
||||
MenuInflater inflater = mainActivity.get().getMenuInflater();
|
||||
inflater.inflate(R.menu.queue_context, menu); // queue-specific menu items
|
||||
inflater.inflate(R.menu.feeditemlist_context, menu); // generic menu items for item feeds
|
||||
|
||||
if (item != null) {
|
||||
menu.setHeaderTitle(item.getTitle());
|
||||
}
|
||||
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item,
|
||||
R.id.skip_episode_item); // Skip Episode is not useful in Queue, so hide it.
|
||||
// Queue-specific menu preparation
|
||||
final boolean keepSorted = UserPreferences.isQueueKeepSorted();
|
||||
final LongList queueAccess = itemAccess.getQueueIds();
|
||||
if (queueAccess.size() == 0 || queueAccess.get(0) == item.getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_top_item).setVisible(false);
|
||||
}
|
||||
if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size()-1) == item.getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected() {
|
||||
itemView.setAlpha(0.5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClear() {
|
||||
itemView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
public void bind(FeedItem item) {
|
||||
this.item = item;
|
||||
if(locked) {
|
||||
dragHandle.setVisibility(View.GONE);
|
||||
} else {
|
||||
dragHandle.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
placeholder.setText(item.getFeed().getTitle());
|
||||
|
||||
title.setText(item.getTitle());
|
||||
FeedMedia media = item.getMedia();
|
||||
|
||||
title.setText(item.getTitle());
|
||||
String pubDateStr = DateUtils.formatAbbrev(mainActivity.get(), item.getPubDate());
|
||||
int index = 0;
|
||||
if(countMatches(pubDateStr, ' ') == 1 || countMatches(pubDateStr, ' ') == 2) {
|
||||
index = pubDateStr.lastIndexOf(' ');
|
||||
} else if(countMatches(pubDateStr, '.') == 2) {
|
||||
index = pubDateStr.lastIndexOf('.');
|
||||
} else if(countMatches(pubDateStr, '-') == 2) {
|
||||
index = pubDateStr.lastIndexOf('-');
|
||||
} else if(countMatches(pubDateStr, '/') == 2) {
|
||||
index = pubDateStr.lastIndexOf('/');
|
||||
}
|
||||
if(index > 0) {
|
||||
pubDateStr = pubDateStr.substring(0, index+1).trim() + "\n" + pubDateStr.substring(index+1);
|
||||
}
|
||||
pubDate.setText(pubDateStr);
|
||||
|
||||
if (media != null) {
|
||||
final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
|
||||
FeedItem.State state = item.getState();
|
||||
if (isDownloadingMedia) {
|
||||
progressLeft.setText(Converter.byteToString(itemAccess.getItemDownloadedBytes(item)));
|
||||
if(itemAccess.getItemDownloadSize(item) > 0) {
|
||||
progressRight.setText(Converter.byteToString(itemAccess.getItemDownloadSize(item)));
|
||||
} else {
|
||||
progressRight.setText(Converter.byteToString(media.getSize()));
|
||||
}
|
||||
progressBar.setProgress(itemAccess.getItemDownloadProgressPercent(item));
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
} else if (state == FeedItem.State.PLAYING
|
||||
|| state == FeedItem.State.IN_PROGRESS) {
|
||||
if (media.getDuration() > 0) {
|
||||
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
|
||||
progressBar.setProgress(progress);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
progressLeft.setText(Converter
|
||||
.getDurationStringLong(media.getPosition()));
|
||||
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
}
|
||||
} else {
|
||||
if(media.getSize() > 0) {
|
||||
progressLeft.setText(Converter.byteToString(media.getSize()));
|
||||
} else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
|
||||
progressLeft.setText("{fa-spinner}");
|
||||
Iconify.addIcons(progressLeft);
|
||||
NetworkUtils.getFeedMediaSizeObservable(media)
|
||||
.subscribe(
|
||||
size -> {
|
||||
if (size > 0) {
|
||||
progressLeft.setText(Converter.byteToString(size));
|
||||
} else {
|
||||
progressLeft.setText("");
|
||||
}
|
||||
}, error -> {
|
||||
progressLeft.setText("");
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
});
|
||||
} else {
|
||||
progressLeft.setText("");
|
||||
}
|
||||
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
if(media.isCurrentlyPlaying()) {
|
||||
container.setBackgroundColor(playingBackGroundColor);
|
||||
} else {
|
||||
container.setBackgroundColor(normalBackGroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
ItemActionButton actionButton = ItemActionButton.forItem(item, true, true);
|
||||
actionButton.configure(butSecondary, mainActivity.get());
|
||||
|
||||
butSecondary.setFocusable(false);
|
||||
butSecondary.setTag(item);
|
||||
|
||||
new CoverLoader(mainActivity.get())
|
||||
.withUri(ImageResourceUtils.getImageLocation(item))
|
||||
.withFallbackUri(item.getFeed().getImageLocation())
|
||||
.withPlaceholderView(placeholder)
|
||||
.withCoverView(cover)
|
||||
.load();
|
||||
}
|
||||
|
||||
public boolean isCurrentlyPlayingItem() {
|
||||
return item.getMedia() != null && item.getMedia().isCurrentlyPlaying();
|
||||
}
|
||||
|
||||
public void notifyPlaybackPositionUpdated(PlaybackPositionEvent event) {
|
||||
progressBar.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
|
||||
progressLeft.setText(Converter.getDurationStringLong(event.getPosition()));
|
||||
progressRight.setText(Converter.getDurationStringLong(event.getDuration()));
|
||||
if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size() - 1) == selectedItem.getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
FeedItem getItem(int position);
|
||||
|
||||
int getCount();
|
||||
long getItemDownloadedBytes(FeedItem item);
|
||||
long getItemDownloadSize(FeedItem item);
|
||||
int getItemDownloadProgressPercent(FeedItem item);
|
||||
|
||||
LongList getQueueIds();
|
||||
}
|
||||
|
||||
|
@ -341,18 +161,4 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
*/
|
||||
void onItemClear();
|
||||
}
|
||||
|
||||
// Oh Xiaomi, I hate you so much. How did you manage to fuck this up?
|
||||
private static int countMatches(final CharSequence str, final char ch) {
|
||||
if (TextUtils.isEmpty(str)) {
|
||||
return 0;
|
||||
}
|
||||
int count = 0;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (ch == str.charAt(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedComponent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
|
||||
/**
|
||||
* List adapter for search activity.
|
||||
*/
|
||||
public class SearchlistAdapter extends BaseAdapter {
|
||||
|
||||
private final Context context;
|
||||
private final ItemAccess itemAccess;
|
||||
|
||||
|
||||
public SearchlistAdapter(Context context, ItemAccess itemAccess) {
|
||||
this.context = context;
|
||||
this.itemAccess = itemAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return itemAccess.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedComponent getItem(int position) {
|
||||
return itemAccess.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
final Holder holder;
|
||||
FeedComponent component = getItem(position);
|
||||
|
||||
// Inflate Layout
|
||||
if (convertView == null) {
|
||||
holder = new Holder();
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
convertView = inflater.inflate(R.layout.searchlist_item, parent, false);
|
||||
holder.title = convertView.findViewById(R.id.txtvTitle);
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
holder.cover = convertView
|
||||
.findViewById(R.id.imgvFeedimage);
|
||||
holder.subtitle = convertView
|
||||
.findViewById(R.id.txtvSubtitle);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
if (component.getClass() == Feed.class) {
|
||||
final Feed feed = (Feed) component;
|
||||
holder.title.setText(feed.getTitle());
|
||||
holder.subtitle.setVisibility(View.GONE);
|
||||
|
||||
Glide.with(context)
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(holder.cover);
|
||||
|
||||
} else if (component.getClass() == FeedItem.class) {
|
||||
final FeedItem item = (FeedItem) component;
|
||||
holder.title.setText(item.getTitle());
|
||||
holder.subtitle.setVisibility(View.VISIBLE);
|
||||
|
||||
convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f);
|
||||
|
||||
Glide.with(context)
|
||||
.load(item.getFeed().getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(holder.cover);
|
||||
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class Holder {
|
||||
ImageView cover;
|
||||
TextView title;
|
||||
TextView subtitle;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
int getCount();
|
||||
|
||||
FeedComponent getItem(int position);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter.actionbutton;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
|
@ -54,14 +55,13 @@ public abstract class ItemActionButton {
|
|||
}
|
||||
}
|
||||
|
||||
public void configure(@NonNull ImageButton button, Context context) {
|
||||
TypedArray drawables = context.obtainStyledAttributes(new int[]{getDrawable()});
|
||||
|
||||
public void configure(@NonNull View button, @NonNull ImageView icon, Context context) {
|
||||
button.setVisibility(getVisibility());
|
||||
button.setContentDescription(context.getString(getLabel()));
|
||||
button.setImageDrawable(drawables.getDrawable(0));
|
||||
button.setOnClickListener((view) -> onClick(context));
|
||||
|
||||
TypedArray drawables = context.obtainStyledAttributes(new int[]{getDrawable()});
|
||||
icon.setImageDrawable(drawables.getDrawable(0));
|
||||
drawables.recycle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,6 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
|||
feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showOnlyNewEpisodes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPrefName() {
|
||||
return PREF_NAME;
|
||||
|
|
|
@ -52,7 +52,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||
addVerticalPadding();
|
||||
addEmptyView();
|
||||
|
||||
listAdapter = new DownloadedEpisodesListAdapter(getActivity(), itemAccess);
|
||||
listAdapter = new DownloadedEpisodesListAdapter((MainActivity) getActivity(), itemAccess);
|
||||
setListAdapter(listAdapter);
|
||||
setListShown(false);
|
||||
EventBus.getDefault().register(this);
|
||||
|
|
|
@ -28,6 +28,7 @@ import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
|
|||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
@ -43,14 +44,11 @@ import de.danoeh.antennapod.core.event.DownloadEvent;
|
|||
import de.danoeh.antennapod.core.event.DownloaderUpdate;
|
||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
|
@ -82,8 +80,6 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
|
||||
@NonNull
|
||||
List<FeedItem> episodes = new ArrayList<>();
|
||||
@NonNull
|
||||
private List<Downloader> downloaderList = new ArrayList<>();
|
||||
|
||||
private boolean isUpdatingFeeds;
|
||||
boolean isMenuInvalidationAllowed = false;
|
||||
|
@ -92,10 +88,6 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
private LinearLayoutManager layoutManager;
|
||||
protected TextView txtvInformation;
|
||||
|
||||
boolean showOnlyNewEpisodes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
String getPrefName() {
|
||||
return DEFAULT_PREF_NAME;
|
||||
}
|
||||
|
@ -347,10 +339,10 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
}
|
||||
|
||||
protected void onFragmentLoaded(List<FeedItem> episodes) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
|
||||
if (episodes.size() == 0) {
|
||||
createRecycleAdapter(recyclerView, emptyView);
|
||||
} else {
|
||||
listAdapter.updateItems(episodes);
|
||||
}
|
||||
|
||||
restoreScrollPosition();
|
||||
|
@ -363,66 +355,13 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
*/
|
||||
private void createRecycleAdapter(RecyclerView recyclerView, EmptyViewHandler emptyViewHandler) {
|
||||
MainActivity mainActivity = (MainActivity) getActivity();
|
||||
listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, showOnlyNewEpisodes());
|
||||
listAdapter = new AllEpisodesRecycleAdapter(mainActivity);
|
||||
listAdapter.setHasStableIds(true);
|
||||
listAdapter.updateItems(episodes);
|
||||
recyclerView.setAdapter(listAdapter);
|
||||
emptyViewHandler.updateAdapter(listAdapter);
|
||||
}
|
||||
|
||||
private final AllEpisodesRecycleAdapter.ItemAccess itemAccess = new AllEpisodesRecycleAdapter.ItemAccess() {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return episodes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
if (0 <= position && position < episodes.size()) {
|
||||
return episodes.get(position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList getItemsIds() {
|
||||
LongList ids = new LongList(episodes.size());
|
||||
for (FeedItem episode : episodes) {
|
||||
ids.add(episode.getId());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
DownloadRequest downloadRequest = downloader.getDownloadRequest();
|
||||
if (downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloadRequest.getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloadRequest.getProgressPercent();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInQueue(FeedItem item) {
|
||||
return item != null && item.isTagged(FeedItem.TAG_QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList getQueueIds() {
|
||||
LongList queueIds = new LongList();
|
||||
for (FeedItem item : episodes) {
|
||||
if (item.isTagged(FeedItem.TAG_QUEUE)) {
|
||||
queueIds.add(item.getId());
|
||||
}
|
||||
}
|
||||
return queueIds;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(FeedItemEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
|
@ -444,8 +383,7 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
public void onEventMainThread(PlaybackPositionEvent event) {
|
||||
if (listAdapter != null) {
|
||||
for (int i = 0; i < listAdapter.getItemCount(); i++) {
|
||||
AllEpisodesRecycleAdapter.Holder holder = (AllEpisodesRecycleAdapter.Holder)
|
||||
recyclerView.findViewHolderForAdapterPosition(i);
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) recyclerView.findViewHolderForAdapterPosition(i);
|
||||
if (holder != null && holder.isCurrentlyPlayingItem()) {
|
||||
holder.notifyPlaybackPositionUpdated(event);
|
||||
break;
|
||||
|
@ -462,7 +400,7 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
DownloaderUpdate update = event.update;
|
||||
downloaderList = update.downloaders;
|
||||
List<Downloader> downloaderList = update.downloaders;
|
||||
if (isMenuInvalidationAllowed && event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
|
||||
requireActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter;
|
||||
import de.danoeh.antennapod.core.event.FavoritesEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
@ -30,11 +30,6 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
|
|||
private static final String TAG = "FavoriteEpisodesFrag";
|
||||
private static final String PREF_NAME = "PrefFavoriteEpisodesFragment";
|
||||
|
||||
@Override
|
||||
protected boolean showOnlyNewEpisodes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPrefName() {
|
||||
return PREF_NAME;
|
||||
|
@ -63,8 +58,8 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
|
|||
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
|
||||
AllEpisodesRecycleAdapter.Holder holder = (AllEpisodesRecycleAdapter.Holder) viewHolder;
|
||||
Log.d(TAG, String.format("remove(%s)", holder.getItemId()));
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) viewHolder;
|
||||
Log.d(TAG, String.format("remove(%s)", holder.getFeedItem().getId()));
|
||||
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
|
|
|
@ -89,25 +89,18 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
private static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id";
|
||||
|
||||
private FeedItemlistAdapter adapter;
|
||||
private ContextMenu contextMenu;
|
||||
private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
|
||||
private MoreContentListFooterUtil listFooter;
|
||||
|
||||
private long feedID;
|
||||
private Feed feed;
|
||||
|
||||
private boolean headerCreated = false;
|
||||
|
||||
private List<Downloader> downloaderList;
|
||||
|
||||
private MoreContentListFooterUtil listFooter;
|
||||
|
||||
private boolean isUpdatingFeed;
|
||||
|
||||
private TextView txtvTitle;
|
||||
private IconTextView txtvFailure;
|
||||
private ImageView imgvBackground;
|
||||
private ImageView imgvCover;
|
||||
|
||||
private TextView txtvInformation;
|
||||
|
||||
private Disposable disposable;
|
||||
|
@ -296,7 +289,7 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
|
||||
// because of addHeaderView(), positions are increased by 1!
|
||||
FeedItem item = itemAccess.getItem(adapterInfo.position-1);
|
||||
FeedItem item = (FeedItem) itemAccess.getItem(adapterInfo.position - 1);
|
||||
|
||||
MenuInflater inflater = getActivity().getMenuInflater();
|
||||
inflater.inflate(R.menu.feeditemlist_context, menu);
|
||||
|
@ -305,7 +298,6 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
menu.setHeaderTitle(item.getTitle());
|
||||
}
|
||||
|
||||
contextMenu = menu;
|
||||
lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
}
|
||||
|
@ -313,11 +305,11 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
if(menuInfo == null) {
|
||||
if (menuInfo == null) {
|
||||
menuInfo = lastMenuInfo;
|
||||
}
|
||||
// because of addHeaderView(), positions are increased by 1!
|
||||
FeedItem selectedItem = itemAccess.getItem(menuInfo.position-1);
|
||||
FeedItem selectedItem = feed.getItemAtIndex(menuInfo.position - 1);
|
||||
|
||||
if (selectedItem == null) {
|
||||
Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection");
|
||||
|
@ -366,7 +358,6 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
DownloaderUpdate update = event.update;
|
||||
downloaderList = update.downloaders;
|
||||
if (event.hasChangedFeedUpdateStatus(isUpdatingFeed)) {
|
||||
updateProgressBarVisibility();
|
||||
}
|
||||
|
@ -424,7 +415,7 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
setListAdapter(null);
|
||||
setupHeaderView();
|
||||
setupFooterView();
|
||||
adapter = new FeedItemlistAdapter(getActivity(), itemAccess, false, true);
|
||||
adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, false, true);
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
refreshHeaderView();
|
||||
|
@ -574,40 +565,13 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList getQueueIds() {
|
||||
LongList queueIds = new LongList();
|
||||
if(feed == null) {
|
||||
return queueIds;
|
||||
}
|
||||
for(FeedItem item : feed.getItems()) {
|
||||
if(item.isTagged(FeedItem.TAG_QUEUE)) {
|
||||
queueIds.add(item.getId());
|
||||
}
|
||||
}
|
||||
return queueIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return (feed != null) ? feed.getNumOfItems() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloader.getDownloadRequest().getProgressPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private void loadItems() {
|
||||
if(disposable != null) {
|
||||
disposable.dispose();
|
||||
|
|
|
@ -16,6 +16,7 @@ import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter;
|
|||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
|
||||
/**
|
||||
* Like 'EpisodesFragment' except that it only shows new episodes and
|
||||
|
@ -26,11 +27,6 @@ public class NewEpisodesFragment extends EpisodesListFragment {
|
|||
public static final String TAG = "NewEpisodesFragment";
|
||||
private static final String PREF_NAME = "PrefNewEpisodesFragment";
|
||||
|
||||
@Override
|
||||
protected boolean showOnlyNewEpisodes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPrefName() {
|
||||
return PREF_NAME;
|
||||
|
@ -63,7 +59,7 @@ public class NewEpisodesFragment extends EpisodesListFragment {
|
|||
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
|
||||
AllEpisodesRecycleAdapter.Holder holder = (AllEpisodesRecycleAdapter.Holder) viewHolder;
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) viewHolder;
|
||||
FeedItemMenuHandler.removeNewFlagWithUndo(NewEpisodesFragment.this, holder.getFeedItem());
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ public class PlaybackHistoryFragment extends ListFragment {
|
|||
// played items shoudln't be transparent for this fragment since, *all* items
|
||||
// in this fragment will, by definition, be played. So it serves no purpose and can make
|
||||
// it harder to read.
|
||||
adapter = new FeedItemlistAdapter(getActivity(), itemAccess, true, false);
|
||||
adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, false);
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class PlaybackHistoryFragment extends ListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true)
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(DownloadEvent event) {
|
||||
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
|
||||
DownloaderUpdate update = event.update;
|
||||
|
@ -180,19 +180,6 @@ public class PlaybackHistoryFragment extends ListFragment {
|
|||
|
||||
private final FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() {
|
||||
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloader.getDownloadRequest().getProgressPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return (playbackHistory != null) ? playbackHistory.size() : 0;
|
||||
|
@ -206,20 +193,6 @@ public class PlaybackHistoryFragment extends ListFragment {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList getQueueIds() {
|
||||
LongList queueIds = new LongList();
|
||||
if(playbackHistory == null) {
|
||||
return queueIds;
|
||||
}
|
||||
for (FeedItem item : playbackHistory) {
|
||||
if (item.isTagged(FeedItem.TAG_QUEUE)) {
|
||||
queueIds.add(item.getId());
|
||||
}
|
||||
}
|
||||
return queueIds;
|
||||
}
|
||||
};
|
||||
|
||||
private void loadItems() {
|
||||
|
|
|
@ -27,6 +27,7 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
|
|||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
@ -45,11 +46,9 @@ import de.danoeh.antennapod.core.event.PlayerStatusEvent;
|
|||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
|
@ -84,7 +83,6 @@ public class QueueFragment extends Fragment {
|
|||
private ProgressBar progLoading;
|
||||
|
||||
private List<FeedItem> queue;
|
||||
private List<Downloader> downloaderList;
|
||||
|
||||
private boolean isUpdatingFeeds = false;
|
||||
|
||||
|
@ -196,7 +194,6 @@ public class QueueFragment extends Fragment {
|
|||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
DownloaderUpdate update = event.update;
|
||||
downloaderList = update.downloaders;
|
||||
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
@ -214,7 +211,7 @@ public class QueueFragment extends Fragment {
|
|||
public void onEventMainThread(PlaybackPositionEvent event) {
|
||||
if (recyclerAdapter != null) {
|
||||
for (int i = 0; i < recyclerAdapter.getItemCount(); i++) {
|
||||
QueueRecyclerAdapter.ViewHolder holder = (QueueRecyclerAdapter.ViewHolder)
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder)
|
||||
recyclerView.findViewHolderForAdapterPosition(i);
|
||||
if (holder != null && holder.isCurrentlyPlayingItem()) {
|
||||
holder.notifyPlaybackPositionUpdated(event);
|
||||
|
@ -510,7 +507,6 @@ public class QueueFragment extends Fragment {
|
|||
layoutManager = new LinearLayoutManager(getActivity());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
|
||||
recyclerView.setHasFixedSize(true);
|
||||
registerForContextMenu(recyclerView);
|
||||
|
||||
itemTouchHelper = new ItemTouchHelper(
|
||||
|
@ -692,46 +688,6 @@ public class QueueFragment extends Fragment {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemDownloadedBytes(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
Log.d(TAG, "downloaded bytes: " + downloader.getDownloadRequest().getSoFar());
|
||||
return downloader.getDownloadRequest().getSoFar();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemDownloadSize(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
Log.d(TAG, "downloaded size: " + downloader.getDownloadRequest().getSize());
|
||||
return downloader.getDownloadRequest().getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloader.getDownloadRequest().getProgressPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList getQueueIds() {
|
||||
return queue != null ? LongList.of(FeedItemUtil.getIds(queue)) : new LongList(0);
|
||||
|
|
|
@ -104,11 +104,12 @@ public class RunningDownloadsFragment extends ListFragment {
|
|||
DownloadRequest downloadRequest = downloader.getDownloadRequest();
|
||||
DownloadRequester.getInstance().cancelDownload(getActivity(), downloadRequest.getSource());
|
||||
|
||||
if(downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA &&
|
||||
UserPreferences.isEnableAutodownload()) {
|
||||
if (downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& UserPreferences.isEnableAutodownload()) {
|
||||
FeedMedia media = DBReader.getFeedMedia(downloadRequest.getFeedfileId());
|
||||
DBWriter.setFeedItemAutoDownload(media.getItem(), false);
|
||||
Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), R.string.download_canceled_msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ import androidx.core.view.MenuItemCompat;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.SearchlistAdapter;
|
||||
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
|
||||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedComponent;
|
||||
|
@ -33,8 +34,10 @@ import io.reactivex.disposables.Disposable;
|
|||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
/**
|
||||
* Performs a search operation on all feeds or one specific feed and displays the search result.
|
||||
|
@ -45,7 +48,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
|
|||
private static final String ARG_QUERY = "query";
|
||||
private static final String ARG_FEED = "feed";
|
||||
|
||||
private SearchlistAdapter searchAdapter;
|
||||
private FeedItemlistAdapter searchAdapter;
|
||||
private List<FeedComponent> searchResults = new ArrayList<>();
|
||||
private Disposable disposable;
|
||||
private ProgressBar progressBar;
|
||||
|
@ -105,7 +108,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
|
|||
View layout = inflater.inflate(R.layout.search_fragment, container, false);
|
||||
ListView listView = layout.findViewById(R.id.listview);
|
||||
progressBar = layout.findViewById(R.id.progressBar);
|
||||
searchAdapter = new SearchlistAdapter(getActivity(), itemAccess);
|
||||
searchAdapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, true);
|
||||
listView.setAdapter(searchAdapter);
|
||||
listView.setOnItemClickListener(this);
|
||||
|
||||
|
@ -164,6 +167,14 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
|
|||
search();
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
if (searchAdapter != null) {
|
||||
searchAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void onSearchResults(List<FeedComponent> results) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
searchResults = results;
|
||||
|
@ -172,7 +183,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
|
|||
emptyViewHandler.setMessage(getString(R.string.no_results_for_query, query));
|
||||
}
|
||||
|
||||
private final SearchlistAdapter.ItemAccess itemAccess = new SearchlistAdapter.ItemAccess() {
|
||||
private final FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return searchResults.size();
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package de.danoeh.antennapod.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class CircularProgressBar extends View {
|
||||
private static final float EPSILON = 0.005f;
|
||||
|
||||
private final Paint paintBackground = new Paint();
|
||||
private final Paint paintProgress = new Paint();
|
||||
private float percentage = 0;
|
||||
private float targetPercentage = 0;
|
||||
private Object tag = null;
|
||||
|
||||
public CircularProgressBar(Context context) {
|
||||
super(context);
|
||||
setup();
|
||||
}
|
||||
|
||||
public CircularProgressBar(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setup();
|
||||
}
|
||||
|
||||
public CircularProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
paintBackground.setAntiAlias(true);
|
||||
paintBackground.setStyle(Paint.Style.STROKE);
|
||||
|
||||
paintProgress.setAntiAlias(true);
|
||||
paintProgress.setStyle(Paint.Style.STROKE);
|
||||
paintProgress.setStrokeCap(Paint.Cap.ROUND);
|
||||
|
||||
int[] colorAttrs = new int[] { android.R.attr.textColorPrimary, android.R.attr.textColorSecondary };
|
||||
TypedArray a = getContext().obtainStyledAttributes(colorAttrs);
|
||||
paintProgress.setColor(a.getColor(0, 0xffffffff));
|
||||
paintBackground.setColor(a.getColor(1, 0xffffffff));
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the percentage to be displayed.
|
||||
* @param percentage Number from 0 to 1
|
||||
* @param tag When the tag is the same as last time calling setPercentage, the update is animated
|
||||
*/
|
||||
public void setPercentage(float percentage, Object tag) {
|
||||
targetPercentage = percentage;
|
||||
|
||||
if (tag == null || !tag.equals(this.tag)) {
|
||||
// Do not animate
|
||||
this.percentage = percentage;
|
||||
this.tag = tag;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
float padding = getHeight() * 0.06f;
|
||||
paintBackground.setStrokeWidth(getHeight() * 0.02f);
|
||||
paintProgress.setStrokeWidth(padding);
|
||||
RectF bounds = new RectF(padding, padding, getWidth() - padding, getHeight() - padding);
|
||||
canvas.drawArc(bounds, 0, 360, false, paintBackground);
|
||||
|
||||
if (percentage > EPSILON && 1 - percentage > EPSILON) {
|
||||
canvas.drawArc(bounds, -90, percentage * 360, false, paintProgress);
|
||||
}
|
||||
|
||||
if (Math.abs(percentage - targetPercentage) > EPSILON) {
|
||||
float delta = Math.min(0.02f, Math.abs(targetPercentage - percentage));
|
||||
percentage += delta * ((targetPercentage - percentage) > 0 ? 1f : -1f);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package de.danoeh.antennapod.view.viewholder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.joanzapata.iconify.widget.IconTextView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.view.CircularProgressBar;
|
||||
|
||||
public class DownloadItemViewHolder extends RecyclerView.ViewHolder {
|
||||
public final View secondaryActionButton;
|
||||
public final ImageView secondaryActionIcon;
|
||||
public final CircularProgressBar secondaryActionProgress;
|
||||
public final IconTextView icon;
|
||||
public final TextView title;
|
||||
public final TextView type;
|
||||
public final TextView date;
|
||||
public final TextView reason;
|
||||
|
||||
public DownloadItemViewHolder(Context context, ViewGroup parent) {
|
||||
super(LayoutInflater.from(context).inflate(R.layout.downloadlog_item, parent, false));
|
||||
date = itemView.findViewById(R.id.txtvDate);
|
||||
type = itemView.findViewById(R.id.txtvType);
|
||||
icon = itemView.findViewById(R.id.txtvIcon);
|
||||
reason = itemView.findViewById(R.id.txtvReason);
|
||||
secondaryActionProgress = itemView.findViewById(R.id.secondaryActionProgress);
|
||||
secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
|
||||
secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
|
||||
title = itemView.findViewById(R.id.txtvTitle);
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
itemView.setTag(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
package de.danoeh.antennapod.view.viewholder;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.CoverLoader;
|
||||
import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.CircularProgressBar;
|
||||
|
||||
/**
|
||||
* Holds the view which shows FeedItems.
|
||||
*/
|
||||
public class EpisodeItemViewHolder extends FeedComponentViewHolder
|
||||
implements QueueRecyclerAdapter.ItemTouchHelperViewHolder {
|
||||
private static final String TAG = "EpisodeItemViewHolder";
|
||||
|
||||
private final View container;
|
||||
public final ImageView dragHandle;
|
||||
private final TextView placeholder;
|
||||
private final ImageView cover;
|
||||
private final TextView title;
|
||||
private final TextView pubDate;
|
||||
private final TextView position;
|
||||
private final TextView duration;
|
||||
private final TextView size;
|
||||
public final TextView isNew;
|
||||
public final ImageView isInQueue;
|
||||
private final ImageView isVideo;
|
||||
public final ImageView isFavorite;
|
||||
private final ProgressBar progressBar;
|
||||
public final View secondaryActionButton;
|
||||
public final ImageView secondaryActionIcon;
|
||||
private final CircularProgressBar secondaryActionProgress;
|
||||
private final TextView separatorIcons;
|
||||
public final CardView coverHolder;
|
||||
|
||||
private final MainActivity activity;
|
||||
private FeedItem item;
|
||||
|
||||
public EpisodeItemViewHolder(MainActivity activity, ViewGroup parent) {
|
||||
super(LayoutInflater.from(activity).inflate(R.layout.feeditemlist_item, parent, false));
|
||||
this.activity = activity;
|
||||
container = itemView.findViewById(R.id.container);
|
||||
dragHandle = itemView.findViewById(R.id.drag_handle);
|
||||
placeholder = itemView.findViewById(R.id.txtvPlaceholder);
|
||||
cover = itemView.findViewById(R.id.imgvCover);
|
||||
title = itemView.findViewById(R.id.txtvTitle);
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
pubDate = itemView.findViewById(R.id.txtvPubDate);
|
||||
position = itemView.findViewById(R.id.txtvPosition);
|
||||
duration = itemView.findViewById(R.id.txtvDuration);
|
||||
progressBar = itemView.findViewById(R.id.progressBar);
|
||||
isInQueue = itemView.findViewById(R.id.ivInPlaylist);
|
||||
isVideo = itemView.findViewById(R.id.ivIsVideo);
|
||||
isNew = itemView.findViewById(R.id.statusUnread);
|
||||
isFavorite = itemView.findViewById(R.id.isFavorite);
|
||||
size = itemView.findViewById(R.id.size);
|
||||
separatorIcons = itemView.findViewById(R.id.separatorIcons);
|
||||
secondaryActionProgress = itemView.findViewById(R.id.secondaryActionProgress);
|
||||
secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
|
||||
secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
|
||||
coverHolder = itemView.findViewById(R.id.coverHolder);
|
||||
itemView.setTag(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected() {
|
||||
itemView.setAlpha(0.5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClear() {
|
||||
itemView.setAlpha(1.0f);
|
||||
}
|
||||
|
||||
public void bind(FeedItem item) {
|
||||
this.item = item;
|
||||
placeholder.setText(item.getFeed().getTitle());
|
||||
title.setText(item.getTitle());
|
||||
pubDate.setText(DateUtils.formatAbbrev(activity, item.getPubDate()));
|
||||
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.5f : 1.0f);
|
||||
|
||||
ItemActionButton actionButton = ItemActionButton.forItem(item, true, true);
|
||||
actionButton.configure(secondaryActionButton, secondaryActionIcon, activity);
|
||||
secondaryActionButton.setFocusable(false);
|
||||
|
||||
if (item.getMedia() != null) {
|
||||
bind(item.getMedia());
|
||||
} else {
|
||||
secondaryActionProgress.setPercentage(0, item);
|
||||
}
|
||||
|
||||
if (coverHolder.getVisibility() == View.VISIBLE) {
|
||||
new CoverLoader(activity)
|
||||
.withUri(ImageResourceUtils.getImageLocation(item))
|
||||
.withFallbackUri(item.getFeed().getImageLocation())
|
||||
.withPlaceholderView(placeholder)
|
||||
.withCoverView(cover)
|
||||
.load();
|
||||
}
|
||||
}
|
||||
|
||||
private void bind(FeedMedia media) {
|
||||
isVideo.setVisibility(media.getMediaType() == MediaType.VIDEO ? View.VISIBLE : View.GONE);
|
||||
duration.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
|
||||
if (media.isCurrentlyPlaying()) {
|
||||
container.setBackgroundColor(ThemeUtils.getColorFromAttr(activity, R.attr.currently_playing_background));
|
||||
} else {
|
||||
container.setBackgroundResource(ThemeUtils.getDrawableFromAttr(activity, R.attr.selectableItemBackground));
|
||||
}
|
||||
|
||||
if (DownloadRequester.getInstance().isDownloadingFile(media)) {
|
||||
final DownloadRequest downloadRequest = DownloadRequester.getInstance().getRequestFor(media);
|
||||
float percent = 0.01f * downloadRequest.getProgressPercent();
|
||||
secondaryActionProgress.setPercentage(Math.max(percent, 0.01f), item);
|
||||
} else if (media.isDownloaded()) {
|
||||
secondaryActionProgress.setPercentage(1, item); // Do not animate 100% -> 0%
|
||||
} else {
|
||||
secondaryActionProgress.setPercentage(0, item); // Animate X% -> 0%
|
||||
}
|
||||
|
||||
if (media.getDuration() > 0
|
||||
&& (item.getState() == FeedItem.State.PLAYING || item.getState() == FeedItem.State.IN_PROGRESS)) {
|
||||
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
|
||||
progressBar.setProgress(progress);
|
||||
position.setText(Converter.getDurationStringLong(media.getPosition()));
|
||||
duration.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
position.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
position.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (media.getSize() > 0) {
|
||||
size.setText(Converter.byteToString(media.getSize()));
|
||||
} else if (NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
|
||||
size.setText("{fa-spinner}");
|
||||
Iconify.addIcons(size);
|
||||
NetworkUtils.getFeedMediaSizeObservable(media).subscribe(
|
||||
sizeValue -> {
|
||||
if (sizeValue > 0) {
|
||||
size.setText(Converter.byteToString(sizeValue));
|
||||
} else {
|
||||
size.setText("");
|
||||
}
|
||||
}, error -> {
|
||||
size.setText("");
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
});
|
||||
} else {
|
||||
size.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
public FeedItem getFeedItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public boolean isCurrentlyPlayingItem() {
|
||||
return item.getMedia() != null && item.getMedia().isCurrentlyPlaying();
|
||||
}
|
||||
|
||||
public void notifyPlaybackPositionUpdated(PlaybackPositionEvent event) {
|
||||
progressBar.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
|
||||
position.setText(Converter.getDurationStringLong(event.getPosition()));
|
||||
duration.setText(Converter.getDurationStringLong(event.getDuration()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the separator dot between icons and text if there are no icons.
|
||||
*/
|
||||
public void hideSeparatorIfNecessary() {
|
||||
boolean hasIcons = isNew.getVisibility() == View.VISIBLE
|
||||
|| isInQueue.getVisibility() == View.VISIBLE
|
||||
|| isVideo.getVisibility() == View.VISIBLE
|
||||
|| isFavorite.getVisibility() == View.VISIBLE
|
||||
|| isNew.getVisibility() == View.VISIBLE;
|
||||
separatorIcons.setVisibility(hasIcons ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package de.danoeh.antennapod.view.viewholder;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Holds the view which shows FeedComponents.
|
||||
*/
|
||||
public class FeedComponentViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public FeedComponentViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package de.danoeh.antennapod.view.viewholder;
|
||||
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.CoverLoader;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
|
||||
/**
|
||||
* Holds the view which shows feeds.
|
||||
*/
|
||||
public class FeedViewHolder extends FeedComponentViewHolder {
|
||||
private static final String TAG = "FeedViewHolder";
|
||||
|
||||
private final TextView placeholder;
|
||||
private final ImageView cover;
|
||||
private final TextView title;
|
||||
public final CardView coverHolder;
|
||||
|
||||
private final MainActivity activity;
|
||||
private Feed feed;
|
||||
|
||||
public FeedViewHolder(MainActivity activity, ViewGroup parent) {
|
||||
super(LayoutInflater.from(activity).inflate(R.layout.feeditemlist_item, parent, false));
|
||||
this.activity = activity;
|
||||
placeholder = itemView.findViewById(R.id.txtvPlaceholder);
|
||||
cover = itemView.findViewById(R.id.imgvCover);
|
||||
coverHolder = itemView.findViewById(R.id.coverHolder);
|
||||
title = itemView.findViewById(R.id.txtvTitle);
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
|
||||
}
|
||||
|
||||
itemView.findViewById(R.id.secondaryActionButton).setVisibility(View.GONE);
|
||||
itemView.findViewById(R.id.status).setVisibility(View.GONE);
|
||||
itemView.findViewById(R.id.progress).setVisibility(View.GONE);
|
||||
itemView.findViewById(R.id.drag_handle).setVisibility(View.GONE);
|
||||
itemView.setTag(this);
|
||||
}
|
||||
|
||||
public void bind(Feed feed) {
|
||||
this.feed = feed;
|
||||
placeholder.setText(feed.getTitle());
|
||||
title.setText(feed.getTitle());
|
||||
|
||||
if (coverHolder.getVisibility() == View.VISIBLE) {
|
||||
new CoverLoader(activity)
|
||||
.withUri(feed.getImageLocation())
|
||||
.withPlaceholderView(placeholder)
|
||||
.withCoverView(cover)
|
||||
.load();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -34,7 +34,7 @@
|
|||
app:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
|
||||
app:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
|
||||
tools:itemCount="13"
|
||||
tools:listitem="@layout/new_episodes_listitem" />
|
||||
tools:listitem="@layout/feeditemlist_item" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:background="@android:color/darker_gray">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvImage"
|
||||
android:layout_width="@dimen/thumbnail_length_downloaded_item"
|
||||
android:layout_height="@dimen/thumbnail_length_downloaded_item"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:contentDescription="@string/cover_label"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@drawable/ic_antenna"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
tools:background="@android:color/holo_red_dark">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
tools:text="Downloaded episode title"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:background="@android:color/holo_red_dark" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvSize"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="23 MB"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<View
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="1dip"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvInPlaylist"
|
||||
android:layout_width="@dimen/enc_icons_size"
|
||||
android:layout_height="@dimen/enc_icons_size"
|
||||
android:contentDescription="@string/in_queue_label"
|
||||
android:src="?attr/stat_playlist"
|
||||
android:visibility="visible"
|
||||
tools:src="@drawable/ic_list_white_24dp"
|
||||
tools:background="@android:color/holo_red_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPublished"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="Jan 23"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/butSecondaryAction"
|
||||
android:layout_width="@dimen/listview_secondary_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/delete_episode_label"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:src="?attr/content_discard"
|
||||
tools:src="@drawable/ic_delete_white_24dp"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,90 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:background="@android:color/darker_gray">
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:descendantFocusability="blocksDescendants">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
tools:text="Download item title"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progProgress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginTop="4dp"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDownloaded"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@sample/episodes.json/data/title"
|
||||
android:ellipsize="end"/>
|
||||
<TextView
|
||||
android:id="@+id/txtvStatus"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:text="21 MB / 42 MB"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPercent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
tools:text="50%"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
</RelativeLayout>
|
||||
|
||||
tools:text="Media file · 10MB / 20MB"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/butSecondaryAction"
|
||||
android:layout_width="@dimen/listview_secondary_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/cancel_download_label"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:src="?attr/navigation_cancel"
|
||||
tools:src="@drawable/ic_cancel_white_24dp"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
<include layout="@layout/secondary_action"/>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,97 +1,90 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
tools:background="@android:color/darker_gray">
|
||||
<LinearLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:descendantFocusability="blocksDescendants">
|
||||
|
||||
<com.joanzapata.iconify.widget.IconTextView
|
||||
android:id="@+id/txtvIcon"
|
||||
android:layout_width="48sp"
|
||||
android:layout_height="48sp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:textSize="48sp"
|
||||
android:gravity="center" />
|
||||
android:id="@+id/txtvIcon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_textleftpadding"
|
||||
android:textSize="40dp"
|
||||
android:gravity="center"
|
||||
tools:text="X"/>
|
||||
|
||||
<com.joanzapata.iconify.widget.IconButton
|
||||
android:id="@+id/btnRetry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txtvIcon"
|
||||
android:layout_alignLeft="@id/txtvIcon"
|
||||
android:layout_alignStart="@id/txtvIcon"
|
||||
android:layout_alignRight="@id/txtvIcon"
|
||||
android:layout_alignEnd="@id/txtvIcon"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="{fa-repeat}"
|
||||
tools:text="↻" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvType"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="Media file"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/status"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toRightOf="@id/txtvIcon"
|
||||
android:layout_toEndOf="@id/txtvIcon"
|
||||
android:layout_toLeftOf="@id/txtvType"
|
||||
android:layout_toStartOf="@id/txtvType"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:minLines="1"
|
||||
android:maxLines="2"
|
||||
tools:text="Download item title"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
<TextView
|
||||
android:id="@+id/txtvType"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Media file"/>
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="·"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
<TextView
|
||||
android:id="@+id/txtvDate"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="January 23"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDate"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/txtvIcon"
|
||||
android:layout_toEndOf="@id/txtvIcon"
|
||||
android:layout_below="@id/txtvTitle"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="January 23"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@sample/episodes.json/data/title"
|
||||
android:ellipsize="end"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvReason"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txtvDate"
|
||||
android:layout_toRightOf="@id/txtvIcon"
|
||||
android:layout_toEndOf="@id/txtvIcon"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textSize="@dimen/text_size_micro"
|
||||
tools:text="@string/design_time_downloaded_log_failure_reason"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
<TextView
|
||||
android:id="@+id/txtvReason"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:text="@string/design_time_downloaded_log_failure_reason"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/secondary_action"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,124 +1,203 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:background="@android:color/darker_gray">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
tools:background="@android:color/holo_orange_dark">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/statusUnread"
|
||||
style="@style/AntennaPod.TextView.UnreadIndicator"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
tools:text="NEW"
|
||||
tools:background="@android:color/white" />
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="16dp">
|
||||
<ImageView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/drag_handle_content_description"
|
||||
android:scaleType="center"
|
||||
android:src="?attr/dragview_background"
|
||||
tools:src="@drawable/ic_drag_vertical_grey600_48dp"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvItemname"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textleftpadding"
|
||||
android:id="@+id/coverHolder"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPlaceholder"
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:background="@color/light_gray"
|
||||
android:maxLines="3"
|
||||
android:padding="2dp"
|
||||
android:ellipsize="end"/>
|
||||
<ImageView
|
||||
android:id="@+id/imgvCover"
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@string/cover_label"
|
||||
tools:src="@tools:sample/avatars"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_toLeftOf="@id/statusUnread"
|
||||
android:layout_toStartOf="@id/statusUnread"
|
||||
tools:text="Episode title"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_weight="1"
|
||||
tools:background="@android:color/holo_red_dark"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/status"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:text="@string/new_episodes_label"
|
||||
style="@style/AntennaPod.TextView.UnreadIndicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/statusUnread"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
tools:text="@sample/episodes.json/data/status_label"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="14sp"
|
||||
android:layout_height="14sp"
|
||||
app:srcCompat="?attr/type_video"
|
||||
tools:srcCompat="@drawable/ic_videocam_grey600_24dp"
|
||||
android:id="@+id/ivIsVideo"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="14sp"
|
||||
android:layout_height="14sp"
|
||||
app:srcCompat="?attr/ic_unfav"
|
||||
tools:srcCompat="@drawable/ic_star_grey600_24dp"
|
||||
android:id="@+id/isFavorite"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="14sp"
|
||||
android:layout_height="14sp"
|
||||
app:srcCompat="?attr/stat_playlist"
|
||||
tools:srcCompat="@drawable/ic_list_grey600_24dp"
|
||||
android:id="@+id/ivInPlaylist"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/separatorIcons"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="·"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPubDate"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
tools:text="@sample/episodes.json/data/published_at"/>
|
||||
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="·"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/size"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="10 MB"/>
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/txtvLenSize"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/txtvItemname"
|
||||
tools:text="00:42:23"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@sample/episodes.json/data/title"
|
||||
android:ellipsize="end"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvInPlaylist"
|
||||
android:layout_width="@dimen/enc_icons_size"
|
||||
android:layout_height="@dimen/enc_icons_size"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@id/txtvItemname"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/in_queue_label"
|
||||
android:src="?attr/stat_playlist"
|
||||
android:visibility="visible"
|
||||
tools:src="@drawable/ic_list_white_24dp"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/progress"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvType"
|
||||
android:layout_width="@dimen/enc_icons_size"
|
||||
android:layout_height="@dimen/enc_icons_size"
|
||||
android:layout_below="@id/txtvItemname"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toLeftOf="@id/imgvInPlaylist"
|
||||
android:layout_toStartOf="@id/imgvInPlaylist"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@drawable/ic_hearing_white_18dp"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
<TextView
|
||||
android:id="@+id/txtvPosition"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="0dp"
|
||||
tools:text="00:42:23"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPublished"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txtvItemname"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toLeftOf="@id/imgvType"
|
||||
android:layout_toStartOf="@id/imgvType"
|
||||
tools:text="Jan 23"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?attr/progressBarTheme"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="4dp"
|
||||
android:max="100"
|
||||
android:layout_margin="4dp"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbar_episode_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@id/txtvPublished"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_toStartOf="@id/txtvPublished"
|
||||
android:layout_toLeftOf="@id/txtvPublished"
|
||||
android:layout_toEndOf="@id/txtvLenSize"
|
||||
android:layout_toRightOf="@id/txtvLenSize"
|
||||
android:layoutDirection="ltr"
|
||||
android:indeterminate="false"
|
||||
android:max="100"
|
||||
android:progress="42"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
<TextView
|
||||
android:id="@+id/txtvDuration"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="0dp"
|
||||
tools:text="@sample/episodes.json/data/duration"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/secondary_action"/>
|
||||
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPlaceholder"
|
||||
android:layout_width="@dimen/thumbnail_length_itemlist"
|
||||
android:layout_height="@dimen/thumbnail_length_itemlist"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:background="@color/light_gray"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:gravity="center"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvCover"
|
||||
android:layout_height="64dp"
|
||||
android:layout_width="64dp"
|
||||
android:layout_alignLeft="@id/txtvPlaceholder"
|
||||
android:layout_alignStart="@id/txtvPlaceholder"
|
||||
android:layout_alignTop="@id/txtvPlaceholder"
|
||||
android:layout_alignRight="@id/txtvPlaceholder"
|
||||
android:layout_alignEnd="@id/txtvPlaceholder"
|
||||
android:layout_alignBottom="@id/txtvPlaceholder"
|
||||
android:contentDescription="@string/cover_label"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_weight="1">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/statusUnread"
|
||||
style="@style/AntennaPod.TextView.UnreadIndicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="@sample/episodes.json/data/status_label"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toLeftOf="@id/statusUnread"
|
||||
android:layout_toStartOf="@id/statusUnread"
|
||||
tools:text="@sample/episodes.json/data/title" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/bottom_bar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txtvTitle"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDuration"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
tools:text="@sample/episodes.json/data/duration" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvInPlaylist"
|
||||
android:layout_width="@dimen/enc_icons_size"
|
||||
android:layout_height="@dimen/enc_icons_size"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:contentDescription="@string/in_queue_label"
|
||||
android:src="?attr/stat_playlist"
|
||||
tools:src="@sample/inplaylist" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPublished"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toLeftOf="@id/imgvInPlaylist"
|
||||
android:layout_toStartOf="@id/imgvInPlaylist"
|
||||
android:ellipsize="end"
|
||||
tools:text="@sample/episodes.json/data/published_at" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbar_progress"
|
||||
style="?attr/progressBarTheme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="4dp"
|
||||
android:layout_below="@id/txtvDuration"
|
||||
android:max="100" />
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
|
||||
<include layout="@layout/secondary_action" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -1,153 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:background="@android:color/darker_gray" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="104dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginLeft="-16dp"
|
||||
android:layout_marginStart="-16dp"
|
||||
android:layout_marginRight="-72dp"
|
||||
android:layout_marginEnd="-72dp"
|
||||
android:contentDescription="@string/drag_handle_content_description"
|
||||
android:scaleType="fitXY"
|
||||
android:src="?attr/dragview_background"
|
||||
tools:src="@drawable/ic_drag_vertical_grey600_48dp"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp">
|
||||
<TextView
|
||||
android:id="@+id/txtvPlaceholder"
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:background="@color/light_gray"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"/>
|
||||
<ImageView
|
||||
android:id="@+id/imgvCover"
|
||||
android:layout_width="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_height="@dimen/thumbnail_length_queue_item"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@string/cover_label"
|
||||
tools:src="@drawable/ic_antenna"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_textleftpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_weight="1"
|
||||
tools:background="@android:color/holo_red_dark">
|
||||
|
||||
<!-- order is important, pubDate first! -->
|
||||
<TextView
|
||||
android:id="@+id/txtvPubDate"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="2"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:gravity="end|top"
|
||||
android:text="Feb\n12"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toLeftOf="@id/txtvPubDate"
|
||||
android:layout_toStartOf="@id/txtvPubDate"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:text="Queue item title"
|
||||
android:ellipsize="end"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/bottom_bar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/txtvTitle"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvProgressLeft"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:text="00:42:23"
|
||||
tools:background="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvProgressRight"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="0dp"
|
||||
tools:text="Jan 23"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?attr/progressBarTheme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="4dp"
|
||||
android:layout_below="@id/txtvProgressLeft"
|
||||
android:layoutDirection="ltr"
|
||||
android:max="100"
|
||||
tools:background="@android:color/holo_blue_light" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
|
||||
<include layout="@layout/secondary_action"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -13,8 +13,5 @@
|
|||
<ListView
|
||||
android:id="@+id/listview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingLeft="@dimen/list_vertical_padding"
|
||||
android:paddingRight="@dimen/list_vertical_padding" />
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
|
@ -1,12 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/butSecondaryAction"
|
||||
android:layout_width="@dimen/listview_secondary_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@sample/secondaryaction" />
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:id="@+id/secondaryActionButton"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/secondaryActionIcon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@sample/secondaryaction"/>
|
||||
|
||||
<de.danoeh.antennapod.view.CircularProgressBar
|
||||
android:id="@+id/secondaryActionProgress"
|
||||
android:layout_width="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="40dp"/>
|
||||
</FrameLayout>
|
||||
|
|
|
@ -1,86 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:background="@android:color/darker_gray">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvStart"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="Start"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:baselineAligned="false"
|
||||
android:descendantFocusability="blocksDescendants">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_horizontalpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
tools:background="@android:color/holo_red_dark">
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding"
|
||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
tools:text="Chapter title"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:id="@+id/txtvStart"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="00:00:00"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvLink"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:maxLines="1"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:text="Link"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:id="@+id/txtvTitle"
|
||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@sample/episodes.json/data/title"
|
||||
android:ellipsize="end"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvLink"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:visibility="gone"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
tools:visibility="visible"
|
||||
tools:text="https://example.com"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDuration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:maxLines="1"
|
||||
tools:text="Duration"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
tools:text="Duration: 00:00:00"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider" />
|
||||
<include layout="@layout/secondary_action"/>
|
||||
|
||||
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/butPlayChapter"
|
||||
android:layout_width="@dimen/listview_secondary_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/chapters_label"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:src="?attr/av_play"
|
||||
tools:src="@drawable/ic_play_arrow_white_36dp"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download.handler;
|
|||
|
||||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -23,6 +24,7 @@ public class PostDownloaderTask implements Runnable {
|
|||
runningDownloads.add(downloader);
|
||||
}
|
||||
}
|
||||
DownloadRequester.getInstance().updateProgress(downloads);
|
||||
List<Downloader> list = Collections.unmodifiableList(runningDownloads);
|
||||
EventBus.getDefault().postSticky(DownloadEvent.refresh(list));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -343,6 +344,16 @@ public class DownloadRequester implements DownloadStateProvider {
|
|||
return item.getDownload_url() != null && downloads.containsKey(item.getDownload_url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the downloader for this item.
|
||||
*/
|
||||
public synchronized DownloadRequest getRequestFor(FeedFile item) {
|
||||
if (isDownloadingFile(item)) {
|
||||
return downloads.get(item.getDownload_url());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feedfile with the given download url is in the downloads list
|
||||
*/
|
||||
|
@ -428,4 +439,13 @@ public class DownloadRequester implements DownloadStateProvider {
|
|||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void updateProgress(List<Downloader> newDownloads) {
|
||||
for (Downloader downloader : newDownloads) {
|
||||
DownloadRequest request = downloader.getDownloadRequest();
|
||||
if (downloads.containsKey(request.getSource())) {
|
||||
downloads.put(request.getSource(), request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,12 @@ public class FeedSearcher {
|
|||
final List<FeedComponent> result = new ArrayList<>();
|
||||
try {
|
||||
FutureTask<List<FeedItem>> itemSearchTask = DBTasks.searchFeedItems(context, selectedFeed, query);
|
||||
FutureTask<List<Feed>> feedSearchTask = DBTasks.searchFeeds(context, query);
|
||||
itemSearchTask.run();
|
||||
feedSearchTask.run();
|
||||
|
||||
result.addAll(feedSearchTask.get());
|
||||
if (selectedFeed == 0) {
|
||||
FutureTask<List<Feed>> feedSearchTask = DBTasks.searchFeeds(context, query);
|
||||
feedSearchTask.run();
|
||||
result.addAll(feedSearchTask.get());
|
||||
}
|
||||
result.addAll(itemSearchTask.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.ColorInt;
|
||||
import android.util.TypedValue;
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
public class ThemeUtils {
|
||||
private ThemeUtils() {
|
||||
|
@ -15,4 +16,10 @@ public class ThemeUtils {
|
|||
context.getTheme().resolveAttribute(attr, typedValue, true);
|
||||
return typedValue.data;
|
||||
}
|
||||
|
||||
public static @DrawableRes int getDrawableFromAttr(Context context, @AttrRes int attr) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(attr, typedValue, true);
|
||||
return typedValue.resourceId;
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 301 B |
Before Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 621 B |
Before Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 492 B |
Before Width: | Height: | Size: 472 B |
Before Width: | Height: | Size: 885 B |
Before Width: | Height: | Size: 840 B |
Before Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 669 B |
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path android:fillColor="#FF757575"
|
||||
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
|
||||
</vector>
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
|
||||
</vector>
|
|
@ -2,6 +2,4 @@
|
|||
<resources>
|
||||
|
||||
<dimen name="thumbnail_length">170dp</dimen>
|
||||
<dimen name="thumbnail_length_queue_item">64dp</dimen>
|
||||
<dimen name="thumbnail_length_downloaded_item">64dp</dimen>
|
||||
</resources>
|
|
@ -26,7 +26,6 @@
|
|||
<attr name="social_share" format="reference"/>
|
||||
<attr name="stat_playlist" format="reference"/>
|
||||
<attr name="ic_folder" format="reference"/>
|
||||
<attr name="type_audio" format="reference"/>
|
||||
<attr name="type_video" format="reference"/>
|
||||
<attr name="overlay_drawable" format="reference"/>
|
||||
<attr name="dragview_background" format="reference"/>
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
<color name="black">#000000</color>
|
||||
<color name="holo_blue_light">#33B5E5</color>
|
||||
<color name="holo_blue_dark">#0099CC</color>
|
||||
<color name="download_success_green">#669900</color>
|
||||
<color name="download_failed_red">#CC0000</color>
|
||||
<color name="download_success_green">#248800</color>
|
||||
<color name="download_failed_red">#B00020</color>
|
||||
<color name="status_progress">#E033B5E5</color>
|
||||
<color name="overlay_dark">#2C2C2C</color>
|
||||
<color name="overlay_light">#FFFFFF</color>
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
<dimen name="text_size_navdrawer">16sp</dimen>
|
||||
<dimen name="text_size_medium">18sp</dimen>
|
||||
<dimen name="text_size_large">22sp</dimen>
|
||||
<dimen name="thumbnail_length_itemlist">64dp</dimen>
|
||||
<dimen name="thumbnail_length_queue_item">64dp</dimen>
|
||||
<dimen name="thumbnail_length_itemlist">56dp</dimen>
|
||||
<dimen name="thumbnail_length_queue_item">56dp</dimen>
|
||||
<dimen name="thumbnail_length_downloaded_item">64dp</dimen>
|
||||
<dimen name="thumbnail_length_onlinefeedview">100dp</dimen>
|
||||
<dimen name="feeditemlist_header_height">132dp</dimen>
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
<dimen name="listitem_threeline_textleftpadding">16dp</dimen>
|
||||
<dimen name="listitem_threeline_textrightpadding">8dp</dimen>
|
||||
<dimen name="listitem_threeline_verticalpadding">16dp</dimen>
|
||||
<dimen name="listitem_threeline_verticalpadding">8dp</dimen>
|
||||
<dimen name="listitem_threeline_horizontalpadding">16dp</dimen>
|
||||
|
||||
<dimen name="list_vertical_padding">8dp</dimen>
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
<string name="feed_volume_reduction_light">Light</string>
|
||||
<string name="feed_volume_reduction_heavy">Heavy</string>
|
||||
<string name="parallel_downloads_suffix">\u0020parallel downloads</string>
|
||||
<string name="download_queued">Download queued</string>
|
||||
<string name="feed_auto_download_global">Global default</string>
|
||||
<string name="feed_auto_download_always">Always</string>
|
||||
<string name="feed_auto_download_never">Never</string>
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
<item name="navigation_up">@drawable/navigation_up</item>
|
||||
<item name="social_share">@drawable/ic_share_grey600_24dp</item>
|
||||
<item name="stat_playlist">@drawable/ic_list_grey600_24dp</item>
|
||||
<item name="type_audio">@drawable/ic_hearing_grey600_18dp</item>
|
||||
<item name="type_video">@drawable/ic_remove_red_eye_grey600_18dp</item>
|
||||
<item name="type_video">@drawable/ic_videocam_grey600_24dp</item>
|
||||
<item name="non_transparent_background">@color/white</item>
|
||||
<item name="overlay_background">@color/overlay_light</item>
|
||||
<item name="overlay_drawable">@drawable/overlay_drawable</item>
|
||||
|
@ -127,8 +126,7 @@
|
|||
<item name="navigation_up">@drawable/navigation_up_dark</item>
|
||||
<item name="social_share">@drawable/ic_share_white_24dp</item>
|
||||
<item name="stat_playlist">@drawable/ic_list_white_24dp</item>
|
||||
<item name="type_audio">@drawable/ic_hearing_white_18dp</item>
|
||||
<item name="type_video">@drawable/ic_remove_red_eye_white_18dp</item>
|
||||
<item name="type_video">@drawable/ic_videocam_white_24dp</item>
|
||||
<item name="non_transparent_background">@color/black</item>
|
||||
<item name="overlay_background">@color/overlay_dark</item>
|
||||
<item name="overlay_drawable">@drawable/overlay_drawable_dark</item>
|
||||
|
@ -291,7 +289,7 @@
|
|||
<style name="AntennaPod.TextView.ListItemPrimaryTitle" parent="@android:style/TextAppearance.Small">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="android:lines">2</item>
|
||||
<item name="android:maxLines">2</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
|
|