diff options
10 files changed, 374 insertions, 267 deletions
diff --git a/res/layout/feeditemlist_item.xml b/res/layout/feeditemlist_item.xml index e2898b601..c887d3a4f 100644 --- a/res/layout/feeditemlist_item.xml +++ b/res/layout/feeditemlist_item.xml @@ -1,155 +1,133 @@ <?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="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - android:paddingLeft="4dp" > - <TextView - android:id="@+id/txtvItemname" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="4dp" - android:layout_marginRight="4dp" - android:layout_marginTop="4dp" - android:layout_toLeftOf="@+id/butAction" - android:ellipsize="end" - android:lines="2" - android:textColor="?android:attr/textColorPrimary" - android:textSize="@dimen/text_size_medium" /> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:orientation="horizontal" + android:layout_height="match_parent"> - <TextView - android:id="@+id/txtvFeedname" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_below="@id/txtvItemname" - android:layout_marginBottom="4dp" - android:layout_toLeftOf="@id/butAction" - android:textColor="?android:attr/textColorSecondary" - android:textSize="@dimen/text_size_micro" - android:visibility="gone" /> + <RelativeLayout + android:layout_margin="8dp" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:paddingLeft="4dp"> - <TextView - android:id="@+id/txtvPublished" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_below="@id/txtvFeedname" - android:layout_marginBottom="4dp" - android:layout_toLeftOf="@id/butAction" - android:textColor="?android:attr/textColorTertiary" - android:textSize="@dimen/text_size_micro" /> + <TextView + android:id="@+id/txtvPublished" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_marginBottom="4dp" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_micro"/> - <ImageView - android:id="@+id/imgvType" - android:layout_width="@dimen/enc_icons_size" - android:layout_height="@dimen/enc_icons_size" - android:layout_below="@id/txtvPublished" - android:layout_toLeftOf="@+id/imgvInPlaylist" - android:padding="2dp" - tools:ignore="ContentDescription"/> + <TextView + android:id="@+id/txtvItemname" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_below="@id/txtvPublished" + android:layout_marginBottom="4dp" + android:layout_marginRight="4dp" + android:layout_marginTop="4dp" + android:ellipsize="end" + android:lines="2" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_medium"/> - <ImageView - android:id="@id/imgvInPlaylist" - android:contentDescription="@string/in_queue_label" - android:layout_width="@dimen/enc_icons_size" - android:layout_height="@dimen/enc_icons_size" - android:layout_below="@id/txtvPublished" - android:layout_toLeftOf="@+id/imgvDownloaded" - android:padding="2dp" - android:src="?attr/stat_playlist" - android:visibility="visible" /> - <ImageView - android:id="@id/imgvDownloaded" - android:contentDescription="@string/status_downloaded_label" - android:layout_width="@dimen/enc_icons_size" - android:layout_height="@dimen/enc_icons_size" - android:layout_below="@id/txtvPublished" - android:layout_toLeftOf="@+id/imgvDownloading" - android:padding="2dp" - android:src="?attr/av_download" - android:visibility="visible" /> + <ImageView + android:id="@+id/imgvInPlaylist" + android:contentDescription="@string/in_queue_label" + android:layout_width="@dimen/enc_icons_size" + android:layout_height="@dimen/enc_icons_size" + android:layout_alignParentBottom="true" + android:layout_alignParentRight="true" + android:padding="2dp" + android:src="?attr/stat_playlist" + android:visibility="visible"/> - <ImageView - android:id="@id/imgvDownloading" - android:contentDescription="@string/downloading_label" - android:layout_width="@dimen/enc_icons_size" - android:layout_height="@dimen/enc_icons_size" - android:layout_below="@id/txtvPublished" - android:layout_toLeftOf="@id/butAction" - android:padding="2dp" - android:src="?attr/navigation_refresh" - android:visibility="visible" /> + <ImageView + android:id="@+id/imgvType" + android:layout_width="@dimen/enc_icons_size" + android:layout_height="@dimen/enc_icons_size" + android:layout_alignParentBottom="true" + android:layout_toLeftOf="@+id/imgvInPlaylist" + android:padding="2dp" + tools:ignore="ContentDescription"/> - <TextView - android:id="@+id/txtvLenSize" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_below="@id/txtvPublished" - android:maxLines="2" - android:textColor="?android:attr/textColorTertiary" - android:textSize="@dimen/text_size_micro" /> + <TextView + android:id="@+id/txtvLenSize" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_below="@id/txtvItemname" + android:maxLines="2" + android:layout_marginBottom="2dp" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_micro"/> - <ProgressBar - android:id="@+id/pbar_episode_progress" - style="?android:attr/progressBarStyleHorizontal" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_below="@id/txtvPublished" - android:layout_marginBottom="4dp" - android:layout_marginLeft="4dp" - android:layout_marginRight="4dp" - android:layout_marginTop="2dp" - android:layout_toLeftOf="@id/imgvType" - android:layout_toRightOf="@id/txtvLenSize" /> + <ProgressBar + android:id="@+id/pbar_episode_progress" + style="?android:attr/progressBarStyleHorizontal" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_below="@id/txtvItemname" + android:layout_marginLeft="4dp" + android:layout_marginRight="4dp" + android:layout_marginTop="2dp" + android:layout_toLeftOf="@id/imgvType" + android:layout_toRightOf="@id/txtvLenSize"/> - <ImageButton - android:id="@id/butAction" - android:contentDescription="@string/butAction_label" - android:layout_width="48dp" + <TextView + android:id="@+id/statusUnread" + android:contentDescription="@string/status_unread_label" + android:layout_width="wrap_content" + android:layout_height="18dp" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginLeft="8dp" + android:layout_marginBottom="8dp" + android:background="@color/status_unread" + android:gravity="center" + android:minWidth="@dimen/status_indicator_width" + android:text="@string/new_label" + android:textAlignment="center" + android:textColor="@color/white" + android:textSize="@dimen/text_size_micro" + android:textStyle="bold"/> + + <ImageView + android:id="@+id/statusPlaying" + android:contentDescription="@string/status_playing_label" + android:layout_width="@dimen/status_indicator_width" + android:layout_height="18dp" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginLeft="8dp" + android:layout_marginBottom="8dp" + android:background="@color/status_playing" + android:gravity="center" + android:padding="2dp" + android:src="@drawable/av_play_dark"/> + + </RelativeLayout> + + <View + android:layout_width="1dp" android:layout_height="match_parent" - android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" - android:background="?attr/borderless_button" - android:clickable="false" + android:background="@drawable/vertical_divider" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp"/> + + <ImageButton + android:id="@+id/butSecondaryAction" android:focusable="false" + android:clickable="false" android:focusableInTouchMode="false" - android:paddingLeft="24dp" - android:paddingRight="8dp" - android:paddingTop="16dp" - android:scaleType="fitEnd" - android:src="?attr/spinner_button" /> - - <TextView - android:id="@+id/statusUnread" - android:contentDescription="@string/status_unread_label" - android:layout_width="wrap_content" - android:layout_height="18dp" - android:layout_alignParentRight="true" - android:layout_alignParentTop="true" - android:layout_margin="8dp" - android:background="@color/status_unread" - android:gravity="center" - android:minWidth="@dimen/status_indicator_width" - android:text="@string/new_label" - android:textAlignment="center" - android:textColor="@color/white" - android:textSize="@dimen/text_size_micro" - android:textStyle="bold" /> - - <ImageView - android:id="@+id/statusPlaying" - android:contentDescription="@string/status_playing_label" - android:layout_width="@dimen/status_indicator_width" - android:layout_height="18dp" - android:layout_alignParentRight="true" - android:layout_alignParentTop="true" - android:layout_margin="8dp" - android:background="@color/status_playing" - android:gravity="center" - android:padding="2dp" - android:src="@drawable/av_play_dark" /> + android:layout_width="@dimen/listview_secondary_button_width" + android:layout_height="match_parent" + android:background="?attr/borderless_button" + tools:ignore="ContentDescription"/> -</RelativeLayout>
\ No newline at end of file +</LinearLayout>
\ No newline at end of file diff --git a/src/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/src/de/danoeh/antennapod/adapter/ActionButtonUtils.java new file mode 100644 index 000000000..78d62a8de --- /dev/null +++ b/src/de/danoeh/antennapod/adapter/ActionButtonUtils.java @@ -0,0 +1,63 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.content.res.TypedArray; +import android.view.View; +import android.widget.ImageButton; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.storage.DownloadRequester; + +/** + * Utility methods for the action button that is displayed on the right hand side + * of a listitem. + */ +public class ActionButtonUtils { + + private final int[] labels; + private final TypedArray drawables; + private final Context context; + + public ActionButtonUtils(Context context) { + if (context == null) throw new IllegalArgumentException("context = null"); + this.context = context; + drawables = context.obtainStyledAttributes(new int[]{ + R.attr.av_play, R.attr.navigation_cancel, R.attr.av_download}); + labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label}; + } + + /** + * Sets the displayed bitmap and content description of the given + * action button so that it matches the state of the FeedItem. + */ + public void configureActionButton(ImageButton butSecondary, FeedItem item) { + if (butSecondary == null || item == null) throw new IllegalArgumentException("butSecondary or item was null"); + final FeedMedia media = item.getMedia(); + if (media != null) { + final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media); + if (!media.isDownloaded()) { + if (isDownloadingMedia) { + // item is being downloaded + butSecondary.setVisibility(View.VISIBLE); + butSecondary.setImageDrawable(drawables + .getDrawable(1)); + butSecondary.setContentDescription(context.getString(labels[1])); + } else { + // item is not downloaded and not being downloaded + butSecondary.setVisibility(View.VISIBLE); + butSecondary.setImageDrawable(drawables.getDrawable(2)); + butSecondary.setContentDescription(context.getString(labels[2])); + } + } else { + // item is not being downloaded + butSecondary.setVisibility(View.VISIBLE); + butSecondary + .setImageDrawable(drawables.getDrawable(0)); + butSecondary.setContentDescription(context.getString(labels[0])); + } + } else { + butSecondary.setVisibility(View.INVISIBLE); + } + } +} diff --git a/src/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/src/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java new file mode 100644 index 000000000..7c023d2c2 --- /dev/null +++ b/src/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java @@ -0,0 +1,45 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.widget.Toast; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.storage.DBTasks; +import de.danoeh.antennapod.storage.DownloadRequestException; +import de.danoeh.antennapod.storage.DownloadRequester; + +/** + * Default implementation of an ActionButtonCallback + */ +public class DefaultActionButtonCallback implements ActionButtonCallback { + private static final String TAG = "DefaultActionButtonCallback"; + + private final Context context; + + public DefaultActionButtonCallback(Context context) { + if (context == null) throw new IllegalArgumentException("context = null"); + this.context = context; + } + + @Override + public void onActionButtonPressed(final FeedItem item) { + final FeedMedia media = item.getMedia(); + boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); + if (!isDownloading && !media.isDownloaded()) { + try { + DBTasks.downloadFeedItems(context, item); + Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show(); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage()); + } + } else if (isDownloading) { + DownloadRequester.getInstance().cancelDownload(context, media); + Toast.makeText(context, R.string.download_cancelled_msg, Toast.LENGTH_SHORT).show(); + } else { // media is downloaded + DBTasks.playMedia(context, media, true, true, false); + } + } +} diff --git a/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java index 4681284f5..356d75d99 100644 --- a/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java +++ b/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java @@ -12,6 +12,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.feed.FeedItem; import de.danoeh.antennapod.feed.FeedMedia; import de.danoeh.antennapod.feed.MediaType; +import de.danoeh.antennapod.service.playback.PlayerStatus; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.Converter; import de.danoeh.antennapod.util.ThemeUtils; @@ -22,6 +23,7 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { private ActionButtonCallback callback; private boolean showFeedtitle; private int selectedItemIndex; + private final ActionButtonUtils actionButtonUtils; public static final int SELECTION_NONE = -1; @@ -32,6 +34,7 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { this.callback = callback; this.showFeedtitle = showFeedtitle; this.selectedItemIndex = SELECTION_NONE; + this.actionButtonUtils = new ActionButtonUtils(context); } @Override @@ -49,20 +52,12 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { holder.lenSize = (TextView) convertView .findViewById(R.id.txtvLenSize); holder.butAction = (ImageButton) convertView - .findViewById(R.id.butAction); + .findViewById(R.id.butSecondaryAction); holder.published = (TextView) convertView .findViewById(R.id.txtvPublished); holder.inPlaylist = (ImageView) convertView .findViewById(R.id.imgvInPlaylist); - holder.downloaded = (ImageView) convertView - .findViewById(R.id.imgvDownloaded); holder.type = (ImageView) convertView.findViewById(R.id.imgvType); - holder.downloading = (ImageView) convertView - .findViewById(R.id.imgvDownloading); - if (showFeedtitle) { - holder.feedtitle = (TextView) convertView - .findViewById(R.id.txtvFeedname); - } holder.statusPlaying = (View) convertView .findViewById(R.id.statusPlaying); holder.statusUnread = (View) convertView @@ -83,11 +78,13 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { convertView.setBackgroundResource(0); } - holder.title.setText(item.getTitle()); - if (showFeedtitle) { - holder.feedtitle.setVisibility(View.VISIBLE); - holder.feedtitle.setText(item.getFeed().getTitle()); - } + StringBuilder buffer = new StringBuilder(item.getTitle()); + if (showFeedtitle) { + buffer.append("("); + buffer.append(item.getFeed().getTitle()); + buffer.append(")"); + } + holder.title.setText(buffer.toString()); FeedItem.State state = item.getState(); switch (state) { @@ -104,12 +101,10 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { case NEW: holder.statusPlaying.setVisibility(View.GONE); holder.statusUnread.setVisibility(View.VISIBLE); - holder.episodeProgress.setVisibility(View.GONE); break; default: holder.statusPlaying.setVisibility(View.GONE); holder.statusUnread.setVisibility(View.GONE); - holder.episodeProgress.setVisibility(View.GONE); break; } @@ -121,11 +116,10 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { FeedMedia media = item.getMedia(); if (media == null) { - holder.downloaded.setVisibility(View.GONE); - holder.downloading.setVisibility(View.GONE); - holder.inPlaylist.setVisibility(View.GONE); - holder.type.setVisibility(View.GONE); - holder.lenSize.setVisibility(View.GONE); + holder.episodeProgress.setVisibility(View.GONE); + holder.inPlaylist.setVisibility(View.INVISIBLE); + holder.type.setVisibility(View.INVISIBLE); + holder.lenSize.setVisibility(View.INVISIBLE); } else { if (state == FeedItem.State.PLAYING @@ -153,19 +147,16 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { if (((ItemAccess) itemAccess).isInQueue(item)) { holder.inPlaylist.setVisibility(View.VISIBLE); } else { - holder.inPlaylist.setVisibility(View.GONE); - } - if (item.getMedia().isDownloaded()) { - holder.downloaded.setVisibility(View.VISIBLE); - } else { - holder.downloaded.setVisibility(View.GONE); + holder.inPlaylist.setVisibility(View.INVISIBLE); } if (DownloadRequester.getInstance().isDownloadingFile( item.getMedia())) { - holder.downloading.setVisibility(View.VISIBLE); - } else { - holder.downloading.setVisibility(View.GONE); + holder.episodeProgress.setVisibility(View.VISIBLE); + holder.episodeProgress.setProgress(((ItemAccess) itemAccess).getItemDownloadProgressPercent(item)); + } else if (!(state == FeedItem.State.IN_PROGRESS + || state == FeedItem.State.PLAYING)) { + holder.episodeProgress.setVisibility(View.GONE); } TypedArray typeDrawables = getContext().obtainStyledAttributes( @@ -187,14 +178,10 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { } } + actionButtonUtils.configureActionButton(holder.butAction, item); holder.butAction.setFocusable(false); - holder.butAction.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - callback.onActionButtonPressed(item); - } - }); + holder.butAction.setTag(item); + holder.butAction.setOnClickListener(butActionListener); } else { convertView.setVisibility(View.GONE); @@ -203,11 +190,16 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { } + private final OnClickListener butActionListener = new OnClickListener() { + @Override + public void onClick(View v) { + FeedItem item = (FeedItem) v.getTag(); + callback.onActionButtonPressed(item); + } + }; + static class Holder extends DefaultFeedItemlistAdapter.Holder { - TextView feedtitle; ImageView inPlaylist; - ImageView downloaded; - ImageView downloading; ImageButton butAction; View statusUnread; View statusPlaying; @@ -225,6 +217,8 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter { public static interface ItemAccess extends DefaultFeedItemlistAdapter.ItemAccess { public boolean isInQueue(FeedItem item); + + int getItemDownloadProgressPercent(FeedItem item); } } diff --git a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java index 4d4a2494e..d13314b0b 100644 --- a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java @@ -24,16 +24,15 @@ public class NewEpisodesListAdapter extends BaseAdapter { private final Context context; private final ItemAccess itemAccess; - private final TypedArray drawables; - private final int[] labels; + private final ActionButtonCallback actionButtonCallback; + private final ActionButtonUtils actionButtonUtils; - public NewEpisodesListAdapter(Context context, ItemAccess itemAccess) { + public NewEpisodesListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) { super(); this.context = context; this.itemAccess = itemAccess; - drawables = context.obtainStyledAttributes(new int[]{ - R.attr.av_play, R.attr.navigation_cancel, R.attr.av_download}); - labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label}; + this.actionButtonUtils = new ActionButtonUtils(context); + this.actionButtonCallback = actionButtonCallback; } @Override @@ -156,35 +155,17 @@ public class NewEpisodesListAdapter extends BaseAdapter { if (!media.isDownloaded()) { if (isDownloadingMedia) { // item is being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary.setImageDrawable(drawables - .getDrawable(1)); - holder.butSecondary.setContentDescription(context.getString(labels[1])); - holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); - } else { - // item is not downloaded and not being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary.setImageDrawable(drawables.getDrawable(2)); - holder.butSecondary.setContentDescription(context.getString(labels[2])); } - } else { - // item is not being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary - .setImageDrawable(drawables.getDrawable(0)); - holder.butSecondary.setContentDescription(context.getString(labels[0])); } - } else { - holder.butSecondary.setVisibility(View.INVISIBLE); } - if (itemAccess.isInQueue(item)) { holder.queueStatus.setVisibility(View.VISIBLE); } else { holder.queueStatus.setVisibility(View.INVISIBLE); } + actionButtonUtils.configureActionButton(holder.butSecondary, item); holder.butSecondary.setFocusable(false); holder.butSecondary.setTag(item); holder.butSecondary.setOnClickListener(secondaryActionListener); @@ -204,7 +185,7 @@ public class NewEpisodesListAdapter extends BaseAdapter { @Override public void onClick(View v) { FeedItem item = (FeedItem) v.getTag(); - itemAccess.onFeedItemSecondaryAction(item); + actionButtonCallback.onActionButtonPressed(item); } }; @@ -232,7 +213,5 @@ public class NewEpisodesListAdapter extends BaseAdapter { int getItemDownloadProgressPercent(FeedItem item); boolean isInQueue(FeedItem item); - - void onFeedItemSecondaryAction(FeedItem item); } } diff --git a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java index ae53f6837..c671f4a5c 100644 --- a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.adapter; import android.content.Context; -import android.content.res.TypedArray; import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; @@ -22,16 +21,16 @@ public class QueueListAdapter extends BaseAdapter { private final Context context; private final ItemAccess itemAccess; - private final TypedArray drawables; - private final int[] labels; + private final ActionButtonCallback actionButtonCallback; + private final ActionButtonUtils actionButtonUtils; - public QueueListAdapter(Context context, ItemAccess itemAccess) { + public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) { super(); this.context = context; this.itemAccess = itemAccess; - drawables = context.obtainStyledAttributes(new int[]{ - R.attr.av_play, R.attr.navigation_cancel, R.attr.av_download}); - labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label}; + this.actionButtonUtils = new ActionButtonUtils(context); + this.actionButtonCallback = actionButtonCallback; + } @Override @@ -104,33 +103,15 @@ public class QueueListAdapter extends BaseAdapter { holder.txtvDuration.setVisibility(View.VISIBLE); holder.downloadProgress.setVisibility(View.GONE); } - if (!media.isDownloaded()) { if (isDownloadingMedia) { // item is being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary.setImageDrawable(drawables - .getDrawable(1)); - holder.butSecondary.setContentDescription(context.getString(labels[1])); - holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); - } else { - // item is not downloaded and not being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary.setImageDrawable(drawables.getDrawable(2)); - holder.butSecondary.setContentDescription(context.getString(labels[2])); } - } else { - // item is not being downloaded - holder.butSecondary.setVisibility(View.VISIBLE); - holder.butSecondary - .setImageDrawable(drawables.getDrawable(0)); - holder.butSecondary.setContentDescription(context.getString(labels[0])); } - } else { - holder.butSecondary.setVisibility(View.INVISIBLE); } + actionButtonUtils.configureActionButton(holder.butSecondary, item); holder.butSecondary.setFocusable(false); holder.butSecondary.setTag(item); holder.butSecondary.setOnClickListener(secondaryActionListener); @@ -149,7 +130,7 @@ public class QueueListAdapter extends BaseAdapter { @Override public void onClick(View v) { FeedItem item = (FeedItem) v.getTag(); - itemAccess.onFeedItemSecondaryAction(item); + actionButtonCallback.onActionButtonPressed(item); } }; @@ -170,7 +151,5 @@ public class QueueListAdapter extends BaseAdapter { FeedItem getItem(int position); int getItemDownloadProgressPercent(FeedItem item); - - void onFeedItemSecondaryAction(FeedItem item); } } diff --git a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java index 8072d219b..dce64aa5e 100644 --- a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -6,30 +6,34 @@ import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.support.v4.app.ListFragment; import android.support.v7.app.ActionBarActivity; import android.text.util.Linkify; import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.ItemviewActivity; -import de.danoeh.antennapod.adapter.ActionButtonCallback; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.InternalFeedItemlistAdapter; +import de.danoeh.antennapod.asynctask.DownloadObserver; import de.danoeh.antennapod.asynctask.ImageLoader; import de.danoeh.antennapod.feed.EventDistributor; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; import de.danoeh.antennapod.service.download.DownloadService; +import de.danoeh.antennapod.service.download.Downloader; import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.QueueAccess; +import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** @@ -58,6 +62,9 @@ public class ItemlistFragment extends ListFragment { private AtomicReference<Activity> activity = new AtomicReference<Activity>(); + private DownloadObserver downloadObserver; + private List<Downloader> downloaderList; + /** * Creates new ItemlistFragment which shows the Feeditems of a specific @@ -112,12 +119,19 @@ public class ItemlistFragment extends ListFragment { adapter = null; viewsCreated = false; activity.set(null); + if (downloadObserver != null) { + downloadObserver.onPause(); + } } @Override public void onAttach(Activity activity) { super.onAttach(activity); this.activity.set(activity); + if (downloadObserver != null) { + downloadObserver.setActivity(activity); + downloadObserver.onResume(); + } if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -176,15 +190,35 @@ public class ItemlistFragment extends ListFragment { private void onFragmentLoaded() { if (adapter == null) { + getListView().setAdapter(null); setupHeaderView(); - adapter = new InternalFeedItemlistAdapter(getActivity(), itemAccess, actionButtonCallback, false); + adapter = new InternalFeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(activity.get()), false); setListAdapter(adapter); + downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); + downloadObserver.onResume(); } setListShown(true); adapter.notifyDataSetChanged(); } + private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { + @Override + public void onContentChanged() { + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onDownloadDataAvailable(List<Downloader> downloaderList) { + ItemlistFragment.this.downloaderList = downloaderList; + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + }; + private void setupHeaderView() { if (getListView() == null || feed == null) { Log.e(TAG, "Unable to setup listview: listView = null or feed = null"); @@ -224,16 +258,21 @@ public class ItemlistFragment extends ListFragment { public boolean isInQueue(FeedItem item) { return (queue != null) && queue.contains(item.getId()); } - }; - private ActionButtonCallback actionButtonCallback = new ActionButtonCallback() { @Override - public void onActionButtonPressed(FeedItem item) { - + 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 ItemLoader itemLoader; private void startItemLoader() { diff --git a/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java index cb5632d05..3377dc565 100644 --- a/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java +++ b/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java @@ -6,7 +6,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,6 +14,7 @@ import android.widget.TextView; import com.mobeta.android.dslv.DragSortListView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.NewEpisodesListAdapter; import de.danoeh.antennapod.asynctask.DownloadObserver; import de.danoeh.antennapod.feed.EventDistributor; @@ -127,7 +127,7 @@ public class NewEpisodesFragment extends Fragment { private void onFragmentLoaded() { if (listAdapter == null) { - listAdapter = new NewEpisodesListAdapter(activity.get(), itemAccess); + listAdapter = new NewEpisodesListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get())); listView.setAdapter(listAdapter); listView.setEmptyView(txtvEmpty); downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); @@ -198,11 +198,6 @@ public class NewEpisodesFragment extends Fragment { } } - @Override - public void onFeedItemSecondaryAction(FeedItem item) { - Log.i(TAG, item.getTitle()); - } - }; diff --git a/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index 1e4140b7b..a8627f12e 100644 --- a/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -4,12 +4,17 @@ import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.support.v4.app.ListFragment; import android.view.View; import de.danoeh.antennapod.adapter.ActionButtonCallback; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.InternalFeedItemlistAdapter; +import de.danoeh.antennapod.asynctask.DownloadObserver; import de.danoeh.antennapod.feed.EventDistributor; import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.service.download.Downloader; import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.util.QueueAccess; @@ -28,6 +33,9 @@ public class PlaybackHistoryFragment extends ListFragment { private AtomicReference<Activity> activity = new AtomicReference<Activity>(); + private DownloadObserver downloadObserver; + private List<Downloader> downloaderList; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -56,12 +64,19 @@ public class PlaybackHistoryFragment extends ListFragment { adapter = null; viewsCreated = false; activity.set(null); + if (downloadObserver != null) { + downloadObserver.onPause(); + } } @Override public void onAttach(Activity activity) { super.onAttach(activity); this.activity.set(activity); + if (downloadObserver != null) { + downloadObserver.setActivity(activity); + downloadObserver.onResume(); + } if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -88,14 +103,32 @@ public class PlaybackHistoryFragment extends ListFragment { private void onFragmentLoaded() { if (adapter == null) { - adapter = new InternalFeedItemlistAdapter(getActivity(), itemAccess, actionButtonCallback, true); + adapter = new InternalFeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(activity.get()), true); setListAdapter(adapter); + downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); + downloadObserver.onResume(); } setListShown(true); adapter.notifyDataSetChanged(); - } + private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { + @Override + public void onContentChanged() { + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onDownloadDataAvailable(List<Downloader> downloaderList) { + PlaybackHistoryFragment.this.downloaderList = downloaderList; + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + }; + private InternalFeedItemlistAdapter.ItemAccess itemAccess = new InternalFeedItemlistAdapter.ItemAccess() { @Override public boolean isInQueue(FeedItem item) { @@ -103,6 +136,19 @@ public class PlaybackHistoryFragment extends ListFragment { } @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; } @@ -113,13 +159,6 @@ public class PlaybackHistoryFragment extends ListFragment { } }; - private ActionButtonCallback actionButtonCallback = new ActionButtonCallback() { - @Override - public void onActionButtonPressed(FeedItem item) { - - } - }; - private ItemLoader itemLoader; private void startItemLoader() { diff --git a/src/de/danoeh/antennapod/fragment/QueueFragment.java b/src/de/danoeh/antennapod/fragment/QueueFragment.java index 73764df36..e88c7e178 100644 --- a/src/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/src/de/danoeh/antennapod/fragment/QueueFragment.java @@ -16,6 +16,7 @@ import android.widget.TextView; import com.mobeta.android.dslv.DragSortListView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.QueueListAdapter; import de.danoeh.antennapod.asynctask.DownloadObserver; import de.danoeh.antennapod.feed.EventDistributor; @@ -185,7 +186,7 @@ public class QueueFragment extends Fragment { private void onFragmentLoaded() { if (listAdapter == null) { - listAdapter = new QueueListAdapter(activity.get(), itemAccess); + listAdapter = new QueueListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get())); listView.setAdapter(listAdapter); downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); downloadObserver.onResume(); @@ -233,11 +234,6 @@ public class QueueFragment extends Fragment { } return 0; } - - @Override - public void onFeedItemSecondaryAction(FeedItem item) { - - } }; private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { |