mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2024-12-25 16:23:54 +01:00
Migrated download screen to RecyclerView
This commit is contained in:
parent
7db3da273a
commit
6066fef1f2
@ -1,67 +0,0 @@
|
||||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
|
||||
/**
|
||||
* Shows a list of downloaded episodes.
|
||||
*/
|
||||
public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
||||
|
||||
private final MainActivity activity;
|
||||
private final ItemAccess itemAccess;
|
||||
|
||||
public DownloadedEpisodesListAdapter(MainActivity activity, ItemAccess itemAccess) {
|
||||
super();
|
||||
this.activity = activity;
|
||||
this.itemAccess = itemAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return itemAccess.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem 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) {
|
||||
EpisodeItemViewHolder holder;
|
||||
if (convertView == null) {
|
||||
holder = new EpisodeItemViewHolder(activity, parent);
|
||||
} else {
|
||||
holder = (EpisodeItemViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
final FeedItem item = getItem(position);
|
||||
holder.bind(item);
|
||||
holder.dragHandle.setVisibility(View.GONE);
|
||||
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(activity, R.attr.ic_delete));
|
||||
holder.secondaryActionButton.setOnClickListener(v -> itemAccess.onFeedItemSecondaryAction(item));
|
||||
holder.hideSeparatorIfNecessary();
|
||||
|
||||
return holder.itemView;
|
||||
}
|
||||
|
||||
public interface ItemAccess {
|
||||
int getCount();
|
||||
|
||||
FeedItem getItem(int position);
|
||||
|
||||
void onFeedItemSecondaryAction(FeedItem item);
|
||||
}
|
||||
}
|
@ -1,61 +1,81 @@
|
||||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.ListFragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
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.FeedItemUtil;
|
||||
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_ADD_TO_QUEUE;
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DELETE;
|
||||
|
||||
/**
|
||||
* Displays all running downloads and provides a button to delete them
|
||||
* Displays all completed downloads and provides a button to delete them.
|
||||
*/
|
||||
public class CompletedDownloadsFragment extends ListFragment {
|
||||
public class CompletedDownloadsFragment extends Fragment {
|
||||
|
||||
private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
|
||||
|
||||
private List<FeedItem> items = new ArrayList<>();
|
||||
private DownloadedEpisodesListAdapter listAdapter;
|
||||
private CompletedDownloadsListAdapter adapter;
|
||||
private RecyclerView recyclerView;
|
||||
private Disposable disposable;
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
addVerticalPadding();
|
||||
addEmptyView();
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.simple_list_fragment, container, false);
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
toolbar.setVisibility(View.GONE);
|
||||
|
||||
listAdapter = new DownloadedEpisodesListAdapter((MainActivity) getActivity(), itemAccess);
|
||||
setListAdapter(listAdapter);
|
||||
setListShown(false);
|
||||
recyclerView = root.findViewById(R.id.recyclerView);
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
adapter = new CompletedDownloadsListAdapter((MainActivity) getActivity());
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
addEmptyView();
|
||||
EventBus.getDefault().register(this);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,6 +87,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
setHasOptionsMenu(true);
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@ -78,14 +99,6 @@ public class CompletedDownloadsFragment extends ListFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
position -= l.getHeaderViewsCount();
|
||||
long[] ids = FeedItemUtil.getIds(items);
|
||||
((MainActivity) requireActivity()).loadChildFragment(ItemPagerFragment.newInstance(ids, position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
@ -103,41 +116,66 @@ public class CompletedDownloadsFragment extends ListFragment {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
||||
FeedItem selectedItem = adapter.getSelectedItem();
|
||||
if (selectedItem == null) {
|
||||
Log.i(TAG, "Selected item at current position was null, ignoring selection");
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
return FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), selectedItem);
|
||||
}
|
||||
|
||||
private void addEmptyView() {
|
||||
EmptyViewHandler emptyView = new EmptyViewHandler(getActivity());
|
||||
emptyView.setIcon(R.attr.av_download);
|
||||
emptyView.setTitle(R.string.no_comp_downloads_head_label);
|
||||
emptyView.setMessage(R.string.no_comp_downloads_label);
|
||||
emptyView.attachToListView(getListView());
|
||||
emptyView.attachToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
private void addVerticalPadding() {
|
||||
final ListView lv = getListView();
|
||||
lv.setClipToPadding(false);
|
||||
final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding);
|
||||
lv.setPadding(0, vertPadding, 0, vertPadding);
|
||||
}
|
||||
|
||||
private final DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return items.size();
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(FeedItemEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
if (items == null) {
|
||||
return;
|
||||
} else if (adapter == null) {
|
||||
loadItems();
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
if (0 <= position && position < items.size()) {
|
||||
return items.get(position);
|
||||
} else {
|
||||
return null;
|
||||
for (int i = 0, size = event.items.size(); i < size; i++) {
|
||||
FeedItem item = event.items.get(i);
|
||||
int pos = FeedItemUtil.indexOfItemWithId(items, item.getId());
|
||||
if (pos >= 0) {
|
||||
items.remove(pos);
|
||||
if (item.getMedia().isDownloaded()) {
|
||||
items.add(pos, item);
|
||||
adapter.notifyItemChanged(pos);
|
||||
} else {
|
||||
adapter.notifyItemRemoved(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFeedItemSecondaryAction(FeedItem item) {
|
||||
DBWriter.deleteFeedMediaOfItem(requireActivity(), item.getMedia().getId());
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(PlaybackPositionEvent event) {
|
||||
if (adapter != null) {
|
||||
for (int i = 0; i < adapter.getItemCount(); i++) {
|
||||
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) recyclerView.findViewHolderForAdapterPosition(i);
|
||||
if (holder != null && holder.isCurrentlyPlayingItem()) {
|
||||
holder.notifyPlaybackPositionUpdated(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onPlayerStatusChanged(PlayerStatusEvent event) {
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDownloadLogChanged(DownloadLogEvent event) {
|
||||
@ -158,13 +196,22 @@ public class CompletedDownloadsFragment extends ListFragment {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
items = result;
|
||||
onItemsLoaded();
|
||||
adapter.updateItems(result);
|
||||
requireActivity().invalidateOptionsMenu();
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
private void onItemsLoaded() {
|
||||
setListShown(true);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
requireActivity().invalidateOptionsMenu();
|
||||
private static class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
|
||||
|
||||
public CompletedDownloadsListAdapter(MainActivity mainActivity) {
|
||||
super(mainActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) {
|
||||
super.onBindViewHolder(holder, pos);
|
||||
DeleteActionButton actionButton = new DeleteActionButton(getItem(pos));
|
||||
actionButton.configure(holder.secondaryActionButton, holder.secondaryActionIcon, getActivity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user