Fix context menu click ending up in wrong fragment

This can have all kinds of weird side effects.
For example, it could trigger the "delete" button of a podcast
and then ask for deleting another one because another fragment
handles the deletion.
This commit is contained in:
ByteHamster 2022-03-13 10:53:19 +01:00
parent bb92f1353d
commit 48d6dc8eb8
10 changed files with 68 additions and 7 deletions

View File

@ -265,7 +265,7 @@ public class CompletedDownloadsFragment extends Fragment implements
speedDialView.setVisibility(View.GONE);
}
private static class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
private class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
public CompletedDownloadsListAdapter(MainActivity mainActivity) {
super(mainActivity);
@ -285,6 +285,7 @@ public class CompletedDownloadsFragment extends Fragment implements
if (!inActionMode()) {
menu.findItem(R.id.multi_select).setVisible(true);
}
MenuItemUtils.setOnClickListeners(menu, CompletedDownloadsFragment.this::onContextItemSelected);
}
}
}

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
@ -285,7 +286,13 @@ public abstract class EpisodesListFragment extends Fragment {
*/
private void createRecycleAdapter(RecyclerView recyclerView, EmptyViewHandler emptyViewHandler) {
MainActivity mainActivity = (MainActivity) getActivity();
listAdapter = new EpisodeItemListAdapter(mainActivity);
listAdapter = new EpisodeItemListAdapter(mainActivity) {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuItemUtils.setOnClickListeners(menu, EpisodesListFragment.this::onContextItemSelected);
}
};
listAdapter.updateItems(episodes);
recyclerView.setAdapter(listAdapter);
emptyViewHandler.updateAdapter(listAdapter);

View File

@ -639,7 +639,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
}
}
private static class FeedItemListAdapter extends EpisodeItemListAdapter {
private class FeedItemListAdapter extends EpisodeItemListAdapter {
public FeedItemListAdapter(MainActivity mainActivity) {
super(mainActivity);
}
@ -655,6 +655,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
if (!inActionMode()) {
menu.findItem(R.id.multi_select).setVisible(true);
}
MenuItemUtils.setOnClickListeners(menu, FeedItemlistFragment.this::onContextItemSelected);
}
}
}

View File

@ -28,6 +28,7 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.NavListAdapter;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.event.QueueEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
@ -132,6 +133,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
} else {
inflater.inflate(R.menu.nav_folder_context, menu);
}
MenuItemUtils.setOnClickListeners(menu, this::onContextItemSelected);
}
@Override

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
@ -17,6 +18,7 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
@ -245,7 +247,7 @@ public class PlaybackHistoryFragment extends Fragment implements Toolbar.OnMenuI
return history;
}
private static class PlaybackHistoryListAdapter extends EpisodeItemListAdapter {
private class PlaybackHistoryListAdapter extends EpisodeItemListAdapter {
public PlaybackHistoryListAdapter(MainActivity mainActivity) {
super(mainActivity);
@ -258,5 +260,11 @@ public class PlaybackHistoryFragment extends Fragment implements Toolbar.OnMenuI
// it harder to read.
holder.itemView.setAlpha(1.0f);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuItemUtils.setOnClickListeners(menu, PlaybackHistoryFragment.this::onContextItemSelected);
}
}
}

View File

@ -7,6 +7,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
@ -522,7 +523,13 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
if (queue != null) {
if (recyclerAdapter == null) {
MainActivity activity = (MainActivity) getActivity();
recyclerAdapter = new QueueRecyclerAdapter(activity, swipeActions);
recyclerAdapter = new QueueRecyclerAdapter(activity, swipeActions) {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuItemUtils.setOnClickListeners(menu, QueueFragment.this::onContextItemSelected);
}
};
recyclerAdapter.setOnSelectModeListener(this);
recyclerView.setAdapter(recyclerAdapter);
emptyView.updateAdapter(recyclerAdapter);

View File

@ -7,6 +7,7 @@ import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.Pair;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -29,6 +30,7 @@ import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
import de.danoeh.antennapod.adapter.FeedSearchResultAdapter;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
@ -129,7 +131,13 @@ public class SearchFragment extends Fragment {
recyclerView = layout.findViewById(R.id.recyclerView);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
adapter = new EpisodeItemListAdapter((MainActivity) getActivity());
adapter = new EpisodeItemListAdapter((MainActivity) getActivity()) {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuItemUtils.setOnClickListeners(menu, SearchFragment.this::onContextItemSelected);
}
};
recyclerView.setAdapter(adapter);
RecyclerView recyclerViewFeeds = layout.findViewById(R.id.recyclerViewFeeds);

View File

@ -8,6 +8,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -252,7 +253,13 @@ public class SubscriptionFragment extends Fragment
@Override
public void onViewCreated(@NonNull View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
subscriptionAdapter = new SubscriptionsRecyclerAdapter((MainActivity) getActivity());
subscriptionAdapter = new SubscriptionsRecyclerAdapter((MainActivity) getActivity()) {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuItemUtils.setOnClickListeners(menu, SubscriptionFragment.this::onContextItemSelected);
}
};
subscriptionAdapter.setOnSelectModeListener(this);
subscriptionRecycler.setAdapter(subscriptionAdapter);
setupEmptyView();

View File

@ -25,6 +25,7 @@ import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
@ -170,6 +171,7 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene
menu.add(Menu.NONE, R.id.share_url_item, Menu.NONE, R.string.share_url_label);
menu.setHeaderTitle(selectedUrl);
}
MenuItemUtils.setOnClickListeners(menu, this::onContextItemSelected);
}
public void setTimecodeSelectedListener(Consumer<Integer> timecodeSelectedListener) {

View File

@ -35,4 +35,22 @@ public class MenuItemUtils {
public interface UpdateRefreshMenuItemChecker {
boolean isRefreshing();
}
/**
* When pressing a context menu item, Android calls onContextItemSelected
* for ALL fragments in arbitrary order, not just for the fragment that the
* context menu was created from. This assigns the listener to every menu item,
* so that the correct fragment is always called first and can consume the click.
* <p />
* Note that Android still calls the onContextItemSelected methods of all fragments
* when the passed listener returns false.
*/
public static void setOnClickListeners(Menu menu, MenuItem.OnMenuItemClickListener listener) {
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).getSubMenu() != null) {
setOnClickListeners(menu.getItem(i).getSubMenu(), listener);
}
menu.getItem(i).setOnMenuItemClickListener(listener);
}
}
}