diff options
-rw-r--r-- | res/layout/downloaded_episodeslist_item.xml | 111 | ||||
-rw-r--r-- | res/layout/downloadlist_item.xml | 99 | ||||
-rw-r--r-- | res/layout/downloads_fragment.xml | 12 | ||||
-rw-r--r-- | res/values/strings.xml | 6 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/DownloadActivity.java | 4 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/MainActivity.java | 8 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java | 124 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/adapter/DownloadlistAdapter.java | 207 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java | 159 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/DownloadLogFragment.java | 121 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/DownloadsFragment.java | 133 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java | 69 |
12 files changed, 932 insertions, 121 deletions
diff --git a/res/layout/downloaded_episodeslist_item.xml b/res/layout/downloaded_episodeslist_item.xml new file mode 100644 index 000000000..35b3dbf9a --- /dev/null +++ b/res/layout/downloaded_episodeslist_item.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:orientation="horizontal" + android:layout_height="match_parent"> + + <RelativeLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:layout_marginRight="16dp"> + + <ImageView + android:id="@+id/imgvImage" + android:contentDescription="@string/cover_label" + android:layout_width="@dimen/thumbnail_length_itemlist" + android:layout_height="@dimen/thumbnail_length_itemlist" + android:layout_alignParentLeft="true" + android:scaleType="centerCrop"/> + + <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_marginBottom="8dp" + android:layout_marginTop="8dp" + android:layout_marginLeft="8dp" + android:background="@color/status_playing" + android:gravity="center" + android:padding="2dp" + android:src="@drawable/av_play_dark"/> + + <TextView + android:id="@+id/txtvPublished" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginLeft="8dp" + android:layout_marginRight="8dp" + android:layout_alignParentTop="true" + android:layout_toRightOf="@id/imgvImage" + android:layout_toLeftOf="@id/statusPlaying" + android:ellipsize="end" + android:maxLines="1" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_micro"/> + + <TextView + android:id="@+id/txtvTitle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_below="@id/txtvPublished" + android:layout_marginLeft="8dp" + android:layout_marginRight="4dp" + android:layout_marginTop="2dp" + android:layout_toRightOf="@id/imgvImage" + android:layout_toLeftOf="@id/statusPlaying" + android:ellipsize="end" + android:lines="2" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_small"/> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentRight="true" + android:layout_toRightOf="@id/imgvImage" + android:orientation="vertical"> + + <RelativeLayout + android:id="@+id/bottom_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/txtvSize" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="8dp" + android:layout_marginRight="8dp" + android:layout_alignParentLeft="true" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_micro"/> + </RelativeLayout> + </LinearLayout> + </RelativeLayout> + + <View + android:layout_width="1dp" + android:layout_height="match_parent" + android:background="@drawable/vertical_divider" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp"/> + + <ImageButton + android:id="@+id/butSecondaryAction" + android:contentDescription="@string/remove_episode_lable" + android:focusable="false" + android:clickable="false" + android:focusableInTouchMode="false" + android:layout_width="@dimen/listview_secondary_button_width" + android:layout_height="match_parent" + android:background="?attr/borderless_button" + android:src="?attr/content_discard" + /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/downloadlist_item.xml b/res/layout/downloadlist_item.xml index 688a64876..a0a589175 100644 --- a/res/layout/downloadlist_item.xml +++ b/res/layout/downloadlist_item.xml @@ -1,46 +1,73 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" > - - <TextView - android:id="@+id/txtvTitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="8dp" - android:layout_marginTop="8dp" - android:textStyle="bold" /> - - <TextView - android:id="@+id/txtvMessage" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="8dp" /> - - <ProgressBar - android:id="@+id/progProgress" - style="?android:attr/progressBarStyleHorizontal" - android:layout_width="match_parent" - android:layout_height="16dp" - android:layout_margin="8dp" /> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="8dp" > + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal"> + + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="match_parent" + android:orientation="vertical"> <TextView - android:id="@+id/txtvDownloaded" - android:layout_width="wrap_content" + android:id="@+id/txtvTitle" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" /> + android:layout_marginLeft="8dp" + android:layout_marginTop="8dp" + android:textStyle="bold"/> <TextView - android:id="@+id/txtvPercent" - android:layout_width="wrap_content" + android:id="@+id/txtvMessage" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="8dp"/> + + <ProgressBar + android:id="@+id/progProgress" + style="?android:attr/progressBarStyleHorizontal" + android:layout_width="match_parent" + android:layout_height="16dp" + android:layout_margin="8dp"/> + + <RelativeLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_alignParentRight="true" /> - </RelativeLayout> + android:layout_margin="8dp"> + + <TextView + android:id="@+id/txtvDownloaded" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true"/> + + <TextView + android:id="@+id/txtvPercent" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true"/> + </RelativeLayout> + + </LinearLayout> + + + <View + android:layout_width="1dp" + android:layout_height="match_parent" + android:background="@drawable/vertical_divider" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp"/> + <ImageButton + android:id="@+id/butSecondaryAction" + android:contentDescription="@string/cancel_download_label" + android:focusable="false" + android:clickable="false" + android:focusableInTouchMode="false" + android:layout_width="@dimen/listview_secondary_button_width" + android:layout_height="match_parent" + android:background="?attr/borderless_button" + android:src="?attr/navigation_cancel" + /> </LinearLayout>
\ No newline at end of file diff --git a/res/layout/downloads_fragment.xml b/res/layout/downloads_fragment.xml new file mode 100644 index 000000000..cb7ae0151 --- /dev/null +++ b/res/layout/downloads_fragment.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <android.support.v4.view.ViewPager + android:id="@+id/pager" + android:layout_width="match_parent" + android:layout_height="match_parent"/> +</LinearLayout>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index ca448f8a8..7cbe075d3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4,7 +4,7 @@ tools:ignore="MissingTranslation" > - <!-- Activitiy titles --> + <!-- Activitiy and fragment titles --> <string name="app_name">AntennaPod</string> <string name="feeds_label">Feeds</string> <string name="podcasts_label">PODCASTS</string> @@ -15,6 +15,9 @@ <string name="settings_label">Settings</string> <string name="add_new_feed_label">Add podcast</string> <string name="downloads_label">Downloads</string> + <string name="downloads_running_label">Running</string> + <string name="downloads_completed_label">Completed</string> + <string name="downloads_log_label">Log</string> <string name="cancel_download_label">Cancel Download</string> <string name="download_log_label">Download log</string> <string name="playback_history_label">Playback history</string> @@ -84,6 +87,7 @@ <string name="pause_label">Pause</string> <string name="stream_label">Stream</string> <string name="remove_label">Remove</string> + <string name="remove_episode_lable">Remove episode</string> <string name="mark_read_label">Mark as read</string> <string name="mark_unread_label">Mark as unread</string> <string name="add_to_queue_label">Add to Queue</string> diff --git a/src/de/danoeh/antennapod/activity/DownloadActivity.java b/src/de/danoeh/antennapod/activity/DownloadActivity.java index 996929cdb..416de73a4 100644 --- a/src/de/danoeh/antennapod/activity/DownloadActivity.java +++ b/src/de/danoeh/antennapod/activity/DownloadActivity.java @@ -180,8 +180,8 @@ public class DownloadActivity extends ActionBarActivity implements @Override public void onDownloadDataAvailable(List<Downloader> downloaderList) { - dla = new DownloadlistAdapter(DownloadActivity.this, 0, - downloaderList); + //dla = new DownloadlistAdapter(DownloadActivity.this, 0, + // downloaderList); listview.setAdapter(dla); dla.notifyDataSetChanged(); } diff --git a/src/de/danoeh/antennapod/activity/MainActivity.java b/src/de/danoeh/antennapod/activity/MainActivity.java index 3b2cc52e9..90be7f0fc 100644 --- a/src/de/danoeh/antennapod/activity/MainActivity.java +++ b/src/de/danoeh/antennapod/activity/MainActivity.java @@ -16,6 +16,7 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.util.Log; @@ -118,6 +119,10 @@ public class MainActivity extends ActionBarActivity { } + public ActionBar getMainActivtyActionBar() { + return getSupportActionBar(); + } + private void loadFragment(int viewType, int relPos) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fT = fragmentManager.beginTransaction(); @@ -130,6 +135,9 @@ public class MainActivity extends ActionBarActivity { case 1: fragment = new QueueFragment(); break; + case 2: + fragment = new DownloadsFragment(); + break; } currentTitle = getString(NavListAdapter.NAV_TITLES[relPos]); diff --git a/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java new file mode 100644 index 000000000..e873a9e5a --- /dev/null +++ b/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java @@ -0,0 +1,124 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.text.format.DateUtils; +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 de.danoeh.antennapod.R; +import de.danoeh.antennapod.asynctask.ImageLoader; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.util.Converter; + +/** + * Shows a list of downloaded episodes + */ +public class DownloadedEpisodesListAdapter extends BaseAdapter { + + private final Context context; + private final ItemAccess itemAccess; + + public DownloadedEpisodesListAdapter(Context context, ItemAccess itemAccess) { + super(); + this.context = context; + this.itemAccess = itemAccess; + } + + @Override + public int getCount() { + return itemAccess.getCount(); + } + + @Override + public Object getItem(int position) { + return itemAccess.getItem(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder; + final FeedItem item = (FeedItem) getItem(position); + if (item == null) return null; + + if (convertView == null) { + holder = new Holder(); + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.downloaded_episodeslist_item, + null); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.pubDate = (TextView) convertView + .findViewById(R.id.txtvPublished); + holder.butSecondary = (ImageButton) convertView + .findViewById(R.id.butSecondaryAction); + holder.statusPlaying = (ImageView) convertView + .findViewById(R.id.statusPlaying); + holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); + holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize); + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + holder.title.setText(item.getTitle()); + holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_SHOW_DATE)); + holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize())); + FeedItem.State state = item.getState(); + + if (state == FeedItem.State.PLAYING) { + holder.statusPlaying.setVisibility(View.VISIBLE); + holder.butSecondary.setEnabled(false); + } else { + holder.butSecondary.setEnabled(true); + holder.statusPlaying.setVisibility(View.INVISIBLE); + } + + holder.butSecondary.setFocusable(false); + holder.butSecondary.setTag(item); + holder.butSecondary.setOnClickListener(secondaryActionListener); + + + ImageLoader.getInstance().loadThumbnailBitmap( + item, + holder.imageView, + (int) convertView.getResources().getDimension( + R.dimen.thumbnail_length) + ); + return convertView; + } + + private View.OnClickListener secondaryActionListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + FeedItem item = (FeedItem) v.getTag(); + itemAccess.onFeedItemSecondaryAction(item); + } + }; + + + static class Holder { + TextView title; + TextView pubDate; + ImageView imageView; + ImageView statusPlaying; + TextView txtvSize; + ImageButton butSecondary; + } + + public interface ItemAccess { + int getCount(); + + FeedItem getItem(int position); + + void onFeedItemSecondaryAction(FeedItem item); + } +} diff --git a/src/de/danoeh/antennapod/adapter/DownloadlistAdapter.java b/src/de/danoeh/antennapod/adapter/DownloadlistAdapter.java index 2739d2f27..fa2e5a0a7 100644 --- a/src/de/danoeh/antennapod/adapter/DownloadlistAdapter.java +++ b/src/de/danoeh/antennapod/adapter/DownloadlistAdapter.java @@ -4,7 +4,8 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; +import android.widget.BaseAdapter; +import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.TextView; import de.danoeh.antennapod.R; @@ -14,86 +15,128 @@ import de.danoeh.antennapod.service.download.Downloader; import de.danoeh.antennapod.util.Converter; import de.danoeh.antennapod.util.ThemeUtils; -import java.util.List; - -public class DownloadlistAdapter extends ArrayAdapter<Downloader> { - private int selectedItemIndex; - - public static final int SELECTION_NONE = -1; - - public DownloadlistAdapter(Context context, int textViewResourceId, - List<Downloader> objects) { - super(context, textViewResourceId, objects); - this.selectedItemIndex = SELECTION_NONE; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - Holder holder; - DownloadRequest request = getItem(position).getDownloadRequest(); - // Inflate layout - if (convertView == null) { - holder = new Holder(); - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.downloadlist_item, null); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.message = (TextView) convertView - .findViewById(R.id.txtvMessage); - holder.downloaded = (TextView) convertView - .findViewById(R.id.txtvDownloaded); - holder.percent = (TextView) convertView - .findViewById(R.id.txtvPercent); - holder.progbar = (ProgressBar) convertView - .findViewById(R.id.progProgress); - - convertView.setTag(holder); - } else { - holder = (Holder) convertView.getTag(); - } - - if (position == selectedItemIndex) { - convertView.setBackgroundColor(convertView.getResources().getColor( - ThemeUtils.getSelectionBackgroundColor())); - } else { - convertView.setBackgroundResource(0); - } - - holder.title.setText(request.getTitle()); - if (request.getStatusMsg() != 0) { - holder.message.setText(request.getStatusMsg()); - } - 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); - } - - holder.downloaded.setText(strDownloaded); - - return convertView; - } - - static class Holder { - TextView title; - TextView message; - TextView downloaded; - TextView percent; - ProgressBar progbar; - } - - public int getSelectedItemIndex() { - return selectedItemIndex; - } - - public void setSelectedItemIndex(int selectedItemIndex) { - this.selectedItemIndex = selectedItemIndex; - notifyDataSetChanged(); - } +public class DownloadlistAdapter extends BaseAdapter { + + public static final int SELECTION_NONE = -1; + + private int selectedItemIndex; + private ItemAccess itemAccess; + private Context context; + + public DownloadlistAdapter(Context context, + ItemAccess itemAccess) { + super(); + this.selectedItemIndex = SELECTION_NONE; + this.context = context; + this.itemAccess = itemAccess; + } + + @Override + public int getCount() { + return itemAccess.getCount(); + } + + @Override + public Downloader getItem(int position) { + return itemAccess.getItem(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + 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); + convertView = inflater.inflate(R.layout.downloadlist_item, null); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.message = (TextView) convertView + .findViewById(R.id.txtvMessage); + holder.downloaded = (TextView) convertView + .findViewById(R.id.txtvDownloaded); + holder.percent = (TextView) convertView + .findViewById(R.id.txtvPercent); + holder.progbar = (ProgressBar) convertView + .findViewById(R.id.progProgress); + holder.butSecondary = (ImageButton) convertView + .findViewById(R.id.butSecondaryAction); + + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + if (position == selectedItemIndex) { + convertView.setBackgroundColor(convertView.getResources().getColor( + ThemeUtils.getSelectionBackgroundColor())); + } else { + convertView.setBackgroundResource(0); + } + + holder.title.setText(request.getTitle()); + if (request.getStatusMsg() != 0) { + holder.message.setText(request.getStatusMsg()); + } + 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); + } + + holder.downloaded.setText(strDownloaded); + + holder.butSecondary.setFocusable(false); + holder.butSecondary.setTag(downloader); + holder.butSecondary.setOnClickListener(butSecondaryListener); + + return convertView; + } + + private View.OnClickListener butSecondaryListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + Downloader downloader = (Downloader) v.getTag(); + itemAccess.onSecondaryActionClick(downloader); + } + }; + + static class Holder { + TextView title; + TextView message; + TextView downloaded; + TextView percent; + ProgressBar progbar; + ImageButton butSecondary; + } + + public int getSelectedItemIndex() { + return selectedItemIndex; + } + + public void setSelectedItemIndex(int selectedItemIndex) { + this.selectedItemIndex = selectedItemIndex; + notifyDataSetChanged(); + } + + public interface ItemAccess { + public int getCount(); + + public Downloader getItem(int position); + + public void onSecondaryActionClick(Downloader downloader); + } } diff --git a/src/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/src/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java new file mode 100644 index 000000000..fe661a38a --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -0,0 +1,159 @@ +package de.danoeh.antennapod.fragment; + +import android.app.Activity; +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.View; +import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter; +import de.danoeh.antennapod.feed.EventDistributor; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.storage.DBReader; +import de.danoeh.antennapod.storage.DBWriter; + +import java.util.List; + +/** + * Displays all running downloads and provides a button to delete them + */ +public class CompletedDownloadsFragment extends ListFragment { + private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | + EventDistributor.DOWNLOADLOG_UPDATE | + EventDistributor.QUEUE_UPDATE | + EventDistributor.UNREAD_ITEMS_UPDATE; + + private List<FeedItem> items; + private DownloadedEpisodesListAdapter listAdapter; + + private boolean viewCreated = false; + private boolean itemsLoaded = false; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + startItemLoader(); + } + + @Override + public void onStart() { + super.onStart(); + EventDistributor.getInstance().register(contentUpdate); + } + + @Override + public void onStop() { + super.onStop(); + EventDistributor.getInstance().unregister(contentUpdate); + stopItemLoader(); + } + + @Override + public void onDetach() { + super.onDetach(); + stopItemLoader(); + listAdapter = null; + viewCreated = false; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + if (viewCreated && itemsLoaded) { + onFragmentLoaded(); + } + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + viewCreated = true; + if (itemsLoaded && getActivity() != null) { + onFragmentLoaded(); + } + } + + private void onFragmentLoaded() { + if (listAdapter == null) { + listAdapter = new DownloadedEpisodesListAdapter(getActivity(), itemAccess); + setListAdapter(listAdapter); + } + listAdapter.notifyDataSetChanged(); + } + + private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() { + @Override + public int getCount() { + return (items != null) ? items.size() : 0; + } + + @Override + public FeedItem getItem(int position) { + return (items != null) ? items.get(position) : null; + } + + @Override + public void onFeedItemSecondaryAction(FeedItem item) { + DBWriter.deleteFeedMediaOfItem(getActivity(), item.getMedia().getId()); + } + }; + + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { + @Override + public void update(EventDistributor eventDistributor, Integer arg) { + if ((arg & EVENTS) != 0) { + startItemLoader(); + } + } + }; + + private ItemLoader itemLoader; + + private void startItemLoader() { + if (itemLoader != null) { + itemLoader.cancel(true); + } + itemLoader = new ItemLoader(); + itemLoader.execute(); + } + + private void stopItemLoader() { + if (itemLoader != null) { + itemLoader.cancel(true); + } + } + + private class ItemLoader extends AsyncTask<Void, Void, List<FeedItem>> { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + if (!itemsLoaded && viewCreated) { + setListShown(false); + } + } + + @Override + protected void onPostExecute(List<FeedItem> feedItems) { + super.onPostExecute(feedItems); + setListShown(true); + if (feedItems != null) { + items = feedItems; + itemsLoaded = true; + if (viewCreated && getActivity() != null) { + onFragmentLoaded(); + } + } + } + + @Override + protected List<FeedItem> doInBackground(Void... params) { + Context context = getActivity(); + if (context != null) { + return DBReader.getDownloadedItems(context); + } + return null; + } + } +} diff --git a/src/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/src/de/danoeh/antennapod/fragment/DownloadLogFragment.java new file mode 100644 index 000000000..d81ba4b86 --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -0,0 +1,121 @@ +package de.danoeh.antennapod.fragment; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.View; +import de.danoeh.antennapod.adapter.DownloadLogAdapter; +import de.danoeh.antennapod.feed.EventDistributor; +import de.danoeh.antennapod.service.download.DownloadStatus; +import de.danoeh.antennapod.storage.DBReader; + +import java.util.List; + +/** + * Shows the download log + */ +public class DownloadLogFragment extends ListFragment { + + private List<DownloadStatus> downloadLog; + private DownloadLogAdapter adapter; + + private boolean viewsCreated = false; + private boolean itemsLoaded = false; + + @Override + public void onStart() { + super.onStart(); + EventDistributor.getInstance().register(contentUpdate); + startItemLoader(); + } + + @Override + public void onStop() { + super.onStop(); + EventDistributor.getInstance().unregister(contentUpdate); + stopItemLoader(); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + viewsCreated = true; + if (itemsLoaded) { + onFragmentLoaded(); + } + } + + private void onFragmentLoaded() { + if (adapter == null) { + adapter = new DownloadLogAdapter(getActivity(), itemAccess); + setListAdapter(adapter); + } + setListShown(true); + adapter.notifyDataSetChanged(); + + } + + private DownloadLogAdapter.ItemAccess itemAccess = new DownloadLogAdapter.ItemAccess() { + + @Override + public int getCount() { + return (downloadLog != null) ? downloadLog.size() : 0; + } + + @Override + public DownloadStatus getItem(int position) { + return (downloadLog != null) ? downloadLog.get(position) : null; + } + }; + + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { + + @Override + public void update(EventDistributor eventDistributor, Integer arg) { + if ((arg & EventDistributor.DOWNLOADLOG_UPDATE) != 0) { + startItemLoader(); + } + } + }; + + private ItemLoader itemLoader; + + private void startItemLoader() { + if (itemLoader != null) { + itemLoader.cancel(true); + } + itemLoader = new ItemLoader(); + itemLoader.execute(); + } + + private void stopItemLoader() { + if (itemLoader != null) { + itemLoader.cancel(true); + } + } + + private class ItemLoader extends AsyncTask<Void, Void, List<DownloadStatus>> { + + @Override + protected void onPostExecute(List<DownloadStatus> downloadStatuses) { + super.onPostExecute(downloadStatuses); + if (downloadStatuses != null) { + downloadLog = downloadStatuses; + itemsLoaded = true; + if (viewsCreated) { + onFragmentLoaded(); + } + } + } + + @Override + protected List<DownloadStatus> doInBackground(Void... params) { + Context context = getActivity(); + if (context != null) { + return DBReader.getDownloadLog(context); + } + return null; + } + } +} diff --git a/src/de/danoeh/antennapod/fragment/DownloadsFragment.java b/src/de/danoeh/antennapod/fragment/DownloadsFragment.java new file mode 100644 index 000000000..f19edd409 --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/DownloadsFragment.java @@ -0,0 +1,133 @@ +package de.danoeh.antennapod.fragment; + +import android.app.Activity; +import android.content.res.Resources; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; + +/** + * Shows the CompletedDownloadsFragment and the RunningDownloadsFragment + */ +public class DownloadsFragment extends Fragment { + + + private ViewPager pager; + private MainActivity activity; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + View root = inflater.inflate(R.layout.downloads_fragment, container, false); + pager = (ViewPager) root.findViewById(R.id.pager); + DownloadsPagerAdapter pagerAdapter = new DownloadsPagerAdapter(getChildFragmentManager(), getResources()); + pager.setAdapter(pagerAdapter); + final ActionBar actionBar = activity.getMainActivtyActionBar(); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + ActionBar.TabListener tabListener = new ActionBar.TabListener() { + @Override + public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { + pager.setCurrentItem(tab.getPosition()); + } + + @Override + public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { + + } + + @Override + public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { + + } + }; + actionBar.removeAllTabs(); + actionBar.addTab(actionBar.newTab() + .setText(R.string.downloads_running_label) + .setTabListener(tabListener)); + actionBar.addTab(actionBar.newTab() + .setText(R.string.downloads_completed_label) + .setTabListener(tabListener)); + actionBar.addTab(actionBar.newTab() + .setText(R.string.downloads_log_label) + .setTabListener(tabListener)); + + pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + actionBar.setSelectedNavigationItem(position); + } + }); + return root; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + this.activity = (MainActivity) activity; + } + + @Override + public void onDetach() { + super.onDetach(); + activity.getMainActivtyActionBar().removeAllTabs(); + activity.getMainActivtyActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); + } + + public class DownloadsPagerAdapter extends FragmentPagerAdapter { + + private final int POS_RUNNING = 0; + private final int POS_COMPLETED = 1; + private final int POS_LOG = 2; + + + Resources resources; + + public DownloadsPagerAdapter(FragmentManager fm, Resources resources) { + super(fm); + this.resources = resources; + } + + @Override + public Fragment getItem(int position) { + switch (position) { + case POS_RUNNING: + return new RunningDownloadsFragment(); + case POS_COMPLETED: + return new CompletedDownloadsFragment(); + case POS_LOG: + return new DownloadLogFragment(); + default: + return null; + } + } + + @Override + public int getCount() { + return 3; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case POS_RUNNING: + return resources.getString(R.string.downloads_running_label); + case POS_COMPLETED: + return resources.getString(R.string.downloads_completed_label); + case POS_LOG: + return resources.getString(R.string.downloads_log_label); + default: + return super.getPageTitle(position); + } + } + } +} diff --git a/src/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/src/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java new file mode 100644 index 000000000..89c30e34b --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java @@ -0,0 +1,69 @@ +package de.danoeh.antennapod.fragment; + +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.ListFragment; +import android.view.View; +import de.danoeh.antennapod.adapter.DownloadlistAdapter; +import de.danoeh.antennapod.asynctask.DownloadObserver; +import de.danoeh.antennapod.service.download.Downloader; +import de.danoeh.antennapod.storage.DownloadRequester; + +import java.util.List; + +/** + * Displays all running downloads and provides actions to cancel them + */ +public class RunningDownloadsFragment extends ListFragment { + private static final String TAG = "RunningDownloadsFragment"; + + private DownloadObserver downloadObserver; + private List<Downloader> downloaderList; + + + @Override + public void onDetach() { + super.onDetach(); + if (downloadObserver != null) { + downloadObserver.onPause(); + } + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + final DownloadlistAdapter downloadlistAdapter = new DownloadlistAdapter(getActivity(), itemAccess); + setListAdapter(downloadlistAdapter); + + downloadObserver = new DownloadObserver(getActivity(), new Handler(), new DownloadObserver.Callback() { + @Override + public void onContentChanged() { + downloadlistAdapter.notifyDataSetChanged(); + } + + @Override + public void onDownloadDataAvailable(List<Downloader> downloaderList) { + RunningDownloadsFragment.this.downloaderList = downloaderList; + downloadlistAdapter.notifyDataSetChanged(); + } + }); + downloadObserver.onResume(); + } + + private DownloadlistAdapter.ItemAccess itemAccess = new DownloadlistAdapter.ItemAccess() { + @Override + public int getCount() { + return (downloaderList != null) ? downloaderList.size() : 0; + } + + @Override + public Downloader getItem(int position) { + return (downloaderList != null) ? downloaderList.get(position) : null; + } + + @Override + public void onSecondaryActionClick(Downloader downloader) { + DownloadRequester.getInstance().cancelDownload(getActivity(), downloader.getDownloadRequest().getSource()); + } + }; +} |