summaryrefslogtreecommitdiff
path: root/app/src/main/java/de
diff options
context:
space:
mode:
authorTom Hennen <TomHennen@users.noreply.github.com>2015-11-07 09:16:24 -0500
committerTom Hennen <TomHennen@users.noreply.github.com>2015-11-07 09:16:24 -0500
commit0aeb520f14763e3f81c6e83d9584b79eac7d19f0 (patch)
treeecfaf180ff4d8d4a30a1c9581fdd71d514ec6a14 /app/src/main/java/de
parentc5d99a84b288d30afd0a2b54bb557fdbcdc9e56b (diff)
parent8286a76cdf580f4adc1e536cabd3cb3ce3427f15 (diff)
downloadAntennaPod-0aeb520f14763e3f81c6e83d9584b79eac7d19f0.zip
Merge pull request #1347 from mfietz/recycler_view
RecyclerView & SnackBar
Diffstat (limited to 'app/src/main/java/de')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java109
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java135
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java250
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java346
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java131
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java47
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java29
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java415
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/DividerItemDecoration.java124
10 files changed, 811 insertions, 779 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index a92eefc00..bcbabffcf 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -102,7 +102,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private View navDrawer;
private ListView navList;
private NavListAdapter navAdapter;
- private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
+ private int mPosition = -1;
private ActionBarDrawerToggle drawerToggle;
@@ -139,11 +139,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
final FragmentManager fm = getSupportFragmentManager();
- fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
- @Override
- public void onBackStackChanged() {
- drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0);
- }
+ fm.addOnBackStackChangedListener(() -> {
+ drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0);
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@@ -153,6 +150,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
navList.setAdapter(navAdapter);
navList.setOnItemClickListener(navListClickListener);
navList.setOnItemLongClickListener(newListLongClickListener);
+ registerForContextMenu(navList);
navAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
@@ -161,12 +159,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
});
- findViewById(R.id.nav_settings).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- drawerLayout.closeDrawer(navDrawer);
- startActivity(new Intent(MainActivity.this, PreferenceController.getPreferenceActivity()));
- }
+ findViewById(R.id.nav_settings).setOnClickListener(v -> {
+ drawerLayout.closeDrawer(navDrawer);
+ startActivity(new Intent(MainActivity.this, PreferenceController.getPreferenceActivity()));
});
FragmentTransaction transaction = fm.beginTransaction();
@@ -218,12 +213,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private void checkFirstLaunch() {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
if (prefs.getBoolean(PREF_IS_FIRST_LAUNCH, true)) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- drawerLayout.openDrawer(navDrawer);
- }
- }, 1500);
+ new Handler().postDelayed(() -> drawerLayout.openDrawer(navDrawer), 1500);
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean(PREF_IS_FIRST_LAUNCH, false);
@@ -245,21 +235,15 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(R.string.drawer_preferences);
- builder.setMultiChoiceItems(navLabels, checked, new DialogInterface.OnMultiChoiceClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which, boolean isChecked) {
- if (isChecked) {
- hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]);
- } else {
- hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
- }
+ builder.setMultiChoiceItems(navLabels, checked, (dialog, which, isChecked) -> {
+ if (isChecked) {
+ hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]);
+ } else {
+ hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
}
});
- builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
- }
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
});
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
@@ -422,6 +406,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
showDrawerPreferencesDialog();
return true;
} else {
+ mPosition = position;
return false;
}
}
@@ -521,6 +506,68 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ if(v.getId() != R.id.nav_list) {
+ return;
+ }
+ AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
+ int position = adapterInfo.position;
+ if(position < navAdapter.getSubscriptionOffset()) {
+ return;
+ }
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.nav_feed_context, menu);
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ menu.setHeaderTitle(feed.getTitle());
+ // episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
+ }
+
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ final int position = mPosition;
+ mPosition = -1; // reset
+ if(position < 0) {
+ return false;
+ }
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ switch(item.getItemId()) {
+ case R.id.mark_all_seen_item:
+ DBWriter.markFeedSeen(feed.getId());
+ return true;
+ case R.id.mark_all_read_item:
+ DBWriter.markFeedRead(feed.getId());
+ return true;
+ case R.id.remove_item:
+ final FeedRemover remover = new FeedRemover(this, feed) {
+ @Override
+ protected void onPostExecute(Void result) {
+ super.onPostExecute(result);
+ if(getSelectedNavListIndex() == position) {
+ loadFragment(EpisodesFragment.TAG, null);
+ }
+ }
+ };
+ ConfirmationDialog conDialog = new ConfirmationDialog(this,
+ R.string.remove_feed_label,
+ R.string.feed_delete_confirmation_msg) {
+ @Override
+ public void onConfirmButtonPressed(
+ DialogInterface dialog) {
+ dialog.dismiss();
+ remover.executeAsync();
+ }
+ };
+ conDialog.createNewDialog().show();
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
private DBReader.NavDrawerData navDrawerData;
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
private int selectedNavListIndex = 0;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
index d60888a43..74cf6af60 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -7,6 +7,8 @@ import android.widget.ImageButton;
import org.apache.commons.lang3.Validate;
+import java.lang.ref.WeakReference;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -27,7 +29,7 @@ public class ActionButtonUtils {
public ActionButtonUtils(Context context) {
Validate.notNull(context);
- this.context = context;
+ this.context = context.getApplicationContext();
drawables = context.obtainStyledAttributes(new int[] {
R.attr.av_play,
R.attr.navigation_cancel,
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
index c72c95feb..b35ff0aa9 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
@@ -5,10 +5,13 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.format.DateUtils;
import android.util.Log;
+import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -22,6 +25,7 @@ import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
import com.joanzapata.iconify.Iconify;
+import com.nineoldandroids.view.ViewHelper;
import java.lang.ref.WeakReference;
@@ -51,6 +55,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
private final boolean showOnlyNewEpisodes;
private final WeakReference<MainActivity> mainActivityRef;
+ private int position = -1;
+
public AllEpisodesRecycleAdapter(Context context,
MainActivity mainActivity,
ItemAccess itemAccess,
@@ -96,6 +102,10 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
public void onBindViewHolder(final Holder holder, int position) {
final FeedItem item = itemAccess.getItem(position);
if (item == null) return;
+ holder.itemView.setOnLongClickListener(v -> {
+ this.position = position;
+ return false;
+ });
holder.item = item;
holder.position = position;
holder.placeholder.setVisibility(View.VISIBLE);
@@ -189,6 +199,12 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
return itemAccess.getItem(position);
}
+ public int getPosition() {
+ int pos = position;
+ position = -1; // reset
+ return pos;
+ }
+
private class CoverTarget extends GlideDrawableImageViewTarget {
private final WeakReference<Uri> fallback;
@@ -235,63 +251,10 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
}
};
- private Menu popupMenu;
- private final FeedItemMenuHandler.MenuInterface contextMenuInterface = new FeedItemMenuHandler.MenuInterface() {
- @Override
- public void setItemVisibility(int id, boolean visible) {
- if(popupMenu == null) {
- return;
- }
- MenuItem item = popupMenu.findItem(id);
- if (item != null) {
- item.setVisible(visible);
- }
- }
- };
-
- private final boolean showContextMenu(View view) {
- // Create a PopupMenu, giving it the clicked view for an anchor
- MainActivity mainActivity = this.mainActivityRef.get();
- if (mainActivity == null) {
- Log.d(TAG, "mainActivity is null");
- return false;
- }
- PopupMenu popup = new PopupMenu(mainActivity, view);
- Menu menu = popup.getMenu();
-
- // Inflate our menu resource into the PopupMenu's Menu
- popup.getMenuInflater().inflate(R.menu.allepisodes_context, popup.getMenu());
-
- Holder holder = (Holder) view.getTag();
- FeedItem item = holder.item;
- if (item == null) {
- return false;
- }
-
- popupMenu = menu;
- FeedItemMenuHandler.onPrepareMenu(context, contextMenuInterface, item, true, null);
-
- // Set a listener so we are notified if a menu item is clicked
- popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- try {
- FeedItemMenuHandler.onMenuItemClicked(context, menuItem.getItemId(), item);
- return true;
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- }
- return false;
- }
- });
-
- popup.show();
- return true;
- }
-
-
public class Holder extends RecyclerView.ViewHolder
- implements View.OnClickListener, View.OnLongClickListener{
+ implements View.OnClickListener,
+ View.OnCreateContextMenuListener,
+ ItemTouchHelperViewHolder {
TextView placeholder;
TextView title;
TextView pubDate;
@@ -308,7 +271,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
public Holder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
- itemView.setOnLongClickListener(this);
+ itemView.setOnCreateContextMenuListener(this);
}
@Override
@@ -319,14 +282,42 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
}
}
- public FeedItem getFeedItem() { return item; }
+ @Override
+ public void onItemSelected() {
+ ViewHelper.setAlpha(itemView, 0.5f);
+ }
- public int getItemPosition() { return position; }
+ @Override
+ public void onItemClear() {
+ ViewHelper.setAlpha(itemView, 1.0f);
+ }
+
+ public FeedItem getFeedItem() { return item; }
@Override
- public boolean onLongClick(View view) {
- return showContextMenu(view);
+ public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ FeedItem item = itemAccess.getItem(getAdapterPosition());
+
+ MenuInflater inflater = mainActivityRef.get().getMenuInflater();
+ inflater.inflate(R.menu.allepisodes_context, menu);
+
+ if (item != null) {
+ menu.setHeaderTitle(item.getTitle());
+ }
+
+ FeedItemMenuHandler.MenuInterface contextMenuInterface = (id, visible) -> {
+ if (menu == null) {
+ return;
+ }
+ MenuItem item1 = menu.findItem(id);
+ if (item1 != null) {
+ item1.setVisible(visible);
+ }
+ };
+ FeedItemMenuHandler.onPrepareMenu(mainActivityRef.get(), contextMenuInterface, item, true,
+ null);
}
+
}
public interface ItemAccess {
@@ -340,4 +331,26 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
boolean isInQueue(FeedItem item);
}
+
+ /**
+ * Notifies a View Holder of relevant callbacks from
+ * {@link ItemTouchHelper.Callback}.
+ */
+ public interface ItemTouchHelperViewHolder {
+
+ /**
+ * Called when the {@link ItemTouchHelper} first registers an
+ * item as being moved or swiped.
+ * Implementations should update the item view to indicate
+ * it's active state.
+ */
+ void onItemSelected();
+
+
+ /**
+ * Called when the {@link ItemTouchHelper} has completed the
+ * move or swipe, and the active item state should be cleared.
+ */
+ void onItemClear();
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
deleted file mode 100644
index d5fb00b34..000000000
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package de.danoeh.antennapod.adapter;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.text.format.DateUtils;
-import android.util.Log;
-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.ProgressBar;
-import android.widget.TextView;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.resource.drawable.GlideDrawable;
-import com.bumptech.glide.request.animation.GlideAnimation;
-import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
-import com.joanzapata.iconify.Iconify;
-
-import java.lang.ref.WeakReference;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.Converter;
-import de.danoeh.antennapod.core.util.NetworkUtils;
-
-/**
- * List adapter for the queue.
- */
-public class QueueListAdapter extends BaseAdapter {
-
- private static final String TAG = QueueListAdapter.class.getSimpleName();
-
- private final Context context;
- private final ItemAccess itemAccess;
- private final ActionButtonCallback actionButtonCallback;
- private final ActionButtonUtils actionButtonUtils;
-
- private boolean locked;
-
-
- public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
- super();
- this.context = context;
- this.itemAccess = itemAccess;
- this.actionButtonUtils = new ActionButtonUtils(context);
- this.actionButtonCallback = actionButtonCallback;
- locked = UserPreferences.isQueueLocked();
- }
-
- public void setLocked(boolean locked) {
- this.locked = locked;
- notifyDataSetChanged();
- }
-
- @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.queue_listitem,
- parent, false);
- holder.dragHandle = (ImageView) convertView.findViewById(R.id.drag_handle);
- holder.placeholder = (TextView) convertView.findViewById(R.id.txtvPlaceholder);
- holder.cover = (ImageView) convertView.findViewById(R.id.imgvCover);
- holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
- holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
- holder.progressLeft = (TextView) convertView.findViewById(R.id.txtvProgressLeft);
- holder.progressRight = (TextView) convertView
- .findViewById(R.id.txtvProgressRight);
- holder.butSecondary = (ImageButton) convertView
- .findViewById(R.id.butSecondaryAction);
- holder.progress = (ProgressBar) convertView
- .findViewById(R.id.progressBar);
- convertView.setTag(holder);
- } else {
- holder = (Holder) convertView.getTag();
- }
-
- if(locked) {
- holder.dragHandle.setVisibility(View.GONE);
- } else {
- holder.dragHandle.setVisibility(View.VISIBLE);
- }
-
- holder.placeholder.setText(item.getFeed().getTitle());
-
- holder.title.setText(item.getTitle());
- FeedMedia media = item.getMedia();
-
- holder.title.setText(item.getTitle());
- String pubDate = DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL);
- holder.pubDate.setText(pubDate.replace(" ", "\n"));
-
- if (media != null) {
- final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
- FeedItem.State state = item.getState();
- if (isDownloadingMedia) {
- holder.progressLeft.setText(Converter.byteToString(itemAccess.getItemDownloadedBytes(item)));
- if(itemAccess.getItemDownloadSize(item) > 0) {
- holder.progressRight.setText(Converter.byteToString(itemAccess.getItemDownloadSize(item)));
- } else {
- holder.progressRight.setText(Converter.byteToString(media.getSize()));
- }
- holder.progress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
- holder.progress.setVisibility(View.VISIBLE);
- } else if (state == FeedItem.State.PLAYING
- || state == FeedItem.State.IN_PROGRESS) {
- if (media.getDuration() > 0) {
- int progress = (int) (100.0 * media.getPosition() / media.getDuration());
- holder.progress.setProgress(progress);
- holder.progress.setVisibility(View.VISIBLE);
- holder.progressLeft.setText(Converter
- .getDurationStringLong(media.getPosition()));
- holder.progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
- }
- } else {
- if(media.getSize() > 0) {
- holder.progressLeft.setText(Converter.byteToString(media.getSize()));
- } else if(false == media.checkedOnSizeButUnknown()) {
- holder.progressLeft.setText("{fa-spinner}");
- Iconify.addIcons(holder.progressLeft);
- NetworkUtils.getFeedMediaSizeObservable(media)
- .subscribe(
- size -> {
- if (size > 0) {
- holder.progressLeft.setText(Converter.byteToString(size));
- } else {
- holder.progressLeft.setText("");
- }
- }, error -> {
- holder.progressLeft.setText("");
- Log.e(TAG, Log.getStackTraceString(error));
- });
- } else {
- holder.progressLeft.setText("");
- }
- holder.progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
- holder.progress.setVisibility(View.GONE);
- }
- }
-
- actionButtonUtils.configureActionButton(holder.butSecondary, item);
- holder.butSecondary.setFocusable(false);
- holder.butSecondary.setTag(item);
- holder.butSecondary.setOnClickListener(secondaryActionListener);
-
- Glide.with(context)
- .load(item.getImageUri())
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .fitCenter()
- .dontAnimate()
- .into(new CoverTarget(item.getFeed().getImageUri(), holder.placeholder, holder.cover));
-
- return convertView;
- }
-
- private class CoverTarget extends GlideDrawableImageViewTarget {
-
- private final WeakReference<Uri> fallback;
- private final WeakReference<TextView> placeholder;
- private final WeakReference<ImageView> cover;
-
- public CoverTarget(Uri fallbackUri, TextView txtvPlaceholder, ImageView imgvCover) {
- super(imgvCover);
- fallback = new WeakReference<>(fallbackUri);
- placeholder = new WeakReference<>(txtvPlaceholder);
- cover = new WeakReference<>(imgvCover);
- }
-
- @Override
- public void onLoadFailed(Exception e, Drawable errorDrawable) {
- Uri fallbackUri = fallback.get();
- TextView txtvPlaceholder = placeholder.get();
- ImageView imgvCover = cover.get();
- if(fallbackUri != null && txtvPlaceholder != null && imgvCover != null) {
- Glide.with(context)
- .load(fallbackUri)
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .fitCenter()
- .dontAnimate()
- .into(new CoverTarget(null, txtvPlaceholder, imgvCover));
- }
- }
-
- @Override
- public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
- super.onResourceReady(drawable, anim);
- TextView txtvPlaceholder = placeholder.get();
- if(txtvPlaceholder != null) {
- txtvPlaceholder.setVisibility(View.INVISIBLE);
- }
- }
- }
-
- private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- FeedItem item = (FeedItem) v.getTag();
- actionButtonCallback.onActionButtonPressed(item);
- }
- };
-
- static class Holder {
- ImageView dragHandle;
- ImageView cover;
- TextView placeholder;
- TextView title;
- TextView pubDate;
- TextView progressLeft;
- TextView progressRight;
- ProgressBar progress;
- ImageButton butSecondary;
- }
-
- public interface ItemAccess {
- FeedItem getItem(int position);
- int getCount();
- long getItemDownloadedBytes(FeedItem item);
- long getItemDownloadSize(FeedItem item);
- int getItemDownloadProgressPercent(FeedItem item);
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
new file mode 100644
index 000000000..062f883bc
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -0,0 +1,346 @@
+package de.danoeh.antennapod.adapter;
+
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v7.widget.PopupMenu;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
+import com.joanzapata.iconify.Iconify;
+import com.nineoldandroids.view.ViewHelper;
+
+import java.lang.ref.WeakReference;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.Converter;
+import de.danoeh.antennapod.core.util.LongList;
+import de.danoeh.antennapod.core.util.NetworkUtils;
+import de.danoeh.antennapod.fragment.ItemFragment;
+import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+
+/**
+ * List adapter for the queue.
+ */
+public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdapter.ViewHolder> {
+
+ private static final String TAG = QueueRecyclerAdapter.class.getSimpleName();
+
+ private WeakReference<MainActivity> mainActivity;
+ private final ItemAccess itemAccess;
+ private final ActionButtonCallback actionButtonCallback;
+ private final ActionButtonUtils actionButtonUtils;
+ private final ItemTouchHelper itemTouchHelper;
+
+ private boolean locked;
+
+ private int position = -1;
+
+ public QueueRecyclerAdapter(MainActivity mainActivity,
+ ItemAccess itemAccess,
+ ActionButtonCallback actionButtonCallback,
+ ItemTouchHelper itemTouchHelper) {
+ super();
+ this.mainActivity = new WeakReference<>(mainActivity);
+ this.itemAccess = itemAccess;
+ this.actionButtonUtils = new ActionButtonUtils(mainActivity);
+ this.actionButtonCallback = actionButtonCallback;
+ this.itemTouchHelper = itemTouchHelper;
+ locked = UserPreferences.isQueueLocked();
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ notifyDataSetChanged();
+ }
+
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.queue_listitem, parent, false);
+ return new ViewHolder(view);
+ }
+
+ public void onBindViewHolder(ViewHolder holder, int pos) {
+ FeedItem item = itemAccess.getItem(pos);
+ holder.bind(item);
+ holder.itemView.setOnLongClickListener(v -> {
+ position = pos;
+ return false;
+ });
+ }
+
+ public int getItemCount() {
+ return itemAccess.getCount();
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener,
+ View.OnCreateContextMenuListener,
+ ItemTouchHelperViewHolder {
+
+ private final ImageView dragHandle;
+ private final TextView placeholder;
+ private final ImageView cover;
+ private final TextView title;
+ private final TextView pubDate;
+ private final TextView progressLeft;
+ private final TextView progressRight;
+ private final ProgressBar progressBar;
+ private final ImageButton butSecondary;
+
+ private FeedItem item;
+
+ public ViewHolder(View v) {
+ super(v);
+ dragHandle = (ImageView) v.findViewById(R.id.drag_handle);
+ placeholder = (TextView) v.findViewById(R.id.txtvPlaceholder);
+ cover = (ImageView) v.findViewById(R.id.imgvCover);
+ title = (TextView) v.findViewById(R.id.txtvTitle);
+ pubDate = (TextView) v.findViewById(R.id.txtvPubDate);
+ progressLeft = (TextView) v.findViewById(R.id.txtvProgressLeft);
+ progressRight = (TextView) v.findViewById(R.id.txtvProgressRight);
+ butSecondary = (ImageButton) v.findViewById(R.id.butSecondaryAction);
+ progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
+ v.setTag(this);
+ v.setOnClickListener(this);
+ v.setOnCreateContextMenuListener(this);
+ dragHandle.setOnTouchListener((v1, event) -> {
+ if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+ Log.d(TAG, "startDrag()");
+ itemTouchHelper.startDrag(ViewHolder.this);
+ }
+ return false;
+ });
+ }
+
+ @Override
+ public void onClick(View v) {
+ MainActivity activity = mainActivity.get();
+ if (activity != null) {
+ activity.loadChildFragment(ItemFragment.newInstance(item.getId()));
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ FeedItem item = itemAccess.getItem(getAdapterPosition());
+
+ MenuInflater inflater = mainActivity.get().getMenuInflater();
+ inflater.inflate(R.menu.queue_context, menu);
+
+ if (item != null) {
+ menu.setHeaderTitle(item.getTitle());
+ }
+
+ FeedItemMenuHandler.MenuInterface contextMenuInterface = (id, visible) -> {
+ if (menu == null) {
+ return;
+ }
+ MenuItem item1 = menu.findItem(id);
+ if (item1 != null) {
+ item1.setVisible(visible);
+ }
+ };
+ FeedItemMenuHandler.onPrepareMenu(mainActivity.get(), contextMenuInterface, item, true,
+ itemAccess.getQueueIds());
+ }
+
+ @Override
+ public void onItemSelected() {
+ ViewHelper.setAlpha(itemView, 0.5f);
+ }
+
+ @Override
+ public void onItemClear() {
+ ViewHelper.setAlpha(itemView, 1.0f);
+ }
+
+ public void bind(FeedItem item) {
+ this.item = item;
+ if(locked) {
+ dragHandle.setVisibility(View.GONE);
+ } else {
+ dragHandle.setVisibility(View.VISIBLE);
+ }
+
+ placeholder.setText(item.getFeed().getTitle());
+
+ title.setText(item.getTitle());
+ FeedMedia media = item.getMedia();
+
+ title.setText(item.getTitle());
+ String pubDateStr = DateUtils.formatDateTime(mainActivity.get(),
+ item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL);
+ pubDate.setText(pubDateStr.replace(" ", "\n"));
+
+ if (media != null) {
+ final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
+ FeedItem.State state = item.getState();
+ if (isDownloadingMedia) {
+ progressLeft.setText(Converter.byteToString(itemAccess.getItemDownloadedBytes(item)));
+ if(itemAccess.getItemDownloadSize(item) > 0) {
+ progressRight.setText(Converter.byteToString(itemAccess.getItemDownloadSize(item)));
+ } else {
+ progressRight.setText(Converter.byteToString(media.getSize()));
+ }
+ progressBar.setProgress(itemAccess.getItemDownloadProgressPercent(item));
+ progressBar.setVisibility(View.VISIBLE);
+ } else if (state == FeedItem.State.PLAYING
+ || state == FeedItem.State.IN_PROGRESS) {
+ if (media.getDuration() > 0) {
+ int progress = (int) (100.0 * media.getPosition() / media.getDuration());
+ progressBar.setProgress(progress);
+ progressBar.setVisibility(View.VISIBLE);
+ progressLeft.setText(Converter
+ .getDurationStringLong(media.getPosition()));
+ progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
+ }
+ } else {
+ if(media.getSize() > 0) {
+ progressLeft.setText(Converter.byteToString(media.getSize()));
+ } else if(false == media.checkedOnSizeButUnknown()) {
+ progressLeft.setText("{fa-spinner}");
+ Iconify.addIcons(progressLeft);
+ NetworkUtils.getFeedMediaSizeObservable(media)
+ .subscribe(
+ size -> {
+ if (size > 0) {
+ progressLeft.setText(Converter.byteToString(size));
+ } else {
+ progressLeft.setText("");
+ }
+ }, error -> {
+ progressLeft.setText("");
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
+ } else {
+ progressLeft.setText("");
+ }
+ progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
+ progressBar.setVisibility(View.GONE);
+ }
+ }
+
+ actionButtonUtils.configureActionButton(butSecondary, item);
+ butSecondary.setFocusable(false);
+ butSecondary.setTag(item);
+ butSecondary.setOnClickListener(secondaryActionListener);
+
+ Glide.with(mainActivity.get())
+ .load(item.getImageUri())
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(item.getFeed().getImageUri(), placeholder, cover));
+ }
+
+
+ }
+
+
+ private class CoverTarget extends GlideDrawableImageViewTarget {
+
+ private final WeakReference<Uri> fallback;
+ private final WeakReference<TextView> placeholder;
+ private final WeakReference<ImageView> cover;
+
+ public CoverTarget(Uri fallbackUri, TextView txtvPlaceholder, ImageView imgvCover) {
+ super(imgvCover);
+ fallback = new WeakReference<>(fallbackUri);
+ placeholder = new WeakReference<>(txtvPlaceholder);
+ cover = new WeakReference<>(imgvCover);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ Uri fallbackUri = fallback.get();
+ TextView txtvPlaceholder = placeholder.get();
+ ImageView imgvCover = cover.get();
+ if(fallbackUri != null && txtvPlaceholder != null && imgvCover != null) {
+ Glide.with(mainActivity.get())
+ .load(fallbackUri)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(null, txtvPlaceholder, imgvCover));
+ }
+ }
+
+ @Override
+ public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
+ super.onResourceReady(drawable, anim);
+ TextView txtvPlaceholder = placeholder.get();
+ if(txtvPlaceholder != null) {
+ txtvPlaceholder.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
+ private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ FeedItem item = (FeedItem) v.getTag();
+ actionButtonCallback.onActionButtonPressed(item);
+ }
+ };
+
+
+ public interface ItemAccess {
+ FeedItem getItem(int position);
+ int getCount();
+ long getItemDownloadedBytes(FeedItem item);
+ long getItemDownloadSize(FeedItem item);
+ int getItemDownloadProgressPercent(FeedItem item);
+ LongList getQueueIds();
+ }
+
+ /**
+ * Notifies a View Holder of relevant callbacks from
+ * {@link ItemTouchHelper.Callback}.
+ */
+ public interface ItemTouchHelperViewHolder {
+
+ /**
+ * Called when the {@link ItemTouchHelper} first registers an
+ * item as being moved or swiped.
+ * Implementations should update the item view to indicate
+ * it's active state.
+ */
+ void onItemSelected();
+
+
+ /**
+ * Called when the {@link ItemTouchHelper} has completed the
+ * move or swipe, and the active item state should be cleared.
+ */
+ void onItemClear();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 8e416139e..c5b6ddb65 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -79,16 +79,14 @@ public class EpisodesApplyActionFragment extends Fragment {
mListView = (ListView) view.findViewById(android.R.id.list);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView<?> ListView, View view, int position, long rowId) {
- long id = episodes.get(position).getId();
- if (checkedIds.contains(id)) {
- checkedIds.remove(id);
- } else {
- checkedIds.add(id);
- }
- refreshCheckboxes();
+ mListView.setOnItemClickListener((ListView, view1, position, rowId) -> {
+ long id = episodes.get(position).getId();
+ if (checkedIds.contains(id)) {
+ checkedIds.remove(id);
+ } else {
+ checkedIds.add(id);
}
+ refreshCheckboxes();
});
for(FeedItem episode : episodes) {
@@ -101,40 +99,15 @@ public class EpisodesApplyActionFragment extends Fragment {
checkAll();
btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue);
- btnAddToQueue.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- queueChecked();
- }
- });
+ btnAddToQueue.setOnClickListener(v -> queueChecked());
btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed);
- btnMarkAsPlayed.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- markedCheckedPlayed();
- }
- });
+ btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed());
btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed);
- btnMarkAsUnplayed.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- markedCheckedUnplayed();
- }
- });
+ btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed());
btnDownload = (Button) view.findViewById(R.id.btnDownload);
- btnDownload.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- downloadChecked();
- }
- });
+ btnDownload.setOnClickListener(v -> downloadChecked());
btnDelete = (Button) view.findViewById(R.id.btnDelete);
- btnDelete.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- deleteChecked();
- }
- });
+ btnDelete.setOnClickListener(v -> deleteChecked());
return view;
}
@@ -153,16 +126,13 @@ public class EpisodesApplyActionFragment extends Fragment {
FontAwesomeIcons.fa_sort).color(textColor).actionBarSize());
mSelectToggle = menu.findItem(R.id.select_toggle);
- mSelectToggle.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- if (checkedIds.size() == episodes.size()) {
- checkNone();
- } else {
- checkAll();
- }
- return true;
+ mSelectToggle.setOnMenuItemClickListener(item -> {
+ if (checkedIds.size() == episodes.size()) {
+ checkNone();
+ } else {
+ checkAll();
}
+ return true;
});
menu.findItem(R.id.select_options).setIcon(new IconDrawable(getActivity(),
@@ -241,14 +211,11 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void sortByTitle(final boolean reverse) {
- Collections.sort(episodes, new Comparator<FeedItem>() {
- @Override
- public int compare(FeedItem lhs, FeedItem rhs) {
- if (reverse) {
- return -1 * lhs.getTitle().compareTo(rhs.getTitle());
- } else {
- return lhs.getTitle().compareTo(rhs.getTitle());
- }
+ Collections.sort(episodes, (lhs, rhs) -> {
+ if (reverse) {
+ return -1 * lhs.getTitle().compareTo(rhs.getTitle());
+ } else {
+ return lhs.getTitle().compareTo(rhs.getTitle());
}
});
refreshTitles();
@@ -256,20 +223,17 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void sortByDate(final boolean reverse) {
- Collections.sort(episodes, new Comparator<FeedItem>() {
- @Override
- public int compare(FeedItem lhs, FeedItem rhs) {
- if (lhs.getPubDate() == null) {
- return -1;
- } else if (rhs.getPubDate() == null) {
- return 1;
- }
- int code = lhs.getPubDate().compareTo(rhs.getPubDate());
- if (reverse) {
- return -1 * code;
- } else {
- return code;
- }
+ Collections.sort(episodes, (lhs, rhs) -> {
+ if (lhs.getPubDate() == null) {
+ return -1;
+ } else if (rhs.getPubDate() == null) {
+ return 1;
+ }
+ int code = lhs.getPubDate().compareTo(rhs.getPubDate());
+ if (reverse) {
+ return -1 * code;
+ } else {
+ return code;
}
});
refreshTitles();
@@ -277,22 +241,19 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void sortByDuration(final boolean reverse) {
- Collections.sort(episodes, new Comparator<FeedItem>() {
- @Override
- public int compare(FeedItem lhs, FeedItem rhs) {
- int ordering;
- if (false == lhs.hasMedia()) {
- ordering = 1;
- } else if (false == rhs.hasMedia()) {
- ordering = -1;
- } else {
- ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration();
- }
- if(reverse) {
- return -1 * ordering;
+ Collections.sort(episodes, (lhs, rhs) -> {
+ int ordering;
+ if (false == lhs.hasMedia()) {
+ ordering = 1;
+ } else if (false == rhs.hasMedia()) {
+ ordering = -1;
} else {
- return ordering;
+ ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration();
}
+ if(reverse) {
+ return -1 * ordering;
+ } else {
+ return ordering;
}
});
refreshTitles();
@@ -361,7 +322,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void queueChecked() {
- DBWriter.addQueueItem(getActivity(), episodes.toArray(new FeedItem[0]));
+ DBWriter.addQueueItem(getActivity(), true, checkedIds.toArray());
close();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index c3249771f..cdd6bc265 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -21,6 +21,8 @@ import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
+import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
+
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -39,9 +41,10 @@ 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.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.view.DividerItemDecoration;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -94,12 +97,6 @@ public class AllEpisodesFragment extends Fragment {
}
@Override
- public void onResume() {
- super.onResume();
- loadItems();
- }
-
- @Override
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
@@ -114,9 +111,17 @@ public class AllEpisodesFragment extends Fragment {
}
@Override
+ public void onResume() {
+ super.onResume();
+ loadItems();
+ registerForContextMenu(recyclerView);
+ }
+
+ @Override
public void onPause() {
super.onPause();
saveScrollPosition();
+ unregisterForContextMenu(recyclerView);
}
@Override
@@ -261,6 +266,31 @@ public class AllEpisodesFragment extends Fragment {
}
@Override
+ public boolean onContextItemSelected(MenuItem item) {
+ if(!isVisible()) {
+ return false;
+ }
+ int pos = listAdapter.getPosition();
+ if(pos < 0) {
+ return false;
+ }
+ FeedItem selectedItem = itemAccess.getItem(pos);
+
+ if (selectedItem == null) {
+ Log.i(TAG, "Selected item at position " + pos + " was null, ignoring selection");
+ return super.onContextItemSelected(item);
+ }
+
+ try {
+ return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem);
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
+ return true;
+ }
+ }
+
+ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return onCreateViewHelper(inflater, container, savedInstanceState,
R.layout.all_episodes_fragment);
@@ -278,8 +308,7 @@ public class AllEpisodesFragment extends Fragment {
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
- RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(getActivity(), null);
- recyclerView.addItemDecoration(itemDecoration);
+ recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
index bbe9b20f3..d684c064c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -14,9 +14,10 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter;
+import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -104,6 +105,32 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
snackbar.show();
h.postDelayed(r, (int)Math.ceil(snackbar.getDuration() * 1.05f));
}
+
+ @Override
+ public void onSelectedChanged(RecyclerView.ViewHolder viewHolder,
+ int actionState) {
+ // We only want the active item
+ if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
+ if (viewHolder instanceof AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder) {
+ AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder itemViewHolder =
+ (AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemSelected();
+ }
+ }
+
+ super.onSelectedChanged(viewHolder, actionState);
+ }
+ @Override
+ public void clearView(RecyclerView recyclerView,
+ RecyclerView.ViewHolder viewHolder) {
+ super.clearView(recyclerView, viewHolder);
+
+ if (viewHolder instanceof AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder) {
+ AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder itemViewHolder =
+ (AllEpisodesRecycleAdapter.ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemClear();
+ }
+ }
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index 0ac33f8fb..709d7038a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -1,43 +1,45 @@
package de.danoeh.antennapod.fragment;
-import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
-import android.view.ContextMenu;
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 com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
+import java.util.Collections;
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.QueueListAdapter;
+import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.event.FeedItemEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
@@ -47,10 +49,9 @@ 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.Converter;
+import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueSorter;
-import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
-import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.greenrobot.event.EventBus;
@@ -71,28 +72,19 @@ public class QueueFragment extends Fragment {
EventDistributor.PLAYER_STATUS_UPDATE;
private TextView infoBar;
- private DragSortListView listView;
- private QueueListAdapter listAdapter;
+ private RecyclerView recyclerView;
+ private QueueRecyclerAdapter recyclerAdapter;
private TextView txtvEmpty;
private ProgressBar progLoading;
- private ContextMenu contextMenu;
- private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
-
- private UndoBarController<FeedItemUndoToken> undoBarController;
-
private List<FeedItem> queue;
private List<Downloader> downloaderList;
- private boolean itemsLoaded = false;
- private boolean viewsCreated = false;
private boolean isUpdatingFeeds = false;
private static final String PREFS = "QueueFragment";
- private static final String PREF_KEY_LIST_TOP = "list_top";
- private static final String PREF_KEY_LIST_SELECTION = "list_selection";
-
- private AtomicReference<Activity> activity = new AtomicReference<Activity>();
+ private static final String PREF_SCROLL_POSITION = "scroll_position";
+ private static final String PREF_SCROLL_OFFSET = "scroll_offset";
private DownloadObserver downloadObserver = null;
@@ -102,6 +94,8 @@ public class QueueFragment extends Fragment {
private boolean blockDownloadObserverUpdate = false;
private Subscription subscription;
+ private LinearLayoutManager layoutManager;
+ private ItemTouchHelper itemTouchHelper;
@Override
@@ -112,90 +106,117 @@ public class QueueFragment extends Fragment {
}
@Override
- public void onResume() {
- super.onResume();
- loadItems();
- }
-
- @Override
public void onStart() {
super.onStart();
- EventDistributor.getInstance().register(contentUpdate);
- EventBus.getDefault().register(this);
- this.activity.set((MainActivity) getActivity());
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
}
- if (viewsCreated && itemsLoaded) {
+ if (queue != null) {
onFragmentLoaded();
}
}
@Override
- public void onPause() {
- super.onPause();
- saveScrollPosition();
+ public void onResume() {
+ super.onResume();
+ recyclerView.setAdapter(recyclerAdapter);
+ loadItems();
+ EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
}
@Override
- public void onStop() {
- super.onStop();
+ public void onPause() {
+ super.onPause();
+ saveScrollPosition();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
if(subscription != null) {
subscription.unsubscribe();
}
- if(undoBarController.isShowing()) {
- undoBarController.close();
- }
}
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- this.activity.set((MainActivity) activity);
+ public void onEventMainThread(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ switch(event.action) {
+ case ADDED:
+ queue.add(event.position, event.item);
+ recyclerAdapter.notifyItemInserted(event.position);
+ break;
+ case SET_QUEUE:
+ queue = event.items;
+ recyclerAdapter.notifyDataSetChanged();
+ break;
+ case REMOVED:
+ int position = FeedItemUtil.indexOfItemWithId(queue, event.item.getId());
+ queue.remove(position);
+ recyclerAdapter.notifyItemRemoved(position);
+ break;
+ case CLEARED:
+ queue.clear();
+ recyclerAdapter.notifyDataSetChanged();
+ break;
+ case SORTED:
+ queue = event.items;
+ recyclerAdapter.notifyDataSetChanged();
+ break;
+ case MOVED:
+ int from = FeedItemUtil.indexOfItemWithId(queue, event.item.getId());
+ int to = event.position;
+ Collections.swap(queue, from, to);
+ recyclerAdapter.notifyItemMoved(from, to);
+ break;
+ }
+ onFragmentLoaded();
}
- public void onEventMainThread(QueueEvent event) {
+ public void onEventMainThread(FeedItemEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
- if(event.action == QueueEvent.Action.REMOVED) {
- undoBarController.showUndoBar(false, getString(R.string.removed_from_queue),
- new FeedItemUndoToken(event.item, event.position));
+ for(int i=0, size = event.items.size(); i < size; i++) {
+ FeedItem item = event.items.get(i);
+ int pos = FeedItemUtil.indexOfItemWithId(queue, item.getId());
+ if(pos >= 0) {
+ queue.remove(pos);
+ queue.add(pos, item);
+ recyclerAdapter.notifyItemChanged(pos);
+ }
}
- loadItems();
}
private void saveScrollPosition() {
+ int firstItem = layoutManager.findFirstVisibleItemPosition();
+ View firstItemView = layoutManager.findViewByPosition(firstItem);
+ float topOffset;
+ if(firstItemView == null) {
+ topOffset = 0;
+ } else {
+ topOffset = firstItemView.getTop();
+ }
+
SharedPreferences prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
- View v = listView.getChildAt(0);
- int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
- editor.putInt(PREF_KEY_LIST_SELECTION, listView.getFirstVisiblePosition());
- editor.putInt(PREF_KEY_LIST_TOP, top);
+ editor.putInt(PREF_SCROLL_POSITION, firstItem);
+ editor.putFloat(PREF_SCROLL_OFFSET, topOffset);
editor.commit();
}
private void restoreScrollPosition() {
SharedPreferences prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
- int listSelection = prefs.getInt(PREF_KEY_LIST_SELECTION, 0);
- int top = prefs.getInt(PREF_KEY_LIST_TOP, 0);
- if(listSelection > 0 || top > 0) {
- listView.setSelectionFromTop(listSelection, top);
+ int position = prefs.getInt(PREF_SCROLL_POSITION, 0);
+ float offset = prefs.getFloat(PREF_SCROLL_OFFSET, 0.0f);
+ if (position > 0 || offset > 0) {
+ layoutManager.scrollToPositionWithOffset(position, (int) offset);
// restore once, then forget
SharedPreferences.Editor editor = prefs.edit();
- editor.putInt(PREF_KEY_LIST_SELECTION, 0);
- editor.putInt(PREF_KEY_LIST_TOP, 0);
+ editor.putInt(PREF_SCROLL_POSITION, 0);
+ editor.putFloat(PREF_SCROLL_OFFSET, 0.0f);
editor.commit();
}
}
private void resetViewState() {
- unregisterForContextMenu(listView);
- listAdapter = null;
- activity.set(null);
- undoBarController = null;
- viewsCreated = false;
+ recyclerAdapter = null;
blockDownloadObserverUpdate = false;
if (downloadObserver != null) {
downloadObserver.onPause();
@@ -208,17 +229,14 @@ public class QueueFragment extends Fragment {
resetViewState();
}
- private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() {
- @Override
- public boolean isRefreshing() {
- return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
- }
+ private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = () -> {
+ return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
};
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded) {
+ if (queue != null) {
inflater.inflate(R.menu.queue, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
@@ -251,14 +269,9 @@ public class QueueFragment extends Fragment {
switch (item.getItemId()) {
case R.id.queue_lock:
boolean locked = !UserPreferences.isQueueLocked();
- if(locked) {
- listView.setDragEnabled(false);
- } else {
- listView.setDragEnabled(true);
- }
UserPreferences.setQueueLocked(locked);
getActivity().supportInvalidateOptionsMenu();
- listAdapter.setLocked(locked);
+ recyclerAdapter.setLocked(locked);
return true;
case R.id.refresh_item:
List<Feed> feeds = ((MainActivity) getActivity()).getFeeds();
@@ -305,54 +318,19 @@ public class QueueFragment extends Fragment {
} else {
return true;
}
-
}
- private final FeedItemMenuHandler.MenuInterface contextMenuInterface = new FeedItemMenuHandler.MenuInterface() {
- @Override
- public void setItemVisibility(int id, boolean visible) {
- if(contextMenu == null) {
- return;
- }
- MenuItem item = contextMenu.findItem(id);
- if (item != null) {
- item.setVisible(visible);
- }
- }
- };
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
- FeedItem item = itemAccess.getItem(adapterInfo.position);
-
- MenuInflater inflater = getActivity().getMenuInflater();
- inflater.inflate(R.menu.queue_context, menu);
-
- if (item != null) {
- menu.setHeaderTitle(item.getTitle());
- }
-
- contextMenu = menu;
- lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
- LongList queueIds = new LongList(queue.size());
- for(FeedItem queueItem : queue) {
- queueIds.add(queueItem.getId());
- }
- FeedItemMenuHandler.onPrepareMenu(getActivity(), contextMenuInterface, item, true, queueIds);
- }
@Override
public boolean onContextItemSelected(MenuItem item) {
- AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
- if(menuInfo == null) {
- menuInfo = lastMenuInfo;
+ if(!isVisible()) {
+ return false;
}
- FeedItem selectedItem = itemAccess.getItem(menuInfo.position);
+ int pos = recyclerAdapter.getPosition();
+ FeedItem selectedItem = itemAccess.getItem(pos);
if (selectedItem == null) {
- Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection");
+ Log.i(TAG, "Selected item at position " + pos + " was null, ignoring selection");
return super.onContextItemSelected(item);
}
@@ -373,112 +351,111 @@ public class QueueFragment extends Fragment {
View root = inflater.inflate(R.layout.queue_fragment, container, false);
infoBar = (TextView) root.findViewById(R.id.info_bar);
- listView = (DragSortListView) root.findViewById(android.R.id.list);
- txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
- progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
- listView.setEmptyView(txtvEmpty);
+ recyclerView = (RecyclerView) root.findViewById(R.id.recyclerView);
+ layoutManager = new LinearLayoutManager(getActivity());
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
+ recyclerView.setHasFixedSize(true);
+ registerForContextMenu(recyclerView);
- if(UserPreferences.isQueueLocked()) {
- listView.setDragEnabled(false);
- } else {
- listView.setDragEnabled(true);
- }
+ itemTouchHelper = new ItemTouchHelper(
+ new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT) {
- listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- FeedItem item = (FeedItem) listAdapter.getItem(position - listView.getHeaderViewsCount());
- if (item != null) {
- ((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
+ int from = viewHolder.getAdapterPosition();
+ int to = target.getAdapterPosition();
+ Log.d(TAG, "move(" + from + ", " + to + ")");
+ Collections.swap(queue, from, to);
+ recyclerAdapter.notifyItemMoved(from, to);
+ DBWriter.moveQueueItem(from, to, false);
+ return true;
}
- }
- });
-
- listView.setDragSortListener(new DragSortListView.DragSortListener() {
- @Override
- public void drag(int from, int to) {
- Log.d(TAG, "drag");
- blockDownloadObserverUpdate = true;
- }
- @Override
- public void drop(int from, int to) {
- Log.d(TAG, "drop");
- blockDownloadObserverUpdate = false;
- if(subscription != null) {
- subscription.unsubscribe();
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ final int position = viewHolder.getAdapterPosition();
+ Log.d(TAG, "remove(" + position + ")");
+ final FeedItem item = queue.get(position);
+ final boolean isRead = item.isPlayed();
+ DBWriter.markItemPlayed(FeedItem.PLAYED, item.getId());
+ DBWriter.removeQueueItem(getActivity(), item, true);
+ Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG);
+ snackbar.setAction(getString(R.string.undo), v -> {
+ DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
+ if(false == isRead) {
+ DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
+ }
+ });
+ snackbar.show();
}
- final FeedItem item = queue.remove(from);
- queue.add(to, item);
- listAdapter.notifyDataSetChanged();
- DBWriter.moveQueueItem(from, to, true);
- }
- @Override
- public void remove(int which) {
- Log.d(TAG, "remove(" + which + ")");
- if(subscription != null) {
- subscription.unsubscribe();
+ @Override
+ public boolean isLongPressDragEnabled() {
+ return false == UserPreferences.isQueueLocked();
}
- FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
- DBWriter.removeQueueItem(getActivity(), item, true);
- }
- });
-
- undoBarController = new UndoBarController<FeedItemUndoToken>(root.findViewById(R.id.undobar),
- new UndoBarController.UndoListener<FeedItemUndoToken>() {
-
- private final Context context = getActivity();
- @Override
- public void onUndo(FeedItemUndoToken token) {
- if (token != null) {
- long itemId = token.getFeedItemId();
- int position = token.getPosition();
- DBWriter.addQueueItemAt(context, itemId, position, false);
+ @Override
+ public boolean isItemViewSwipeEnabled() {
+ return false == UserPreferences.isQueueLocked();
}
- }
- @Override
- public void onHide(FeedItemUndoToken token) {
- if (token != null && context != null) {
- long itemId = token.getFeedItemId();
- FeedItem item = DBReader.getFeedItem(itemId);
- if(item != null) {
- FeedMedia media = item.getMedia();
- if (media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) {
- DBWriter.deleteFeedMediaOfItem(context, media.getId());
+ @Override
+ public void onSelectedChanged(RecyclerView.ViewHolder viewHolder,
+ int actionState) {
+ // We only want the active item
+ if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
+ if (viewHolder instanceof QueueRecyclerAdapter.ItemTouchHelperViewHolder) {
+ QueueRecyclerAdapter.ItemTouchHelperViewHolder itemViewHolder =
+ (QueueRecyclerAdapter.ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemSelected();
}
}
+
+ super.onSelectedChanged(viewHolder, actionState);
+ }
+ @Override
+ public void clearView(RecyclerView recyclerView,
+ RecyclerView.ViewHolder viewHolder) {
+ super.clearView(recyclerView, viewHolder);
+
+ if (viewHolder instanceof QueueRecyclerAdapter.ItemTouchHelperViewHolder) {
+ QueueRecyclerAdapter.ItemTouchHelperViewHolder itemViewHolder =
+ (QueueRecyclerAdapter.ItemTouchHelperViewHolder) viewHolder;
+ itemViewHolder.onItemClear();
+ }
}
}
+ );
+ itemTouchHelper.attachToRecyclerView(recyclerView);
- });
-
- registerForContextMenu(listView);
-
- if (!itemsLoaded) {
- progLoading.setVisibility(View.VISIBLE);
- txtvEmpty.setVisibility(View.GONE);
- }
-
- viewsCreated = true;
-
- if (itemsLoaded && activity.get() != null) {
- onFragmentLoaded();
- }
+ txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
+ txtvEmpty.setVisibility(View.GONE);
+ progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
+ progLoading.setVisibility(View.VISIBLE);
return root;
}
private void onFragmentLoaded() {
- if (listAdapter == null) {
- listAdapter = new QueueListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get()));
- listView.setAdapter(listAdapter);
- downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback);
+ if (recyclerAdapter == null) {
+ MainActivity activity = (MainActivity) getActivity();
+ recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess,
+ new DefaultActionButtonCallback(activity), itemTouchHelper);
+ recyclerView.setAdapter(recyclerAdapter);
+ downloadObserver = new DownloadObserver(activity, new Handler(), downloadObserverCallback);
downloadObserver.onResume();
}
- listAdapter.notifyDataSetChanged();
+ if(queue == null || queue.size() == 0) {
+ recyclerView.setVisibility(View.GONE);
+ txtvEmpty.setVisibility(View.VISIBLE);
+ } else {
+ txtvEmpty.setVisibility(View.GONE);
+ recyclerView.setVisibility(View.VISIBLE);
+ }
restoreScrollPosition();
@@ -486,7 +463,10 @@ public class QueueFragment extends Fragment {
// needs data that may have just been loaded.
getActivity().supportInvalidateOptionsMenu();
- // refresh information bar
+ refreshInfoBar();
+ }
+
+ private void refreshInfoBar() {
String info = queue.size() + getString(R.string.episodes_suffix);
if(queue.size() > 0) {
long duration = 0;
@@ -505,21 +485,21 @@ public class QueueFragment extends Fragment {
@Override
public void onContentChanged(List<Downloader> downloaderList) {
QueueFragment.this.downloaderList = downloaderList;
- if (listAdapter != null && !blockDownloadObserverUpdate) {
- listAdapter.notifyDataSetChanged();
+ if (recyclerAdapter != null && !blockDownloadObserverUpdate) {
+ recyclerAdapter.notifyDataSetChanged();
}
}
};
- private QueueListAdapter.ItemAccess itemAccess = new QueueListAdapter.ItemAccess() {
+ private QueueRecyclerAdapter.ItemAccess itemAccess = new QueueRecyclerAdapter.ItemAccess() {
@Override
public int getCount() {
- return (itemsLoaded) ? queue.size() : 0;
+ return queue != null ? queue.size() : 0;
}
@Override
public FeedItem getItem(int position) {
- return (itemsLoaded) ? queue.get(position) : null;
+ return queue != null ? queue.get(position) : null;
}
@Override
@@ -561,6 +541,11 @@ public class QueueFragment extends Fragment {
}
return 0;
}
+
+ @Override
+ public LongList getQueueIds() {
+ return queue != null ? LongList.of(FeedItemUtil.getIds(queue)) : new LongList(0);
+ }
};
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@@ -579,23 +564,19 @@ public class QueueFragment extends Fragment {
if(subscription != null) {
subscription.unsubscribe();
}
- if (viewsCreated && !itemsLoaded) {
- listView.setVisibility(View.GONE);
+ if (queue == null) {
+ recyclerView.setVisibility(View.GONE);
txtvEmpty.setVisibility(View.GONE);
progLoading.setVisibility(View.VISIBLE);
}
subscription = Observable.defer(() -> Observable.just(DBReader.getQueue()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> {
- listView.setVisibility(View.VISIBLE);
- progLoading.setVisibility(View.GONE);
- if(result != null) {
- queue = result;
- itemsLoaded = true;
- if (viewsCreated && activity.get() != null) {
- onFragmentLoaded();
- }
+ .subscribe(items -> {
+ if(items != null) {
+ progLoading.setVisibility(View.GONE);
+ queue = items;
+ onFragmentLoaded();
}
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
diff --git a/app/src/main/java/de/danoeh/antennapod/view/DividerItemDecoration.java b/app/src/main/java/de/danoeh/antennapod/view/DividerItemDecoration.java
deleted file mode 100644
index c32f7e702..000000000
--- a/app/src/main/java/de/danoeh/antennapod/view/DividerItemDecoration.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package de.danoeh.antennapod.view;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class DividerItemDecoration extends RecyclerView.ItemDecoration {
-
- private Drawable mDivider;
- private boolean mShowFirstDivider = false;
- private boolean mShowLastDivider = false;
-
-
- public DividerItemDecoration(Context context, AttributeSet attrs) {
- final TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.listDivider });
- mDivider = a.getDrawable(0);
- a.recycle();
- }
-
- public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
- boolean showLastDivider) {
- this(context, attrs);
- mShowFirstDivider = showFirstDivider;
- mShowLastDivider = showLastDivider;
- }
-
- public DividerItemDecoration(Drawable divider) {
- mDivider = divider;
- }
-
- public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
- boolean showLastDivider) {
- this(divider);
- mShowFirstDivider = showFirstDivider;
- mShowLastDivider = showLastDivider;
- }
-
- @Override
- public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
- RecyclerView.State state) {
- super.getItemOffsets(outRect, view, parent, state);
- if (mDivider == null) {
- return;
- }
- if (parent.getChildPosition(view) < 1) {
- return;
- }
-
- if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
- outRect.top = mDivider.getIntrinsicHeight();
- } else {
- outRect.left = mDivider.getIntrinsicWidth();
- }
- }
-
- @Override
- public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
- if (mDivider == null) {
- super.onDrawOver(c, parent, state);
- return;
- }
-
- // Initialization needed to avoid compiler warning
- int left = 0, right = 0, top = 0, bottom = 0, size;
- int orientation = getOrientation(parent);
- int childCount = parent.getChildCount();
-
- if (orientation == LinearLayoutManager.VERTICAL) {
- size = mDivider.getIntrinsicHeight();
- left = parent.getPaddingLeft();
- right = parent.getWidth() - parent.getPaddingRight();
- } else { //horizontal
- size = mDivider.getIntrinsicWidth();
- top = parent.getPaddingTop();
- bottom = parent.getHeight() - parent.getPaddingBottom();
- }
-
- for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
- View child = parent.getChildAt(i);
- RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
-
- if (orientation == LinearLayoutManager.VERTICAL) {
- top = child.getTop() - params.topMargin;
- bottom = top + size;
- } else { //horizontal
- left = child.getLeft() - params.leftMargin;
- right = left + size;
- }
- mDivider.setBounds(left, top, right, bottom);
- mDivider.draw(c);
- }
-
- // show last divider
- if (mShowLastDivider && childCount > 0) {
- View child = parent.getChildAt(childCount - 1);
- RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
- if (orientation == LinearLayoutManager.VERTICAL) {
- top = child.getBottom() + params.bottomMargin;
- bottom = top + size;
- } else { // horizontal
- left = child.getRight() + params.rightMargin;
- right = left + size;
- }
- mDivider.setBounds(left, top, right, bottom);
- mDivider.draw(c);
- }
- }
-
- private int getOrientation(RecyclerView parent) {
- if (parent.getLayoutManager() instanceof LinearLayoutManager) {
- LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
- return layoutManager.getOrientation();
- } else {
- throw new IllegalStateException(
- "DividerItemDecoration can only be used with a LinearLayoutManager.");
- }
- }
-}