diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2013-08-22 15:11:37 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2013-08-22 15:11:37 +0200 |
commit | 1376b5284849e198f2a2c8346d681d49d30a4234 (patch) | |
tree | f5670b1fdda7d7b1b70cf989579472689cc29367 | |
parent | 1c8dc43a7f4db4141480423b561b0824828779f5 (diff) | |
download | AntennaPod-1376b5284849e198f2a2c8346d681d49d30a4234.zip |
Improved AddFeedActivity layout, added gpodder.net toplist fragment
-rw-r--r-- | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | res/layout-v14/addfeed.xml | 69 | ||||
-rw-r--r-- | res/layout/addfeed.xml | 64 | ||||
-rw-r--r-- | res/layout/gpodnet_main.xml | 12 | ||||
-rw-r--r-- | res/layout/gpodnet_podcast_list.xml | 34 | ||||
-rw-r--r-- | res/layout/gpodnet_podcast_listitem.xml | 44 | ||||
-rw-r--r-- | res/values/ids.xml | 1 | ||||
-rw-r--r-- | res/values/strings.xml | 6 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/AddFeedActivity.java | 10 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java | 25 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java | 63 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/asynctask/ImageDiskCache.java | 54 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java | 109 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java | 27 |
14 files changed, 454 insertions, 68 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d99375a27..0d041079c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -320,6 +320,10 @@ android:configChanges="orientation" android:label="@string/organize_queue_label" > </activity> + <activity + android:name=".activity.gpoddernet.GpodnetMainActivity" + android:configChanges="orientation" + android:label="@string/gpodnet_main_label"/> <receiver android:name=".receiver.ConnectivityActionReceiver" > <intent-filter> diff --git a/res/layout-v14/addfeed.xml b/res/layout-v14/addfeed.xml index 14d3a2a67..5760bea95 100644 --- a/res/layout-v14/addfeed.xml +++ b/res/layout-v14/addfeed.xml @@ -1,20 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" > + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> <RelativeLayout android:id="@+id/footer" android:layout_width="fill_parent" android:layout_height="48dp" - android:layout_alignParentBottom="true" > + android:focusableInTouchMode="true" + android:layout_alignParentBottom="true"> <View android:layout_width="match_parent" android:layout_height="1dip" android:layout_alignParentTop="true" - android:background="?android:attr/dividerVertical" /> + android:background="?android:attr/dividerVertical"/> <View android:id="@+id/horizontal_divider" @@ -24,7 +25,7 @@ android:layout_centerHorizontal="true" android:layout_marginBottom="4dp" android:layout_marginTop="4dp" - android:background="?android:attr/dividerVertical" /> + android:background="?android:attr/dividerVertical"/> <Button android:id="@+id/butCancel" @@ -35,7 +36,7 @@ android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" - android:text="@string/cancel_label" /> + android:text="@string/cancel_label"/> <Button android:id="@+id/butConfirm" @@ -46,7 +47,7 @@ android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" - android:text="@string/confirm_label" /> + android:text="@string/confirm_label"/> </RelativeLayout> <ScrollView @@ -54,21 +55,22 @@ android:layout_height="0dp" android:layout_above="@id/footer" android:layout_alignParentTop="true" - android:scrollbars="vertical" > + android:scrollbars="vertical"> <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content" > + android:layout_height="wrap_content"> <TextView android:id="@+id/txtvFeedurl" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" - android:layout_margin="8dp" - android:focusable="true" - android:focusableInTouchMode="true" - android:text="@string/txtvfeedurl_label" /> + android:layout_margin="16dp" + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/txtvfeedurl_label"/> <EditText android:id="@+id/etxtFeedurl" @@ -77,23 +79,35 @@ android:layout_below="@id/txtvFeedurl" android:layout_margin="8dp" android:hint="@string/feedurl_label" - android:inputType="textUri" /> + android:inputType="textUri"/> <TextView - android:id="@+id/txtvBrowseMiroguide" + android:id="@+id/txtvPodcastDirectories" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/etxtFeedurl" android:layout_margin="8dp" - android:text="@string/txtv_browse_miroguide_label" /> + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/podcastdirectories_label"/> + + <Button + android:id="@+id/butBrowseGpoddernet" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/txtvPodcastDirectories" + android:layout_margin="8dp" + android:text="@string/gpodnet_main_label"/> <Button android:id="@+id/butBrowseMiroguide" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/txtvBrowseMiroguide" + android:layout_below="@id/butBrowseGpoddernet" android:layout_margin="8dp" - android:text="@string/browse_miroguide_label" /> + android:text="@string/miro_guide_label"/> + <TextView android:id="@+id/txtvOpmlImport" @@ -101,17 +115,28 @@ android:layout_height="wrap_content" android:layout_below="@id/butBrowseMiroguide" android:layout_margin="8dp" - android:text="@string/opml_import_txtv_button_lable" /> + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/opml_import_label"/> + + <TextView + android:id="@+id/txtvOpmlImportExpl" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/txtvOpmlImport" + android:layout_margin="8dp" + android:text="@string/opml_import_txtv_button_lable"/> <Button android:id="@+id/butOpmlImport" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/txtvOpmlImport" + android:layout_below="@id/txtvOpmlImportExpl" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" - android:text="@string/opml_import_label" /> + android:text="@string/opml_import_label"/> </RelativeLayout> </ScrollView> diff --git a/res/layout/addfeed.xml b/res/layout/addfeed.xml index 39552976b..bb72a2be1 100644 --- a/res/layout/addfeed.xml +++ b/res/layout/addfeed.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" > + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> <LinearLayout android:id="@+id/footer" @@ -10,21 +10,21 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" - android:orientation="horizontal" > + android:orientation="horizontal"> <Button android:id="@+id/butConfirm" android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="1" - android:text="@string/confirm_label" /> + android:text="@string/confirm_label"/> <Button android:id="@+id/butCancel" android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="1" - android:text="@string/cancel_label" /> + android:text="@string/cancel_label"/> </LinearLayout> <ScrollView @@ -32,21 +32,22 @@ android:layout_height="0dp" android:layout_above="@id/footer" android:layout_alignParentTop="true" - android:scrollbars="vertical" > + android:scrollbars="vertical"> <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content" > + android:layout_height="wrap_content"> <TextView android:id="@+id/txtvFeedurl" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" - android:layout_margin="8dp" - android:focusable="true" - android:focusableInTouchMode="true" - android:text="@string/txtvfeedurl_label" /> + android:layout_margin="16dp" + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/txtvfeedurl_label"/> <EditText android:id="@+id/etxtFeedurl" @@ -55,23 +56,35 @@ android:layout_below="@id/txtvFeedurl" android:layout_margin="8dp" android:hint="@string/feedurl_label" - android:inputType="textUri" /> + android:inputType="textUri"/> <TextView - android:id="@+id/txtvBrowseMiroguide" + android:id="@+id/txtvPodcastDirectories" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/etxtFeedurl" android:layout_margin="8dp" - android:text="@string/txtv_browse_miroguide_label" /> + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/podcastdirectories_label"/> + + <Button + android:id="@+id/butBrowseGpoddernet" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/txtvPodcastDirectories" + android:layout_margin="8dp" + android:text="@string/gpodnet_main_label"/> <Button android:id="@+id/butBrowseMiroguide" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/txtvBrowseMiroguide" + android:layout_below="@id/butBrowseGpoddernet" android:layout_margin="8dp" - android:text="@string/browse_miroguide_label" /> + android:text="@string/miro_guide_label"/> + <TextView android:id="@+id/txtvOpmlImport" @@ -79,17 +92,28 @@ android:layout_height="wrap_content" android:layout_below="@id/butBrowseMiroguide" android:layout_margin="8dp" - android:text="@string/opml_import_txtv_button_lable" /> + android:textSize="@dimen/text_size_large" + android:textColor="@color/bright_blue" + android:textStyle="italic" + android:text="@string/opml_import_label"/> + + <TextView + android:id="@+id/txtvOpmlImportExpl" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/txtvOpmlImport" + android:layout_margin="8dp" + android:text="@string/opml_import_txtv_button_lable"/> <Button android:id="@+id/butOpmlImport" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/txtvOpmlImport" + android:layout_below="@id/txtvOpmlImportExpl" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" - android:text="@string/opml_import_label" /> + android:text="@string/opml_import_label"/> </RelativeLayout> </ScrollView> diff --git a/res/layout/gpodnet_main.xml b/res/layout/gpodnet_main.xml new file mode 100644 index 000000000..7e382a641 --- /dev/null +++ b/res/layout/gpodnet_main.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"> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/toplist_fragment"/> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/gpodnet_podcast_list.xml b/res/layout/gpodnet_podcast_list.xml new file mode 100644 index 000000000..e69c2dbee --- /dev/null +++ b/res/layout/gpodnet_podcast_list.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <GridView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/gridView" + android:stretchMode="columnWidth" + android:numColumns="auto_fit" + android:verticalSpacing="4dp" + android:horizontalSpacing="4dp" + android:gravity="center" + android:columnWidth="200dp" + tools:listitem="@layout/gpodnet_podcast_listitem"/> + + <ProgressBar + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/progressBar" + android:layout_gravity="center" + android:indeterminateOnly="true"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/txtvError" + android:layout_gravity="center" + android:visibility="gone" + android:textSize="@dimen/text_size_small"/> +</FrameLayout>
\ No newline at end of file diff --git a/res/layout/gpodnet_podcast_listitem.xml b/res/layout/gpodnet_podcast_listitem.xml new file mode 100644 index 000000000..596eee136 --- /dev/null +++ b/res/layout/gpodnet_podcast_listitem.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <ImageView + android:id="@+id/imgvCover" + android:layout_width="@dimen/thumbnail_length" + android:layout_height="@dimen/thumbnail_length" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:layout_marginRight="4dip" + android:adjustViewBounds="true" + android:cropToPadding="true" + android:scaleType="fitXY" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="@dimen/thumbnail_length" + android:layout_centerVertical="true" + android:layout_toRightOf="@id/imgvCover" + android:layout_marginRight="8dp" + android:orientation="vertical" > + + <TextView + android:id="@+id/txtvTitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="1" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_small" /> + + <TextView + android:id="@+id/txtvDescription" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:maxLines="2" + android:ellipsize="end" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_micro" /> + + </LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/res/values/ids.xml b/res/values/ids.xml index 4d393e675..7cbc4699a 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -15,5 +15,6 @@ <item name="organize_queue_item" type="id"/> <item name="drag_handle" type="id"/> <item name="skip_episode_item" type="id"/> + <item name="image_disk_cache_key" type="id"/> </resources>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index b3f9975cb..78a92e249 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -17,6 +17,7 @@ <string name="cancel_download_label">Cancel Download</string> <string name="download_log_label">Download log</string> <string name="playback_history_label">Playback history</string> + <string name="gpodnet_main_label">gpodder.net</string> <!-- Webview actions --> <string name="open_in_browser_label">Open in browser</string> @@ -50,7 +51,8 @@ <!-- 'Add Feed' Activity labels --> <string name="feedurl_label">Feed URL</string> - <string name="txtvfeedurl_label">Type in the URL of the Feed here:</string> + <string name="txtvfeedurl_label">Add Podcast by URL</string> + <string name="podcastdirectories_label">Podcast directories</string> <!-- Actions on feeds --> <string name="mark_all_read_label">Mark all as read</string> @@ -229,8 +231,6 @@ <!-- Miro Guide --> <string name="loading_categories_label">Loading categories...</string> - <string name="browse_miroguide_label">Browse Miro Guide</string> - <string name="txtv_browse_miroguide_label">Or browse the Miro Guide:</string> <string name="miro_guide_label">Miro Guide</string> <string name="miro_search_hint">Search Miro Guide</string> <string name="popular_label">Popular</string> diff --git a/src/de/danoeh/antennapod/activity/AddFeedActivity.java b/src/de/danoeh/antennapod/activity/AddFeedActivity.java index 4085fc8d2..ad1adfa6b 100644 --- a/src/de/danoeh/antennapod/activity/AddFeedActivity.java +++ b/src/de/danoeh/antennapod/activity/AddFeedActivity.java @@ -5,6 +5,7 @@ import java.util.Date; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; +import de.danoeh.antennapod.activity.gpoddernet.GpodnetMainActivity; import org.apache.commons.lang3.StringUtils; import android.app.AlertDialog; @@ -37,6 +38,7 @@ public class AddFeedActivity extends ActionBarActivity { private EditText etxtFeedurl; private Button butBrowseMiroGuide; + private Button butBrowserGpoddernet; private Button butOpmlImport; private Button butConfirm; private Button butCancel; @@ -63,6 +65,7 @@ public class AddFeedActivity extends ActionBarActivity { } butBrowseMiroGuide = (Button) findViewById(R.id.butBrowseMiroguide); + butBrowserGpoddernet = (Button) findViewById(R.id.butBrowseGpoddernet); butOpmlImport = (Button) findViewById(R.id.butOpmlImport); butConfirm = (Button) findViewById(R.id.butConfirm); butCancel = (Button) findViewById(R.id.butCancel); @@ -75,6 +78,13 @@ public class AddFeedActivity extends ActionBarActivity { MiroGuideMainActivity.class)); } }); + butBrowserGpoddernet.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(AddFeedActivity.this, + GpodnetMainActivity.class)); + } + }); butOpmlImport.setOnClickListener(new OnClickListener() { diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java new file mode 100644 index 000000000..316ea2e88 --- /dev/null +++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java @@ -0,0 +1,25 @@ +package de.danoeh.antennapod.activity.gpoddernet; + +import android.os.Bundle; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.ActionBarActivity; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.fragment.gpodnet.PodcastTopListFragment; + +/** + * Created by daniel on 22.08.13. + */ +public class GpodnetMainActivity extends ActionBarActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.gpodnet_main); + FragmentTransaction transaction = getSupportFragmentManager() + .beginTransaction(); + PodcastTopListFragment topListFragment = new PodcastTopListFragment(); + transaction.replace(R.id.toplist_fragment, topListFragment); + transaction.commit(); + } +} diff --git a/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java new file mode 100644 index 000000000..795b17917 --- /dev/null +++ b/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java @@ -0,0 +1,63 @@ +package de.danoeh.antennapod.adapter.gpodnet; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.asynctask.ImageDiskCache; +import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast; + +import java.util.List; + +/** + * Adapter for displaying a list of GPodnetPodcast-Objects. + */ +public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> { + private final ImageDiskCache diskCache; + private final int thumbnailLength; + + public PodcastListAdapter(Context context, int resource, List<GpodnetPodcast> objects) { + super(context, resource, objects); + diskCache = ImageDiskCache.getDefaultInstance(); + thumbnailLength = (int) context.getResources().getDimension(R.dimen.thumbnail_length); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder; + + GpodnetPodcast podcast = getItem(position); + + // Inflate Layout + if (convertView == null) { + holder = new Holder(); + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + convertView = inflater.inflate(R.layout.gpodnet_podcast_listitem, null); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.description = (TextView) convertView.findViewById(R.id.txtvDescription); + holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); + + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + holder.title.setText(podcast.getTitle()); + holder.description.setText(podcast.getDescription()); + diskCache.loadThumbnailBitmap(podcast.getLogoUrl(), holder.image, thumbnailLength); + + return convertView; + } + + static class Holder { + TextView title; + TextView description; + ImageView image; + } +} diff --git a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java index 938f5d968..e0675982f 100644 --- a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java +++ b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java @@ -5,6 +5,7 @@ import android.util.Pair; import android.widget.ImageView; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.PodcastApp; +import de.danoeh.antennapod.R; import org.apache.commons.io.IOUtils; import java.io.*; @@ -59,7 +60,6 @@ public class ImageDiskCache { /** * Filename - cache object mapping */ - private static final int KEY_IMAGE_DISK_CACHE = 2; private static final String CACHE_FILE_NAME = "cachefile"; private ExecutorService executor; private ConcurrentHashMap<String, DiskCacheObject> diskCache; @@ -79,7 +79,8 @@ public class ImageDiskCache { } private synchronized void initCacheFolder() { - if (diskCache != null) { + if (diskCache == null) { + if (AppConfig.DEBUG) Log.d(TAG, "Initializing cache folder"); File cacheFile = new File(cacheFolder, CACHE_FILE_NAME); if (cacheFile.exists()) { try { @@ -178,21 +179,21 @@ public class ImageDiskCache { * be loaded from the disk. Otherwise, the image will be downloaded first. * The image will be stored in the thumbnail cache. */ - public synchronized void loadThumbnailBitmap(final String url, final ImageView target) { + public void loadThumbnailBitmap(final String url, final ImageView target, final int length) { final ImageLoader il = ImageLoader.getInstance(); if (diskCache != null) { DiskCacheObject dco = getFromCacheIfAvailable(url); if (dco != null) { - il.loadThumbnailBitmap(dco.loadImage(), target); + il.loadThumbnailBitmap(dco.loadImage(), target, length); return; } } - target.setTag(KEY_IMAGE_DISK_CACHE, url); + target.setTag(R.id.image_disk_cache_key, url); executor.submit(new ImageDownloader(url) { @Override protected void onImageLoaded(DiskCacheObject diskCacheObject) { - if (target.getTag(KEY_IMAGE_DISK_CACHE) == url) { - il.loadThumbnailBitmap(diskCacheObject.loadImage(), target); + if (target.getTag(R.id.image_disk_cache_key) == url) { + il.loadThumbnailBitmap(diskCacheObject.loadImage(), target, length); } } }); @@ -204,21 +205,21 @@ public class ImageDiskCache { * be loaded from the disk. Otherwise, the image will be downloaded first. * The image will be stored in the cover cache. */ - public synchronized void loadCoverBitmap(final String url, final ImageView target) { + public void loadCoverBitmap(final String url, final ImageView target, final int length) { final ImageLoader il = ImageLoader.getInstance(); if (diskCache != null) { DiskCacheObject dco = getFromCacheIfAvailable(url); if (dco != null) { - il.loadThumbnailBitmap(dco.loadImage(), target); + il.loadThumbnailBitmap(dco.loadImage(), target, length); return; } } - target.setTag(KEY_IMAGE_DISK_CACHE, url); + target.setTag(R.id.image_disk_cache_key, url); executor.submit(new ImageDownloader(url) { @Override protected void onImageLoaded(DiskCacheObject diskCacheObject) { - if (target.getTag(KEY_IMAGE_DISK_CACHE) == url) { - il.loadCoverBitmap(diskCacheObject.loadImage(), target); + if (target.getTag(R.id.image_disk_cache_key) == url) { + il.loadCoverBitmap(diskCacheObject.loadImage(), target, length); } } }); @@ -234,6 +235,20 @@ public class ImageDiskCache { if (cacheSize > maxCacheSize) { cleanup(); } + saveCacheInfoFile(); + } + + private synchronized void saveCacheInfoFile() { + OutputStream out = null; + try { + out = new BufferedOutputStream(new FileOutputStream(new File(cacheFolder, CACHE_FILE_NAME))); + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(diskCache); + } catch (IOException e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(out); + } } private synchronized DiskCacheObject getFromCacheIfAvailable(String key) { @@ -275,6 +290,7 @@ public class ImageDiskCache { final DiskCacheObject dco = new DiskCacheObject(newFile.getAbsolutePath(), size); addToDiskCache(downloadUrl, dco); + if (AppConfig.DEBUG) Log.d(TAG, "Image was downloaded"); onImageLoaded(dco); } catch (MalformedURLException e) { e.printStackTrace(); @@ -287,7 +303,7 @@ public class ImageDiskCache { } } - private static class DiskCacheObject { + private static class DiskCacheObject implements Serializable{ private final String fileUrl; /** @@ -311,7 +327,6 @@ public class ImageDiskCache { public ImageLoader.ImageWorkerTaskResource loadImage() { return new ImageLoader.ImageWorkerTaskResource() { - FileInputStream in = null; @Override public InputStream openImageInputStream() { @@ -325,15 +340,8 @@ public class ImageDiskCache { @Override public InputStream reopenImageInputStream(InputStream input) { - if (in != null) { - try { - in.close(); - return openImageInputStream(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return null; + IOUtils.closeQuietly(input); + return openImageInputStream(); } @Override diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java new file mode 100644 index 000000000..ba74d9d03 --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java @@ -0,0 +1,109 @@ +package de.danoeh.antennapod.fragment.gpodnet; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; +import android.widget.ProgressBar; +import android.widget.TextView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.adapter.gpodnet.PodcastListAdapter; +import de.danoeh.antennapod.gpoddernet.GpodnetService; +import de.danoeh.antennapod.gpoddernet.GpodnetServiceException; +import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast; + +import java.util.List; + +/** + * Displays a list of GPodnetPodcast-Objects in a GridView + */ +public abstract class PodcastListFragment extends Fragment { + private static final String TAG = "PodcastListFragment"; + + private GridView gridView; + private ProgressBar progressBar; + private TextView txtvError; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + setRetainInstance(true); + View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false); + + gridView = (GridView) root.findViewById(R.id.gridView); + progressBar = (ProgressBar) root.findViewById(R.id.progressBar); + txtvError = (TextView) root.findViewById(R.id.txtvError); + + gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position)); + } + }); + + loadData(); + return root; + } + + protected abstract void onPodcastSelected(GpodnetPodcast selection); + + protected abstract List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException; + + private void loadData() { + AsyncTask<Void, Void, List<GpodnetPodcast>> loaderTask = new AsyncTask<Void, Void, List<GpodnetPodcast>>() { + volatile Exception exception = null; + + @Override + protected List<GpodnetPodcast> doInBackground(Void... params) { + GpodnetService service = null; + try { + service = new GpodnetService(); + return loadPodcastData(service); + } catch (GpodnetServiceException e) { + exception = e; + e.printStackTrace(); + return null; + } finally { + if (service != null) { + service.shutdown(); + } + } + } + + @Override + protected void onPostExecute(List<GpodnetPodcast> gpodnetPodcasts) { + super.onPostExecute(gpodnetPodcasts); + final Context context = getActivity(); + if (context != null && gpodnetPodcasts != null) { + PodcastListAdapter listAdapter = new PodcastListAdapter(context, 0, gpodnetPodcasts); + gridView.setAdapter(listAdapter); + listAdapter.notifyDataSetChanged(); + + progressBar.setVisibility(View.GONE); + gridView.setVisibility(View.VISIBLE); + } else if (context != null) { + gridView.setVisibility(View.GONE); + progressBar.setVisibility(View.GONE); + txtvError.setText(getString(R.string.error_msg_prefix) + exception.getMessage()); + } + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + // gridView.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + } + }; + + if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { + loaderTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + loaderTask.execute(); + } + } +} diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java new file mode 100644 index 000000000..4e7e42aa3 --- /dev/null +++ b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java @@ -0,0 +1,27 @@ +package de.danoeh.antennapod.fragment.gpodnet; + +import android.util.Log; +import de.danoeh.antennapod.AppConfig; +import de.danoeh.antennapod.gpoddernet.GpodnetService; +import de.danoeh.antennapod.gpoddernet.GpodnetServiceException; +import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast; + +import java.util.List; + +/** + * + */ +public class PodcastTopListFragment extends PodcastListFragment { + private static final String TAG = "PodcastTopListFragment"; + private static final int PODCAST_COUNT = 50; + + @Override + protected void onPodcastSelected(GpodnetPodcast selection) { + if (AppConfig.DEBUG) Log.d(TAG, "Selected: " + selection.getTitle()); + } + + @Override + protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException { + return service.getPodcastToplist(PODCAST_COUNT); + } +} |