Replaced FeedItemDialog with ItemFragment

This commit is contained in:
daniel oeh 2014-12-17 21:58:43 +01:00
parent 120db7ae7e
commit ab772e55f5
14 changed files with 617 additions and 654 deletions

View File

@ -89,7 +89,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
setContentView(R.layout.main);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerTitle = currentTitle = getTitle();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
@ -252,6 +253,14 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
.commit();
}
public void dismissChildFragment() {
getSupportFragmentManager().popBackStack();
}
public Toolbar getToolbar() {
return toolbar;
}
private AdapterView.OnItemClickListener navListClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

View File

@ -1,445 +0,0 @@
package de.danoeh.antennapod.dialog;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.Validate;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.ShownotesProvider;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
/**
* Shows information about a specific FeedItem and provides actions like playing, downloading, etc.
*/
public class FeedItemDialog extends Dialog {
private static final String TAG = "FeedItemDialog";
private FeedItem item;
private QueueAccess queue;
private ViewGroup contentContainer;
private View header;
private TextView txtvTitle;
private WebView webvDescription;
private ImageButton butAction1;
private ImageButton butAction2;
private ImageButton butMore;
private PopupMenu popupMenu;
public static FeedItemDialog newInstance(Context context, FeedItemDialogSavedInstance savedInstance) {
Validate.notNull(savedInstance);
FeedItemDialog dialog = newInstance(context, savedInstance.item, savedInstance.queueAccess);
if (savedInstance.isShowing) {
dialog.show();
}
return dialog;
}
public static FeedItemDialog newInstance(Context context, FeedItem item, QueueAccess queue) {
if (useDarkThemeWorkAround()) {
return new FeedItemDialog(context, R.style.Theme_AntennaPod_Dark, item, queue);
} else {
return new FeedItemDialog(context, item, queue);
}
}
public FeedItemDialog(Context context, int theme, FeedItem item, QueueAccess queue) {
super(context, theme);
Validate.notNull(item);
Validate.notNull(queue);
this.item = item;
this.queue = queue;
}
private FeedItemDialog(Context context, FeedItem item, QueueAccess queue) {
this(context, 0, item, queue);
}
/**
* Returns true if the dialog should use a dark theme. This has to be done on Gingerbread devices
* because dialogs are only available in a dark theme.
*/
private static boolean useDarkThemeWorkAround() {
return Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1
&& UserPreferences.getTheme() != R.style.Theme_AntennaPod_Dark;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.feeditem_dialog);
contentContainer = (ViewGroup) findViewById(R.id.contentContainer);
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
header = findViewById(R.id.header);
webvDescription = (WebView) findViewById(R.id.webview);
butAction1 = (ImageButton) findViewById(R.id.butAction1);
butAction2 = (ImageButton) findViewById(R.id.butAction2);
butMore = (ImageButton) findViewById(R.id.butMoreActions);
popupMenu = new PopupMenu(getContext(), butMore);
webvDescription.setWebViewClient(new WebViewClient());
if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448
txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
}
txtvTitle.setText(item.getTitle());
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
if (Build.VERSION.SDK_INT >= 11
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webvDescription.setBackgroundColor(getContext().getResources().getColor(
R.color.black));
}
webvDescription.getSettings().setUseWideViewPort(false);
webvDescription.getSettings().setLayoutAlgorithm(
WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webvDescription.getSettings().setLoadWithOverviewMode(true);
webvDescription.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
try {
getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
});
loadDescriptionWebview(item);
butAction1.setOnClickListener(new View.OnClickListener() {
DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getContext());
@Override
public void onClick(View v) {
actionButtonCallback.onActionButtonPressed(item);
FeedMedia media = item.getMedia();
if (media != null && media.isDownloaded()) {
// playback was started, dialog should close itself
dismiss();
}
}
}
);
butAction2.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
if (item.hasMedia()) {
FeedMedia media = item.getMedia();
if (!media.isDownloaded()) {
DBTasks.playMedia(getContext(), media, true, true, true);
dismiss();
} else {
DBWriter.deleteFeedMediaOfItem(getContext(), media.getId());
}
} else if (item.getLink() != null) {
Uri uri = Uri.parse(item.getLink());
getContext().startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
}
}
);
butMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupMenu.getMenu().clear();
popupMenu.inflate(R.menu.feeditem_dialog);
if (item.hasMedia()) {
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue);
} else {
// these are already available via button1 and button2
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue,
R.id.mark_read_item, R.id.visit_website_item);
}
popupMenu.show();
}
}
);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
try {
return FeedItemMenuHandler.onMenuItemClicked(getContext(), menuItem.getItemId(), item);
} catch (DownloadRequestException e) {
e.printStackTrace();
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
return true;
}
}
}
);
updateMenuAppearance();
}
@Override
public void dismiss() {
super.dismiss();
if (contentContainer != null && webvDescription != null) {
contentContainer.removeAllViews();
webvDescription.destroy();
}
}
private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() {
@Override
public void setItemVisibility(int id, boolean visible) {
MenuItem item = popupMenu.getMenu().findItem(id);
if (item != null) {
item.setVisible(visible);
}
}
};
public void updateMenuAppearance() {
if (item == null || queue == null) {
Log.w(TAG, "UpdateMenuAppearance called while item or queue was null");
return;
}
FeedMedia media = item.getMedia();
if (media == null) {
TypedArray drawables = getContext().obtainStyledAttributes(new int[]{R.attr.navigation_accept,
R.attr.location_web_site});
if (!item.isRead()) {
butAction1.setImageDrawable(drawables.getDrawable(0));
butAction1.setContentDescription(getContext().getString(R.string.mark_read_label));
butAction1.setVisibility(View.VISIBLE);
} else {
butAction1.setVisibility(View.INVISIBLE);
}
if (item.getLink() != null) {
butAction2.setImageDrawable(drawables.getDrawable(1));
butAction2.setContentDescription(getContext().getString(R.string.visit_website_label));
} else {
butAction2.setEnabled(false);
}
drawables.recycle();
} else {
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
TypedArray drawables = getContext().obtainStyledAttributes(new int[]{R.attr.av_play,
R.attr.av_download, R.attr.action_stream, R.attr.content_discard, R.attr.navigation_cancel});
if (!media.isDownloaded()) {
butAction2.setImageDrawable(drawables.getDrawable(2));
butAction2.setContentDescription(getContext().getString(R.string.stream_label));
} else {
butAction2.setImageDrawable(drawables.getDrawable(3));
butAction2.setContentDescription(getContext().getString(R.string.remove_episode_lable));
}
if (isDownloading) {
butAction1.setImageDrawable(drawables.getDrawable(4));
butAction1.setContentDescription(getContext().getString(R.string.cancel_download_label));
} else if (media.isDownloaded()) {
butAction1.setImageDrawable(drawables.getDrawable(0));
butAction1.setContentDescription(getContext().getString(R.string.play_label));
} else {
butAction1.setImageDrawable(drawables.getDrawable(1));
butAction1.setContentDescription(getContext().getString(R.string.download_label));
}
drawables.recycle();
}
}
private void loadDescriptionWebview(final ShownotesProvider shownotesProvider) {
AsyncTask<Void, Void, Void> loadTask = new AsyncTask<Void, Void, Void>() {
String data;
private String applyWebviewStyle(String textColor, String data) {
final String WEBVIEW_STYLE = "<html><head><style type=\"text/css\"> @font-face { font-family: 'Roboto-Light'; src: url('file:///android_asset/Roboto-Light.ttf'); } * { color: %s; font-family: roboto-Light; font-size: 11pt; } a { font-style: normal; text-decoration: none; font-weight: normal; color: #00A8DF; } img { display: block; margin: 10 auto; max-width: %s; height: auto; } body { margin: %dpx %dpx %dpx %dpx; }</style></head><body>%s</body></html>";
final int pageMargin = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 8, getContext().getResources()
.getDisplayMetrics()
);
return String.format(WEBVIEW_STYLE, textColor, "100%", pageMargin,
pageMargin, pageMargin, pageMargin, data);
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// /webvDescription.loadData(url, "text/html", "utf-8");
if (FeedItemDialog.this.isShowing() && webvDescription != null) {
webvDescription.loadDataWithBaseURL(null, data, "text/html",
"utf-8", "about:blank");
if (BuildConfig.DEBUG)
Log.d(TAG, "Webview loaded");
}
}
@Override
protected Void doInBackground(Void... params) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Loading Webview");
try {
Callable<String> shownotesLoadTask = shownotesProvider.loadShownotes();
final String shownotes = shownotesLoadTask.call();
data = StringEscapeUtils.unescapeHtml4(shownotes);
TypedArray res = getContext()
.getTheme()
.obtainStyledAttributes(
new int[]{android.R.attr.textColorPrimary});
int colorResource;
if (useDarkThemeWorkAround()) {
colorResource = getContext().getResources().getColor(R.color.black);
} else {
colorResource = res.getColor(0, 0);
}
String colorString = String.format("#%06X",
0xFFFFFF & colorResource);
Log.i(TAG, "text color: " + colorString);
res.recycle();
data = applyWebviewStyle(colorString, data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
loadTask.execute();
}
/**
* Convenience method that calls setQueue() and setItemFromCollection() with
* the given arguments.
*
* @return true if one of the calls to setItemFromCollection returned true,
* false otherwise.
*/
public boolean updateContent(QueueAccess queue, List<FeedItem>... collections) {
setQueue(queue);
boolean setItemFromCollectionResult = false;
if (collections != null) {
for (List<FeedItem> list : collections) {
setItemFromCollectionResult |= setItemFromCollection(list);
}
}
if (isShowing()) {
updateMenuAppearance();
}
return setItemFromCollectionResult;
}
public void setItem(FeedItem item) {
Validate.notNull(item);
this.item = item;
}
/**
* Finds the FeedItem of this dialog in a collection and updates its state from that
* collection.
*
* @return true if the FeedItem was found, false otherwise.
*/
public boolean setItemFromCollection(Collection<FeedItem> items) {
for (FeedItem item : items) {
if (item.getId() == this.item.getId()) {
setItem(item);
return true;
}
}
return false;
}
public void setQueue(QueueAccess queue) {
Validate.notNull(queue);
this.queue = queue;
}
public FeedItem getItem() {
return item;
}
public QueueAccess getQueue() {
return queue;
}
public FeedItemDialogSavedInstance save() {
return new FeedItemDialogSavedInstance(item, queue, isShowing());
}
/**
* Used to save the FeedItemDialog's state across configuration changes
*/
public static class FeedItemDialogSavedInstance {
final FeedItem item;
final QueueAccess queueAccess;
final boolean isShowing;
private FeedItemDialogSavedInstance(FeedItem item, QueueAccess queueAccess, boolean isShowing) {
this.item = item;
this.queueAccess = queueAccess;
this.isShowing = isShowing;
}
}
}

View File

@ -8,17 +8,17 @@ import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.QueueAccess;
import java.util.List;
/**
* Displays all running downloads and provides a button to delete them
*/
@ -36,8 +36,6 @@ public class CompletedDownloadsFragment extends ListFragment {
private boolean viewCreated = false;
private boolean itemsLoaded = false;
private FeedItemDialog feedItemDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -69,7 +67,6 @@ public class CompletedDownloadsFragment extends ListFragment {
super.onDestroyView();
listAdapter = null;
viewCreated = false;
feedItemDialog = null;
stopItemLoader();
}
@ -102,8 +99,7 @@ public class CompletedDownloadsFragment extends ListFragment {
super.onListItemClick(l, v, position, id);
FeedItem item = listAdapter.getItem(position - l.getHeaderViewsCount());
if (item != null) {
feedItemDialog = FeedItemDialog.newInstance(getActivity(), item, queue);
feedItemDialog.show();
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
}
}
@ -115,12 +111,6 @@ public class CompletedDownloadsFragment extends ListFragment {
}
setListShown(true);
listAdapter.notifyDataSetChanged();
if (feedItemDialog != null) {
boolean res = feedItemDialog.updateContent(queue, items);
if (!res && feedItemDialog.isShowing()) {
feedItemDialog.dismiss();
}
}
}
private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
@ -143,11 +133,7 @@ public class CompletedDownloadsFragment extends ListFragment {
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EventDistributor.DOWNLOAD_QUEUED) != 0) {
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateMenuAppearance();
}
} else if ((arg & EVENTS) != 0) {
if ((arg & EVENTS) != 0) {
startItemLoader();
}
}

View File

@ -0,0 +1,416 @@
package de.danoeh.antennapod.fragment;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
import de.danoeh.antennapod.core.asynctask.DBTaskLoader;
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
/**
* Displays information about a FeedItem and actions.
*/
public class ItemFragment extends Fragment implements LoaderManager.LoaderCallbacks<Pair<FeedItem, QueueAccess>> {
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
EventDistributor.QUEUE_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE;
private static final String ARG_FEEDITEM = "feeditem";
/**
* Creates a new instance of an ItemFragment
*
* @param feeditem The ID of the FeedItem that should be displayed.
* @return The ItemFragment instance
*/
public static ItemFragment newInstance(long feeditem) {
ItemFragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putLong(ARG_FEEDITEM, feeditem);
fragment.setArguments(args);
return fragment;
}
private boolean itemsLoaded = false;
private long itemID;
private FeedItem item;
private QueueAccess queue;
private String webviewData;
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
private ViewGroup root;
private View header;
private WebView webvDescription;
private TextView txtvTitle;
private ImageView imgvCover;
private ProgressBar progbarDownload;
private ProgressBar progbarLoading;
private ImageButton butAction1;
private ImageButton butAction2;
private ImageButton butMore;
private PopupMenu popupMenu;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(false);
itemID = getArguments().getLong(ARG_FEEDITEM, -1);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, null, this);
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
toolbar.addView(header);
}
@Override
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
}
if (itemsLoaded) {
onFragmentLoaded();
}
}
@Override
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
}
private void resetViewState() {
if (downloadObserver != null) {
downloadObserver.onPause();
}
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
toolbar.removeView(header);
}
@Override
public void onDestroyView() {
super.onDestroyView();
resetViewState();
if (webvDescription != null && root != null) {
root.removeView(webvDescription);
webvDescription.destroy();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
((MainActivity) getActivity()).getSupportActionBar().setTitle("");
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
View layout = inflater.inflate(R.layout.feeditem_fragment, container, false);
header = inflater.inflate(R.layout.feeditem_fragment_header, toolbar, false);
root = (ViewGroup) layout.findViewById(R.id.content_root);
txtvTitle = (TextView) header.findViewById(R.id.txtvTitle);
if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448
txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
}
webvDescription = (WebView) layout.findViewById(R.id.webvDescription);
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
if (Build.VERSION.SDK_INT >= 11
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webvDescription.setBackgroundColor(getResources().getColor(
R.color.black));
}
webvDescription.getSettings().setUseWideViewPort(false);
webvDescription.getSettings().setLayoutAlgorithm(
WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webvDescription.getSettings().setLoadWithOverviewMode(true);
webvDescription.setWebViewClient(new WebViewClient());
imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
progbarDownload = (ProgressBar) header.findViewById(R.id.progbarDownload);
progbarLoading = (ProgressBar) layout.findViewById(R.id.progbarLoading);
butAction1 = (ImageButton) header.findViewById(R.id.butAction1);
butAction2 = (ImageButton) header.findViewById(R.id.butAction2);
butMore = (ImageButton) header.findViewById(R.id.butMoreActions);
popupMenu = new PopupMenu(getActivity(), butMore);
butAction1.setOnClickListener(new View.OnClickListener() {
DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getActivity());
@Override
public void onClick(View v) {
actionButtonCallback.onActionButtonPressed(item);
FeedMedia media = item.getMedia();
if (media != null && media.isDownloaded()) {
// playback was started, dialog should close itself
((MainActivity) getActivity()).dismissChildFragment();
}
}
}
);
butAction2.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
if (item.hasMedia()) {
FeedMedia media = item.getMedia();
if (!media.isDownloaded()) {
DBTasks.playMedia(getActivity(), media, true, true, true);
((MainActivity) getActivity()).dismissChildFragment();
} else {
DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId());
}
} else if (item.getLink() != null) {
Uri uri = Uri.parse(item.getLink());
getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
}
}
);
butMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupMenu.getMenu().clear();
popupMenu.inflate(R.menu.feeditem_dialog);
if (item.hasMedia()) {
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue);
} else {
// these are already available via button1 and button2
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue,
R.id.mark_read_item, R.id.visit_website_item);
}
popupMenu.show();
}
}
);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
try {
return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item);
} catch (DownloadRequestException e) {
e.printStackTrace();
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
return true;
}
}
}
);
return layout;
}
private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() {
@Override
public void setItemVisibility(int id, boolean visible) {
MenuItem item = popupMenu.getMenu().findItem(id);
if (item != null) {
item.setVisible(visible);
}
}
};
private void onFragmentLoaded() {
progbarLoading.setVisibility(View.GONE);
if (webviewData != null) {
webvDescription.loadDataWithBaseURL(null, webviewData, "text/html",
"utf-8", "about:blank");
}
updateAppearance();
downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback);
downloadObserver.onResume();
}
private void updateAppearance() {
txtvTitle.setText(item.getTitle());
Picasso.with(getActivity()).load(item.getImageUri())
.fit()
.into(imgvCover);
progbarDownload.setVisibility(View.GONE);
if (item.hasMedia() && downloaderList != null) {
for (Downloader downloader : downloaderList) {
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
progbarDownload.setVisibility(View.VISIBLE);
progbarDownload.setProgress(downloader.getDownloadRequest().getProgressPercent());
}
}
}
FeedMedia media = item.getMedia();
if (media == null) {
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.navigation_accept,
R.attr.location_web_site});
if (!item.isRead()) {
butAction1.setImageDrawable(drawables.getDrawable(0));
butAction1.setContentDescription(getActivity().getString(R.string.mark_read_label));
butAction1.setVisibility(View.VISIBLE);
} else {
butAction1.setVisibility(View.INVISIBLE);
}
if (item.getLink() != null) {
butAction2.setImageDrawable(drawables.getDrawable(1));
butAction2.setContentDescription(getActivity().getString(R.string.visit_website_label));
} else {
butAction2.setEnabled(false);
}
drawables.recycle();
} else {
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.av_play,
R.attr.av_download, R.attr.action_stream, R.attr.content_discard, R.attr.navigation_cancel});
if (!media.isDownloaded()) {
butAction2.setImageDrawable(drawables.getDrawable(2));
butAction2.setContentDescription(getActivity().getString(R.string.stream_label));
} else {
butAction2.setImageDrawable(drawables.getDrawable(3));
butAction2.setContentDescription(getActivity().getString(R.string.remove_episode_lable));
}
if (isDownloading) {
butAction1.setImageDrawable(drawables.getDrawable(4));
butAction1.setContentDescription(getActivity().getString(R.string.cancel_download_label));
} else if (media.isDownloaded()) {
butAction1.setImageDrawable(drawables.getDrawable(0));
butAction1.setContentDescription(getActivity().getString(R.string.play_label));
} else {
butAction1.setImageDrawable(drawables.getDrawable(1));
butAction1.setContentDescription(getActivity().getString(R.string.download_label));
}
drawables.recycle();
}
}
@Override
public Loader<Pair<FeedItem, QueueAccess>> onCreateLoader(int id, Bundle args) {
return new DBTaskLoader<Pair<FeedItem, QueueAccess>>(getActivity()) {
@Override
public Pair<FeedItem, QueueAccess> loadInBackground() {
FeedItem data1 = DBReader.getFeedItem(getContext(), itemID);
if (data1 != null) {
Timeline t = new Timeline(getActivity(), data1);
webviewData = t.processShownotes(false);
}
QueueAccess data2 = QueueAccess.IDListAccess(DBReader.getQueueIDList(getContext()));
return Pair.create(data1, data2);
}
};
}
@Override
public void onLoadFinished(Loader<Pair<FeedItem, QueueAccess>> loader, Pair<FeedItem, QueueAccess> data) {
if (data != null) {
item = data.first;
queue = data.second;
if (!itemsLoaded) {
itemsLoaded = true;
onFragmentLoaded();
} else {
updateAppearance();
}
}
}
@Override
public void onLoaderReset(Loader<Pair<FeedItem, QueueAccess>> loader) {
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EVENTS) != 0) {
getLoaderManager().restartLoader(0, null, ItemFragment.this);
}
}
};
private final DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
public void onContentChanged() {
if (itemsLoaded && getActivity() != null) {
updateAppearance();
}
}
@Override
public void onDownloadDataAvailable(List<Downloader> downloaderList) {
ItemFragment.this.downloaderList = downloaderList;
if (itemsLoaded && getActivity() != null) {
updateAppearance();
}
}
};
}

View File

@ -50,7 +50,6 @@ import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
@ -82,9 +81,6 @@ public class ItemlistFragment extends ListFragment {
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
private FeedItemDialog feedItemDialog;
private FeedItemDialog.FeedItemDialogSavedInstance feedItemDialogSavedInstance;
private MoreContentListFooterUtil listFooter;
private boolean isUpdatingFeed;
@ -160,10 +156,6 @@ public class ItemlistFragment extends ListFragment {
if (downloadObserver != null) {
downloadObserver.onPause();
}
if (feedItemDialog != null) {
feedItemDialogSavedInstance = feedItemDialog.save();
}
feedItemDialog = null;
}
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() {
@ -273,8 +265,9 @@ public class ItemlistFragment extends ListFragment {
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
FeedItem selection = adapter.getItem(position - l.getHeaderViewsCount());
feedItemDialog = FeedItemDialog.newInstance(getActivity(), selection, queue);
feedItemDialog.show();
if (selection != null) {
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(selection.getId()));
}
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@ -317,11 +310,6 @@ public class ItemlistFragment extends ListFragment {
setListShown(true);
adapter.notifyDataSetChanged();
if (feedItemDialog != null) {
feedItemDialog.updateContent(queue, feed.getItems());
} else if (feedItemDialogSavedInstance != null) {
feedItemDialog = FeedItemDialog.newInstance(getActivity(), feedItemDialogSavedInstance);
}
getActivity().supportInvalidateOptionsMenu();
if (feed != null && feed.getNextPageLink() == null && listFooter != null) {
@ -336,9 +324,6 @@ public class ItemlistFragment extends ListFragment {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateMenuAppearance();
}
}
@Override

View File

@ -7,21 +7,28 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.*;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.mobeta.android.dslv.DragSortListView;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
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.core.asynctask.DownloadObserver;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
@ -37,9 +44,6 @@ import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* Shows unread or recently published episodes
*/
@ -73,9 +77,6 @@ public class NewEpisodesFragment extends Fragment {
private DownloadObserver downloadObserver = null;
private FeedItemDialog feedItemDialog;
private FeedItemDialog.FeedItemDialogSavedInstance feedItemDialogSavedInstance;
private boolean isUpdatingFeeds;
@Override
@ -133,10 +134,6 @@ public class NewEpisodesFragment extends Fragment {
if (downloadObserver != null) {
downloadObserver.onPause();
}
if (feedItemDialog != null) {
feedItemDialogSavedInstance = feedItemDialog.save();
}
feedItemDialog = null;
}
@ -226,8 +223,7 @@ public class NewEpisodesFragment extends Fragment {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FeedItem item = (FeedItem) listAdapter.getItem(position - listView.getHeaderViewsCount());
if (item != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), item, queueAccess);
feedItemDialog.show();
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
}
}
@ -257,11 +253,6 @@ public class NewEpisodesFragment extends Fragment {
downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback);
downloadObserver.onResume();
}
if (feedItemDialog != null) {
feedItemDialog.updateContent(queueAccess, unreadItems, recentItems);
} else if (feedItemDialogSavedInstance != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), feedItemDialogSavedInstance);
}
listAdapter.notifyDataSetChanged();
getActivity().supportInvalidateOptionsMenu();
updateShowOnlyEpisodesListViewState();
@ -273,9 +264,6 @@ public class NewEpisodesFragment extends Fragment {
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateMenuAppearance();
}
}
@Override

View File

@ -13,11 +13,15 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@ -28,9 +32,6 @@ import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class PlaybackHistoryFragment extends ListFragment {
private static final String TAG = "PlaybackHistoryFragment";
@ -46,9 +47,6 @@ public class PlaybackHistoryFragment extends ListFragment {
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
private FeedItemDialog feedItemDialog;
private FeedItemDialog.FeedItemDialogSavedInstance feedItemDialogSavedInstance;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -103,10 +101,6 @@ public class PlaybackHistoryFragment extends ListFragment {
if (downloadObserver != null) {
downloadObserver.onPause();
}
if (feedItemDialog != null) {
feedItemDialogSavedInstance = feedItemDialog.save();
}
feedItemDialog = null;
}
@Override
@ -130,8 +124,7 @@ public class PlaybackHistoryFragment extends ListFragment {
super.onListItemClick(l, v, position, id);
FeedItem item = adapter.getItem(position - l.getHeaderViewsCount());
if (item != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), item, queue);
feedItemDialog.show();
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
}
}
@ -158,7 +151,7 @@ public class PlaybackHistoryFragment extends ListFragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch(item.getItemId()) {
switch (item.getItemId()) {
case R.id.clear_history_item:
DBWriter.clearPlaybackHistory(getActivity());
return true;
@ -190,11 +183,6 @@ public class PlaybackHistoryFragment extends ListFragment {
}
setListShown(true);
adapter.notifyDataSetChanged();
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateContent(queue, playbackHistory);
} else if (feedItemDialogSavedInstance != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), feedItemDialogSavedInstance);
}
getActivity().supportInvalidateOptionsMenu();
}
@ -204,9 +192,6 @@ public class PlaybackHistoryFragment extends ListFragment {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateMenuAppearance();
}
}
@Override

View File

@ -29,14 +29,12 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
import de.danoeh.antennapod.adapter.QueueListAdapter;
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
@ -64,9 +62,6 @@ public class QueueFragment extends Fragment {
private DownloadObserver downloadObserver = null;
private FeedItemDialog feedItemDialog;
private FeedItemDialog.FeedItemDialogSavedInstance feedItemDialogSavedInstance;
/**
* Download observer updates won't result in an upate of the list adapter if this is true.
*/
@ -122,10 +117,6 @@ public class QueueFragment extends Fragment {
if (downloadObserver != null) {
downloadObserver.onPause();
}
if (feedItemDialog != null) {
feedItemDialogSavedInstance = feedItemDialog.save();
}
feedItemDialog = null;
}
@Override
@ -215,8 +206,7 @@ public class QueueFragment extends Fragment {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FeedItem item = (FeedItem) listAdapter.getItem(position - listView.getHeaderViewsCount());
if (item != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), item, QueueAccess.ItemListAccess(queue));
feedItemDialog.show();
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
}
}
});
@ -268,11 +258,6 @@ public class QueueFragment extends Fragment {
downloadObserver.onResume();
}
listAdapter.notifyDataSetChanged();
if (feedItemDialog != null) {
feedItemDialog.updateContent(QueueAccess.ItemListAccess(queue), queue);
} else if (feedItemDialogSavedInstance != null) {
feedItemDialog = FeedItemDialog.newInstance(activity.get(), feedItemDialogSavedInstance);
}
}
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@ -281,9 +266,6 @@ public class QueueFragment extends Fragment {
if (listAdapter != null && !blockDownloadObserverUpdate) {
listAdapter.notifyDataSetChanged();
}
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.updateMenuAppearance();
}
}
@Override

View File

@ -12,19 +12,23 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.SearchlistAdapter;
import de.danoeh.antennapod.dialog.FeedItemDialog;
import de.danoeh.antennapod.core.feed.*;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.FeedSearcher;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import java.util.List;
/**
* Performs a search operation on all feeds or one specific feed and displays the search result.
*/
@ -42,9 +46,6 @@ public class SearchFragment extends ListFragment {
private QueueAccess queue;
private FeedItemDialog feedItemDialog;
private FeedItemDialog.FeedItemDialogSavedInstance feedItemDialogSavedInstance;
/**
* Create a new SearchFragment that searches all feeds.
*/
@ -99,10 +100,6 @@ public class SearchFragment extends ListFragment {
super.onDestroyView();
searchAdapter = null;
viewCreated = false;
if (feedItemDialog != null) {
feedItemDialogSavedInstance = feedItemDialog.save();
}
feedItemDialog = null;
}
@Override
@ -128,11 +125,11 @@ public class SearchFragment extends ListFragment {
SearchResult result = (SearchResult) l.getAdapter().getItem(position);
FeedComponent comp = result.getComponent();
if (comp.getClass() == Feed.class) {
((MainActivity)getActivity()).loadFeedFragment(comp.getId());
((MainActivity) getActivity()).loadFeedFragment(comp.getId());
} else {
if (comp.getClass() == FeedItem.class) {
feedItemDialog = FeedItemDialog.newInstance(getActivity(), (FeedItem) comp, queue);
feedItemDialog.show();
FeedItem item = (FeedItem) comp;
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
}
}
}
@ -167,9 +164,6 @@ public class SearchFragment extends ListFragment {
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & (EventDistributor.DOWNLOAD_QUEUED)) != 0 && feedItemDialog != null) {
feedItemDialog.updateMenuAppearance();
}
if ((arg & (EventDistributor.UNREAD_ITEMS_UPDATE
| EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.QUEUE_UPDATE)) != 0) {
@ -185,18 +179,6 @@ public class SearchFragment extends ListFragment {
}
searchAdapter.notifyDataSetChanged();
setListShown(true);
if (feedItemDialog != null && feedItemDialog.isShowing()) {
feedItemDialog.setQueue(queue);
for (SearchResult result : searchResults) {
FeedComponent comp = result.getComponent();
if (comp.getClass() == FeedItem.class && ((FeedItem) comp).getId() == feedItemDialog.getItem().getId()) {
feedItemDialog.setItem((FeedItem) comp);
}
}
feedItemDialog.updateMenuAppearance();
} else if (feedItemDialogSavedInstance != null) {
feedItemDialog = FeedItemDialog.newInstance(getActivity(), feedItemDialogSavedInstance);
}
}
private final SearchlistAdapter.ItemAccess itemAccess = new SearchlistAdapter.ItemAccess() {

View File

@ -1,73 +0,0 @@
<?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:id="@+id/contentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txtvTitle"
style="@style/AntennaPod.Dialog.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="16dp"
android:ellipsize="none"
android:maxLines="5" />
<View
android:id="@+id/title_divider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/txtvTitle"
android:background="@color/bright_blue" />
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_divider"
android:orientation="horizontal">
<ImageButton
android:id="@+id/butAction1"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
tools:ignore="ContentDescription" />
<ImageButton
android:id="@+id/butAction2"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
tools:ignore="ContentDescription" />
<ImageButton
android:id="@+id/butMoreActions"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/butAction_label"
android:src="?attr/ic_action_overflow" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/header"
android:background="@color/bright_blue" />
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_below="@id/divider" />
</RelativeLayout>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webvDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="?android:windowContentOverlay" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progbarLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true" />
</FrameLayout>
</FrameLayout>

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="?attr/colorPrimary"
android:gravity="center_horizontal"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:paddingBottom="8dp">
<ImageView
android:id="@+id/imgvCover"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:layout_marginBottom="8dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/cover_label"
android:gravity="center_vertical" />
<ImageButton
android:id="@+id/butMoreActions"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/butAction_label"
android:paddingTop="4dp"
android:src="?attr/ic_action_overflow" />
<TextView
android:id="@+id/txtvTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="8dp"
android:layout_marginTop="16dp"
android:layout_toLeftOf="@id/butMoreActions"
android:layout_toRightOf="@id/imgvCover"
android:ellipsize="end"
android:maxLines="5" />
</RelativeLayout>
<ProgressBar
android:id="@+id/progbarDownload"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:orientation="horizontal">
<ImageButton
android:id="@+id/butAction1"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:paddingTop="4dp"
tools:ignore="ContentDescription" />
<ImageButton
android:id="@+id/butAction2"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:paddingTop="4dp"
tools:ignore="ContentDescription" />
</LinearLayout>
</LinearLayout>

View File

@ -5,19 +5,19 @@
<item
android:id="@+id/download_item"
android:icon="?attr/av_download"
custom:showAsAction="ifRoom|collapseActionView"
custom:showAsAction="collapseActionView"
android:title="@string/download_label">
</item>
<item
android:id="@+id/stream_item"
android:icon="?attr/action_stream"
custom:showAsAction="ifRoom|collapseActionView"
custom:showAsAction="collapseActionView"
android:title="@string/stream_label">
</item>
<item
android:id="@+id/play_item"
android:icon="?attr/av_play"
custom:showAsAction="ifRoom|collapseActionView"
custom:showAsAction="collapseActionView"
android:title="@string/play_label">
</item>
<item
@ -65,7 +65,7 @@
<item
android:id="@+id/visit_website_item"
android:icon="?attr/location_web_site"
custom:showAsAction="ifRoom|collapseActionView"
custom:showAsAction="collapseActionView"
android:title="@string/visit_website_label">
</item>
<item

View File

@ -0,0 +1,29 @@
package de.danoeh.antennapod.core.asynctask;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
/**
* Subclass of AsyncTaskLoader that is made for loading data with one of the DB*-classes.
* This class will provide a useful default implementation that would otherwise always be necessary when interacting
* with the DB*-classes with an AsyncTaskLoader.
*/
public abstract class DBTaskLoader<D> extends AsyncTaskLoader<D> {
public DBTaskLoader(Context context) {
super(context);
}
@Override
protected void onStopLoading() {
super.onStopLoading();
cancelLoad();
}
@Override
protected void onStartLoading() {
super.onStartLoading();
// according to https://code.google.com/p/android/issues/detail?id=14944, this has to be called manually
forceLoad();
}
}