Moved Toolbar to individual Fragments

This commit is contained in:
ByteHamster 2020-03-12 13:28:30 +01:00
parent 03d1f41e9b
commit 7f4d43deb1
31 changed files with 967 additions and 844 deletions

View File

@ -1,7 +1,6 @@
package de.danoeh.antennapod.activity; package de.danoeh.antennapod.activity;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -11,18 +10,7 @@ import android.database.DataSetObserver;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.google.android.material.snackbar.Snackbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -31,25 +19,23 @@ import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.NavListAdapter; import de.danoeh.antennapod.adapter.NavListAdapter;
import de.danoeh.antennapod.core.asynctask.FeedRemover; import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.MessageEvent; import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
@ -77,6 +63,13 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
/** /**
* The activity that is shown when the user launches the app. * The activity that is shown when the user launches the app.
@ -96,7 +89,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
private static final String EXTRA_FEED_ID = "fragment_feed_id"; private static final String EXTRA_FEED_ID = "fragment_feed_id";
private static final String SAVE_BACKSTACK_COUNT = "backstackCount"; private static final String SAVE_BACKSTACK_COUNT = "backstackCount";
private static final String SAVE_TITLE = "title";
public static final String[] NAV_DRAWER_TAGS = { public static final String[] NAV_DRAWER_TAGS = {
QueueFragment.TAG, QueueFragment.TAG,
@ -108,15 +100,11 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
NavListAdapter.SUBSCRIPTION_LIST_TAG NavListAdapter.SUBSCRIPTION_LIST_TAG
}; };
private Toolbar toolbar;
private ExternalPlayerFragment externalPlayerFragment;
private DrawerLayout drawerLayout; private DrawerLayout drawerLayout;
private View navDrawer; private View navDrawer;
private ListView navList;
private NavListAdapter navAdapter; private NavListAdapter navAdapter;
private int mPosition = -1; private int mPosition = -1;
private ActionBarDrawerToggle drawerToggle; private ActionBarDrawerToggle drawerToggle;
private CharSequence currentTitle;
private Disposable disposable; private Disposable disposable;
private long lastBackButtonPressTime = 0; private long lastBackButtonPressTime = 0;
@ -135,20 +123,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
StorageUtils.checkStorageAvailability(this); StorageUtils.checkStorageAvailability(this);
setContentView(R.layout.main); setContentView(R.layout.main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
findViewById(R.id.shadow).setVisibility(View.GONE);
int elevation = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4,
getResources().getDisplayMetrics());
getSupportActionBar().setElevation(elevation);
}
currentTitle = getTitle();
drawerLayout = findViewById(R.id.drawer_layout); drawerLayout = findViewById(R.id.drawer_layout);
navList = findViewById(R.id.nav_list); ListView navList = findViewById(R.id.nav_list);
navDrawer = findViewById(R.id.nav_layout); navDrawer = findViewById(R.id.nav_layout);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
@ -162,9 +138,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
fm.addOnBackStackChangedListener(() -> drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0)); fm.addOnBackStackChangedListener(() -> drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
navAdapter = new NavListAdapter(itemAccess, this); navAdapter = new NavListAdapter(itemAccess, this);
navList.setAdapter(navAdapter); navList.setAdapter(navAdapter);
navList.setOnItemClickListener(navListClickListener); navList.setOnItemClickListener(navListClickListener);
@ -203,7 +176,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
} }
} }
} }
externalPlayerFragment = new ExternalPlayerFragment(); ExternalPlayerFragment externalPlayerFragment = new ExternalPlayerFragment();
transaction.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG); transaction.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG);
transaction.commit(); transaction.commit();
@ -315,8 +288,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
args = null; args = null;
break; break;
} }
currentTitle = navAdapter.getLabel(tag);
getSupportActionBar().setTitle(currentTitle);
saveLastNavFragment(tag); saveLastNavFragment(tag);
if (args != null) { if (args != null) {
fragment.setArguments(args); fragment.setArguments(args);
@ -338,8 +309,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
fragment.setArguments(args); fragment.setArguments(args);
} }
saveLastNavFragment(String.valueOf(feedId)); saveLastNavFragment(String.valueOf(feedId));
currentTitle = "";
getSupportActionBar().setTitle(currentTitle);
loadFragment(fragment); loadFragment(fragment);
} }
@ -452,10 +421,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);
drawerToggle.syncState(); drawerToggle.syncState();
if (savedInstanceState != null) { if (savedInstanceState != null) {
currentTitle = savedInstanceState.getString(SAVE_TITLE);
if (!drawerLayout.isDrawerOpen(navDrawer)) {
getSupportActionBar().setTitle(currentTitle);
}
selectedNavListIndex = getSelectedNavListIndex(); selectedNavListIndex = getSelectedNavListIndex();
} }
} }
@ -469,7 +434,6 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
@Override @Override
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(SAVE_TITLE, getSupportActionBar().getTitle().toString());
outState.putInt(SAVE_BACKSTACK_COUNT, getSupportFragmentManager().getBackStackEntryCount()); outState.putInt(SAVE_BACKSTACK_COUNT, getSupportFragmentManager().getBackStackEntryCount());
} }

View File

@ -13,26 +13,17 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.PluralsRes; import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.collection.ArrayMap; import androidx.collection.ArrayMap;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView; import com.leinardi.android.speeddial.SpeedDialView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
@ -43,6 +34,12 @@ import de.danoeh.antennapod.core.util.FeedItemPermutors;
import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.SortOrder; import de.danoeh.antennapod.core.util.SortOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class EpisodesApplyActionFragment extends Fragment { public class EpisodesApplyActionFragment extends Fragment {
public static final String TAG = "EpisodeActionFragment"; public static final String TAG = "EpisodeActionFragment";
@ -55,6 +52,7 @@ public class EpisodesApplyActionFragment extends Fragment {
public static final int ACTION_DELETE = 32; public static final int ACTION_DELETE = 32;
private static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE private static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
| ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE; | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE;
private Toolbar toolbar;
/** /**
* Specify an action (defined by #flag) 's UI bindings. * Specify an action (defined by #flag) 's UI bindings.
@ -76,20 +74,15 @@ public class EpisodesApplyActionFragment extends Fragment {
} }
private final List<? extends ActionBinding> actionBindings; private final List<? extends ActionBinding> actionBindings;
private final Map<Long, FeedItem> idMap = new ArrayMap<>();
private ListView mListView;
private ArrayAdapter<String> mAdapter;
private SpeedDialView mSpeedDialView;
@NonNull
private CharSequence actionBarTitleOriginal = "";
private final Map<Long,FeedItem> idMap = new ArrayMap<>();
private final List<FeedItem> episodes = new ArrayList<>(); private final List<FeedItem> episodes = new ArrayList<>();
private int actions; private int actions;
private final List<String> titles = new ArrayList<>(); private final List<String> titles = new ArrayList<>();
private final LongList checkedIds = new LongList(); private final LongList checkedIds = new LongList();
private ListView mListView;
private ArrayAdapter<String> mAdapter;
private SpeedDialView mSpeedDialView;
private MenuItem mSelectToggle; private MenuItem mSelectToggle;
public EpisodesApplyActionFragment() { public EpisodesApplyActionFragment() {
@ -137,7 +130,7 @@ public class EpisodesApplyActionFragment extends Fragment {
mListView = view.findViewById(android.R.id.list); mListView = view.findViewById(android.R.id.list);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mListView.setOnItemClickListener((ListView, view1, position, rowId) -> { mListView.setOnItemClickListener((listView, view1, position, rowId) -> {
long id = episodes.get(position).getId(); long id = episodes.get(position).getId();
if (checkedIds.contains(id)) { if (checkedIds.contains(id)) {
checkedIds.remove(id); checkedIds.remove(id);
@ -177,8 +170,8 @@ public class EpisodesApplyActionFragment extends Fragment {
mAdapter = new ArrayAdapter<>(getActivity(), mAdapter = new ArrayAdapter<>(getActivity(),
R.layout.simple_list_item_multiple_choice_on_start, titles); R.layout.simple_list_item_multiple_choice_on_start, titles);
mListView.setAdapter(mAdapter); mListView.setAdapter(mAdapter);
toolbar = view.findViewById(R.id.toolbar);
saveActionBarTitle(); // needed when we dynamically change the title based on selection ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
// Init action UI (via a FAB Speed Dial) // Init action UI (via a FAB Speed Dial)
mSpeedDialView = view.findViewById(R.id.fabSD); mSpeedDialView = view.findViewById(R.id.fabSD);
@ -206,18 +199,10 @@ public class EpisodesApplyActionFragment extends Fragment {
} }
return true; return true;
}); });
refreshCheckboxes();
showSpeedDialIfAnyChecked();
return view; return view;
} }
@Override
public void onStop() {
restoreActionBarTitle(); // it might have been changed to "N selected". Restore original.
super.onStop();
}
private void showSpeedDialIfAnyChecked() { private void showSpeedDialIfAnyChecked() {
if (checkedIds.size() > 0) { if (checkedIds.size() > 0) {
if (!mSpeedDialView.isShown()) { if (!mSpeedDialView.isShown()) {
@ -327,7 +312,7 @@ public class EpisodesApplyActionFragment extends Fragment {
return true; return true;
} }
} }
if(resId != 0) { if (resId != 0) {
Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT) Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT)
.show(); .show();
return true; return true;
@ -345,7 +330,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkAll() { private void checkAll() {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(!checkedIds.contains(episode.getId())) { if (!checkedIds.contains(episode.getId())) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} }
} }
@ -359,12 +344,12 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkPlayed(boolean isPlayed) { private void checkPlayed(boolean isPlayed) {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(episode.isPlayed() == isPlayed) { if (episode.isPlayed() == isPlayed) {
if(!checkedIds.contains(episode.getId())) { if (!checkedIds.contains(episode.getId())) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} }
} else { } else {
if(checkedIds.contains(episode.getId())) { if (checkedIds.contains(episode.getId())) {
checkedIds.remove(episode.getId()); checkedIds.remove(episode.getId());
} }
} }
@ -374,12 +359,12 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkDownloaded(boolean isDownloaded) { private void checkDownloaded(boolean isDownloaded) {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) { if (episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) {
if(!checkedIds.contains(episode.getId())) { if (!checkedIds.contains(episode.getId())) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} }
} else { } else {
if(checkedIds.contains(episode.getId())) { if (checkedIds.contains(episode.getId())) {
checkedIds.remove(episode.getId()); checkedIds.remove(episode.getId());
} }
} }
@ -389,7 +374,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkQueued(boolean isQueued) { private void checkQueued(boolean isQueued) {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) { if (episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} else { } else {
checkedIds.remove(episode.getId()); checkedIds.remove(episode.getId());
@ -400,7 +385,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkWithMedia() { private void checkWithMedia() {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(episode.hasMedia()) { if (episode.hasMedia()) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} else { } else {
checkedIds.remove(episode.getId()); checkedIds.remove(episode.getId());
@ -425,35 +410,7 @@ public class EpisodesApplyActionFragment extends Fragment {
} }
ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity()); ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
showSpeedDialIfAnyChecked(); showSpeedDialIfAnyChecked();
updateActionBarTitle(); toolbar.setTitle(getString(R.string.num_selected_label, checkedIds.size()));
}
private void saveActionBarTitle() {
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
CharSequence title = actionBar.getTitle();
if (title == null) {
title = "";
}
actionBarTitleOriginal = title;
}
}
private void restoreActionBarTitle() {
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(actionBarTitleOriginal);
}
}
private void updateActionBarTitle() {
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
CharSequence title = checkedIds.size() > 0 ?
getString(R.string.num_selected_label, checkedIds.size()) :
actionBarTitleOriginal;
actionBar.setTitle(title);
}
} }
private void queueChecked() { private void queueChecked() {
@ -487,7 +444,7 @@ public class EpisodesApplyActionFragment extends Fragment {
// download the check episodes in the same order as they are currently displayed // download the check episodes in the same order as they are currently displayed
List<FeedItem> toDownload = new ArrayList<>(checkedIds.size()); List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(checkedIds.contains(episode.getId()) && episode.hasMedia()) { if (checkedIds.contains(episode.getId()) && episode.hasMedia()) {
toDownload.add(episode); toDownload.add(episode);
} }
} }
@ -503,7 +460,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void deleteChecked() { private void deleteChecked() {
for (long id : checkedIds.toArray()) { for (long id : checkedIds.toArray()) {
FeedItem episode = idMap.get(id); FeedItem episode = idMap.get(id);
if(episode.hasMedia()) { if (episode.hasMedia()) {
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId()); DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
} }
} }
@ -516,7 +473,7 @@ public class EpisodesApplyActionFragment extends Fragment {
getResources().getQuantityString(msgId, numItems, numItems), getResources().getQuantityString(msgId, numItems, numItems),
Snackbar.LENGTH_LONG Snackbar.LENGTH_LONG
) )
.setAction(android.R.string.ok, v -> {}) .setAction(android.R.string.ok, v -> { })
.show(); .show();
} }
getActivity().getSupportFragmentManager().popBackStack(); getActivity().getSupportFragmentManager().popBackStack();

View File

@ -6,6 +6,7 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -41,9 +42,8 @@ public class AddFeedFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.addfeed, container, false); View root = inflater.inflate(R.layout.addfeed, container, false);
activity = (MainActivity) getActivity(); activity = (MainActivity) getActivity();
activity.getSupportActionBar().setTitle(R.string.add_feed_label); ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
setupAdvancedSearchButtons(root); setupAdvancedSearchButtons(root);
setupSeachBox(root); setupSeachBox(root);

View File

@ -4,6 +4,8 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -37,6 +39,9 @@ public class DownloadsFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.pager_fragment, container, false); View root = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.downloads_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
viewPager = root.findViewById(R.id.viewpager); viewPager = root.findViewById(R.id.viewpager);
DownloadsPagerAdapter pagerAdapter = new DownloadsPagerAdapter(getChildFragmentManager(), getResources()); DownloadsPagerAdapter pagerAdapter = new DownloadsPagerAdapter(getChildFragmentManager(), getResources());

View File

@ -2,20 +2,18 @@ package de.danoeh.antennapod.fragment;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
public class EpisodesFragment extends Fragment { public class EpisodesFragment extends Fragment {
@ -38,22 +36,21 @@ public class EpisodesFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
} }
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
setHasOptionsMenu(true);
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.episodes_label);
View rootView = inflater.inflate(R.layout.pager_fragment, container, false); View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = rootView.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.episodes_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
viewPager = rootView.findViewById(R.id.viewpager); viewPager = rootView.findViewById(R.id.viewpager);
viewPager.setAdapter(new EpisodesPagerAdapter()); viewPager.setAdapter(new EpisodesPagerAdapter());
// Give the TabLayout the ViewPager // Give the TabLayout the ViewPager
tabLayout = rootView.findViewById(R.id.sliding_tabs); tabLayout = rootView.findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);
return rootView; return rootView;
} }

View File

@ -8,6 +8,8 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -22,6 +24,9 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.snackbar.Snackbar;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
@ -33,8 +38,10 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils; import de.danoeh.antennapod.core.util.LangUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText; import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.view.ToolbarIconTintManager;
import io.reactivex.Maybe; import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe; import io.reactivex.MaybeOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
@ -64,6 +71,8 @@ public class FeedInfoFragment extends Fragment {
private TextView txtvUrl; private TextView txtvUrl;
private TextView txtvAuthorHeader; private TextView txtvAuthorHeader;
private ImageView imgvBackground; private ImageView imgvBackground;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
public static FeedInfoFragment newInstance(Feed feed) { public static FeedInfoFragment newInstance(Feed feed) {
FeedInfoFragment fragment = new FeedInfoFragment(); FeedInfoFragment fragment = new FeedInfoFragment();
@ -82,23 +91,33 @@ public class FeedInfoFragment extends Fragment {
android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext() android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext()
.getSystemService(Context.CLIPBOARD_SERVICE); .getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(clipData); cm.setPrimaryClip(clipData);
Toast t = Toast.makeText(getContext(), R.string.copied_url_msg, Toast.LENGTH_SHORT); Snackbar.make(getView(), R.string.copied_url_msg, Snackbar.LENGTH_SHORT).show();
t.show();
} }
} }
}; };
@Override
public void onResume() {
super.onResume();
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.feed_info_label);
}
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.feedinfo, null); View root = inflater.inflate(R.layout.feedinfo, null);
Toolbar toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle("");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
@Override
protected void doTint(Context themedContext) {
if (optionsMenu == null) {
return;
}
optionsMenu.findItem(R.id.visit_website_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.location_web_site));
}
};
appBar.addOnOffsetChangedListener(iconTintManager);
setHasOptionsMenu(true); setHasOptionsMenu(true);
imgvCover = root.findViewById(R.id.imgvCover); imgvCover = root.findViewById(R.id.imgvCover);
@ -110,7 +129,6 @@ public class FeedInfoFragment extends Fragment {
// https://github.com/bumptech/glide/issues/529 // https://github.com/bumptech/glide/issues/529
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
txtvDescription = root.findViewById(R.id.txtvDescription); txtvDescription = root.findViewById(R.id.txtvDescription);
lblLanguage = root.findViewById(R.id.lblLanguage); lblLanguage = root.findViewById(R.id.lblLanguage);
txtvLanguage = root.findViewById(R.id.txtvLanguage); txtvLanguage = root.findViewById(R.id.txtvLanguage);
@ -201,6 +219,8 @@ public class FeedInfoFragment extends Fragment {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.feedinfo, menu); inflater.inflate(R.menu.feedinfo, menu);
optionsMenu = menu;
iconTintManager.updateTint();
} }
@Override @Override

View File

@ -1,6 +1,5 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.LightingColorFilter; import android.graphics.LightingColorFilter;
@ -12,31 +11,26 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.MenuItemCompat; import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.ListFragment; import androidx.fragment.app.Fragment;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconTextView; import com.joanzapata.iconify.widget.IconTextView;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.FeedItemlistAdapter; import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
@ -46,28 +40,23 @@ import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.DownloaderUpdate;
import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent; import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedEvent; import de.danoeh.antennapod.core.feed.FeedEvent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedItemFilter; import de.danoeh.antennapod.core.feed.FeedItemFilter;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.glide.FastBlurTransformation; import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemPermutors; import de.danoeh.antennapod.core.util.FeedItemPermutors;
import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.Optional; import de.danoeh.antennapod.core.util.Optional;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
@ -79,12 +68,17 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
/** /**
* Displays a list of FeedItems. * Displays a list of FeedItems.
*/ */
@SuppressLint("ValidFragment") public class FeedItemlistFragment extends Fragment implements AdapterView.OnItemClickListener {
public class FeedItemlistFragment extends ListFragment {
private static final String TAG = "ItemlistFragment"; private static final String TAG = "ItemlistFragment";
private static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id"; private static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id";
@ -102,6 +96,8 @@ public class FeedItemlistFragment extends ListFragment {
private ImageView imgvBackground; private ImageView imgvBackground;
private ImageView imgvCover; private ImageView imgvCover;
private TextView txtvInformation; private TextView txtvInformation;
private ListView listView;
private ProgressBar progressBar;
private Disposable disposable; private Disposable disposable;
@ -131,22 +127,23 @@ public class FeedItemlistFragment extends ListFragment {
feedID = args.getLong(ARGUMENT_FEED_ID); feedID = args.getLong(ARGUMENT_FEED_ID);
} }
@Nullable
@Override @Override
public void onHiddenChanged(boolean hidden) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
super.onHiddenChanged(hidden); @Nullable Bundle savedInstanceState) {
if (!hidden && getActivity() != null) { View root = inflater.inflate(R.layout.feed_item_list_fragment, container, false);
((MainActivity) getActivity()).getSupportActionBar().setTitle(""); Toolbar toolbar = root.findViewById(R.id.toolbar);
} toolbar.setTitle("");
} ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
@Override listView = root.findViewById(android.R.id.list);
public void onViewCreated(View view, Bundle savedInstanceState) { listView.setOnItemClickListener(this);
super.onViewCreated(view, savedInstanceState); registerForContextMenu(listView);
progressBar = root.findViewById(R.id.progLoading);
registerForContextMenu(getListView());
EventBus.getDefault().register(this); EventBus.getDefault().register(this);
loadItems(); loadItems();
return root;
} }
@Override @Override
@ -320,21 +317,20 @@ public class FeedItemlistFragment extends ListFragment {
} }
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(adapter == null) { if (adapter == null) {
return; return;
} }
position -= l.getHeaderViewsCount(); position -= listView.getHeaderViewsCount();
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
long[] ids = FeedItemUtil.getIds(feed.getItems()); long[] ids = FeedItemUtil.getIds(feed.getItems());
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position)); activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
activity.getSupportActionBar().setTitle(feed.getTitle());
} }
@Subscribe @Subscribe
public void onEvent(FeedEvent event) { public void onEvent(FeedEvent event) {
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
if(event.feedId == feedID) { if (event.feedId == feedID) {
loadItems(); loadItems();
} }
} }
@ -342,12 +338,12 @@ public class FeedItemlistFragment extends ListFragment {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FeedItemEvent event) { public void onEventMainThread(FeedItemEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if(feed == null || feed.getItems() == null || adapter == null) { if (feed == null || feed.getItems() == null || adapter == null) {
return; return;
} }
for(FeedItem item : event.items) { for (FeedItem item : event.items) {
int pos = FeedItemUtil.indexOfItemWithId(feed.getItems(), item.getId()); int pos = FeedItemUtil.indexOfItemWithId(feed.getItems(), item.getId());
if(pos >= 0) { if (pos >= 0) {
loadItems(); loadItems();
return; return;
} }
@ -369,7 +365,7 @@ public class FeedItemlistFragment extends ListFragment {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(PlaybackPositionEvent event) { public void onEventMainThread(PlaybackPositionEvent event) {
if (adapter != null) { if (adapter != null) {
adapter.notifyCurrentlyPlayingItemChanged(event, getListView()); adapter.notifyCurrentlyPlayingItemChanged(event, listView);
} }
} }
@ -412,39 +408,40 @@ public class FeedItemlistFragment extends ListFragment {
return; return;
} }
if (adapter == null) { if (adapter == null) {
setListAdapter(null); listView.setAdapter(null);
setupHeaderView(); setupHeaderView();
setupFooterView(); setupFooterView();
adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, false, true); adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, false, true);
setListAdapter(adapter); listView.setAdapter(adapter);
} }
refreshHeaderView(); refreshHeaderView();
setListShown(true); listView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
getActivity().supportInvalidateOptionsMenu(); getActivity().supportInvalidateOptionsMenu();
if (feed != null && feed.getNextPageLink() == null && listFooter != null) { if (feed != null && feed.getNextPageLink() == null && listFooter != null) {
getListView().removeFooterView(listFooter.getRoot()); listView.removeFooterView(listFooter.getRoot());
} }
} }
private void refreshHeaderView() { private void refreshHeaderView() {
if (getListView() == null || feed == null || !headerCreated) { if (listView == null || feed == null || !headerCreated) {
Log.e(TAG, "Unable to refresh header view"); Log.e(TAG, "Unable to refresh header view");
return; return;
} }
loadFeedImage(); loadFeedImage();
if(feed.hasLastUpdateFailed()) { if (feed.hasLastUpdateFailed()) {
txtvFailure.setVisibility(View.VISIBLE); txtvFailure.setVisibility(View.VISIBLE);
} else { } else {
txtvFailure.setVisibility(View.GONE); txtvFailure.setVisibility(View.GONE);
} }
txtvTitle.setText(feed.getTitle()); txtvTitle.setText(feed.getTitle());
if(feed.getItemFilter() != null) { if (feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter(); FeedItemFilter filter = feed.getItemFilter();
if(filter.getValues().length > 0) { if (filter.getValues().length > 0) {
if(feed.hasLastUpdateFailed()) { if (feed.hasLastUpdateFailed()) {
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) txtvInformation.getLayoutParams(); RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) txtvInformation.getLayoutParams();
p.addRule(RelativeLayout.BELOW, R.id.txtvFailure); p.addRule(RelativeLayout.BELOW, R.id.txtvFailure);
} }
@ -460,15 +457,14 @@ public class FeedItemlistFragment extends ListFragment {
} }
private void setupHeaderView() { private void setupHeaderView() {
if (getListView() == null || feed == null) { if (listView == null || feed == null) {
Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null"); Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null");
return; return;
} }
ListView lv = getListView();
LayoutInflater inflater = (LayoutInflater) LayoutInflater inflater = (LayoutInflater)
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View header = inflater.inflate(R.layout.feeditemlist_header, lv, false); View header = inflater.inflate(R.layout.feeditemlist_header, listView, false);
lv.addHeaderView(header); listView.addHeaderView(header);
txtvTitle = header.findViewById(R.id.txtvTitle); txtvTitle = header.findViewById(R.id.txtvTitle);
TextView txtvAuthor = header.findViewById(R.id.txtvAuthor); TextView txtvAuthor = header.findViewById(R.id.txtvAuthor);
@ -482,7 +478,6 @@ public class FeedItemlistFragment extends ListFragment {
txtvTitle.setText(feed.getTitle()); txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor()); txtvAuthor.setText(feed.getAuthor());
// https://github.com/bumptech/glide/issues/529 // https://github.com/bumptech/glide/issues/529
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
@ -530,16 +525,15 @@ public class FeedItemlistFragment extends ListFragment {
private void setupFooterView() { private void setupFooterView() {
if (getListView() == null || feed == null) { if (listView == null || feed == null) {
Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null"); Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null");
return; return;
} }
if (feed.isPaged() && feed.getNextPageLink() != null) { if (feed.isPaged() && feed.getNextPageLink() != null) {
ListView lv = getListView();
LayoutInflater inflater = (LayoutInflater) LayoutInflater inflater = (LayoutInflater)
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View header = inflater.inflate(R.layout.more_content_list_footer, lv, false); View header = inflater.inflate(R.layout.more_content_list_footer, listView, false);
lv.addFooterView(header); listView.addFooterView(header);
listFooter = new MoreContentListFooterUtil(header); listFooter = new MoreContentListFooterUtil(header);
listFooter.setClickListener(() -> { listFooter.setClickListener(() -> {
if (feed != null) { if (feed != null) {
@ -573,7 +567,7 @@ public class FeedItemlistFragment extends ListFragment {
}; };
private void loadItems() { private void loadItems() {
if(disposable != null) { if (disposable != null) {
disposable.dispose(); disposable.dispose();
} }
disposable = Observable.fromCallable(this::loadData) disposable = Observable.fromCallable(this::loadData)
@ -600,5 +594,4 @@ public class FeedItemlistFragment extends ListFragment {
} }
return Optional.ofNullable(feed); return Optional.ofNullable(feed);
} }
} }

View File

@ -4,11 +4,18 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference; import androidx.preference.SwitchPreference;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent; import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent;
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent; import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
@ -34,17 +41,11 @@ import java.util.Locale;
import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL; import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL;
public class FeedSettingsFragment extends PreferenceFragmentCompat { public class FeedSettingsFragment extends Fragment {
private static final CharSequence PREF_EPISODE_FILTER = "episodeFilter";
private static final String PREF_FEED_PLAYBACK_SPEED = "feedPlaybackSpeed";
private static final DecimalFormat SPEED_FORMAT =
new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US));
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
private static final String TAG = "FeedSettingsFragment"; private static final String TAG = "FeedSettingsFragment";
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
private Feed feed;
private Disposable disposable; private Disposable disposable;
private FeedPreferences feedPreferences;
public static FeedSettingsFragment newInstance(Feed feed) { public static FeedSettingsFragment newInstance(Feed feed) {
FeedSettingsFragment fragment = new FeedSettingsFragment(); FeedSettingsFragment fragment = new FeedSettingsFragment();
@ -54,13 +55,20 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
return fragment; return fragment;
} }
@Nullable
@Override @Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
addPreferencesFromResource(R.xml.feed_settings); View root = inflater.inflate(R.layout.feedsettings, container, false);
setupAutoDownloadGlobalPreference(); // To prevent transition animation because of summary update
long feedId = getArguments().getLong(EXTRA_FEED_ID); long feedId = getArguments().getLong(EXTRA_FEED_ID);
Toolbar toolbar = root.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
getFragmentManager().beginTransaction()
.replace(R.id.settings_fragment_container,
FeedSettingsPreferenceFragment.newInstance(feedId), "settings_fragment")
.commitAllowingStateLoss();
disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> { disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
Feed feed = DBReader.getFeed(feedId); Feed feed = DBReader.getFeed(feedId);
if (feed != null) { if (feed != null) {
@ -71,39 +79,12 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
}) })
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> toolbar.setSubtitle(result.getTitle()),
feed = result; error -> Log.d(TAG, Log.getStackTraceString(error)),
feedPreferences = feed.getPreferences(); () -> { });
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
setupAutoDownloadPreference();
setupKeepUpdatedPreference();
setupAutoDeletePreference();
setupVolumeReductionPreferences();
setupAuthentificationPreference();
setupEpisodeFilterPreference();
setupPlaybackSpeedPreference();
updateAutoDeleteSummary(); return root;
updateVolumeReductionValue();
updateAutoDownloadEnabled();
updatePlaybackSpeedPreference();
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
}
@Override
public void onResume() {
super.onResume();
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.feed_settings_label);
if (feed != null) {
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
}
}
@Override
public void onStop() {
super.onStop();
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(null);
} }
@Override @Override
@ -114,212 +95,275 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
} }
} }
private void setupPlaybackSpeedPreference() { public static class FeedSettingsPreferenceFragment extends PreferenceFragmentCompat {
ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED); private static final CharSequence PREF_EPISODE_FILTER = "episodeFilter";
private static final String PREF_FEED_PLAYBACK_SPEED = "feedPlaybackSpeed";
private static final DecimalFormat SPEED_FORMAT =
new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US));
final String[] speeds = getResources().getStringArray(R.array.playback_speed_values); private Feed feed;
String[] values = new String[speeds.length + 1]; private Disposable disposable;
values[0] = SPEED_FORMAT.format(SPEED_USE_GLOBAL); private FeedPreferences feedPreferences;
String[] entries = new String[speeds.length + 1]; public static FeedSettingsPreferenceFragment newInstance(long feedId) {
entries[0] = getString(R.string.feed_auto_download_global); FeedSettingsPreferenceFragment fragment = new FeedSettingsPreferenceFragment();
Bundle arguments = new Bundle();
System.arraycopy(speeds, 0, values, 1, speeds.length); arguments.putLong(EXTRA_FEED_ID, feedId);
System.arraycopy(speeds, 0, entries, 1, speeds.length); fragment.setArguments(arguments);
return fragment;
feedPlaybackSpeedPreference.setEntryValues(values);
feedPlaybackSpeedPreference.setEntries(entries);
feedPlaybackSpeedPreference.setOnPreferenceChangeListener((preference, newValue) -> {
feedPreferences.setFeedPlaybackSpeed(Float.parseFloat((String) newValue));
feed.savePreferences();
updatePlaybackSpeedPreference();
EventBus.getDefault().post(
new SpeedPresetChangedEvent(feedPreferences.getFeedPlaybackSpeed(), feed.getId()));
return false;
});
}
private void setupEpisodeFilterPreference() {
findPreference(PREF_EPISODE_FILTER).setOnPreferenceClickListener(preference -> {
new EpisodeFilterDialog(getContext(), feedPreferences.getFilter()) {
@Override
protected void onConfirmed(FeedFilter filter) {
feedPreferences.setFilter(filter);
feed.savePreferences();
}
}.show();
return false;
});
}
private void setupAuthentificationPreference() {
findPreference("authentication").setOnPreferenceClickListener(preference -> {
new AuthenticationDialog(getContext(),
R.string.authentication_label, true, false,
feedPreferences.getUsername(), feedPreferences.getPassword()) {
@Override
protected void onConfirmed(String username, String password, boolean saveUsernamePassword) {
feedPreferences.setUsername(username);
feedPreferences.setPassword(password);
feed.savePreferences();
}
}.show();
return false;
});
}
private void setupAutoDeletePreference() {
ListPreference autoDeletePreference = (ListPreference) findPreference("autoDelete");
autoDeletePreference.setOnPreferenceChangeListener((preference, newValue) -> {
switch ((String) newValue) {
case "global":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.GLOBAL);
break;
case "always":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.YES);
break;
case "never":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
break;
}
feed.savePreferences();
updateAutoDeleteSummary();
return false;
});
}
private void updatePlaybackSpeedPreference() {
ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED);
float speedValue = feedPreferences.getFeedPlaybackSpeed();
feedPlaybackSpeedPreference.setValue(SPEED_FORMAT.format(speedValue));
}
private void updateAutoDeleteSummary() {
ListPreference autoDeletePreference = findPreference("autoDelete");
switch (feedPreferences.getAutoDeleteAction()) {
case GLOBAL:
autoDeletePreference.setSummary(R.string.feed_auto_download_global);
autoDeletePreference.setValue("global");
break;
case YES:
autoDeletePreference.setSummary(R.string.feed_auto_download_always);
autoDeletePreference.setValue("always");
break;
case NO:
autoDeletePreference.setSummary(R.string.feed_auto_download_never);
autoDeletePreference.setValue("never");
break;
}
}
private void setupVolumeReductionPreferences() {
ListPreference volumeReductionPreference = (ListPreference) findPreference("volumeReduction");
volumeReductionPreference.setOnPreferenceChangeListener((preference, newValue) -> {
switch ((String) newValue) {
case "off":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.OFF);
break;
case "light":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
break;
case "heavy":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.HEAVY_REDUCTION);
break;
}
feed.savePreferences();
updateVolumeReductionValue();
EventBus.getDefault().post(
new VolumeAdaptionChangedEvent(feedPreferences.getVolumeAdaptionSetting(), feed.getId()));
return false;
});
}
private void updateVolumeReductionValue() {
ListPreference volumeReductionPreference = (ListPreference) findPreference("volumeReduction");
switch (feedPreferences.getVolumeAdaptionSetting()) {
case OFF:
volumeReductionPreference.setValue("off");
break;
case LIGHT_REDUCTION:
volumeReductionPreference.setValue("light");
break;
case HEAVY_REDUCTION:
volumeReductionPreference.setValue("heavy");
break;
}
}
private void setupKeepUpdatedPreference() {
SwitchPreference pref = (SwitchPreference) findPreference("keepUpdated");
pref.setChecked(feedPreferences.getKeepUpdated());
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean checked = newValue == Boolean.TRUE;
feedPreferences.setKeepUpdated(checked);
feed.savePreferences();
pref.setChecked(checked);
return false;
});
}
private void setupAutoDownloadGlobalPreference() {
if (!UserPreferences.isEnableAutodownload()) {
SwitchPreference autodl = findPreference("autoDownload");
autodl.setChecked(false);
autodl.setEnabled(false);
autodl.setSummary(R.string.auto_download_disabled_globally);
findPreference(PREF_EPISODE_FILTER).setEnabled(false);
}
}
private void setupAutoDownloadPreference() {
SwitchPreference pref = (SwitchPreference) findPreference("autoDownload");
pref.setEnabled(UserPreferences.isEnableAutodownload());
if (UserPreferences.isEnableAutodownload()) {
pref.setChecked(feedPreferences.getAutoDownload());
} else {
pref.setChecked(false);
pref.setSummary(R.string.auto_download_disabled_globally);
}
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean checked = newValue == Boolean.TRUE;
feedPreferences.setAutoDownload(checked);
feed.savePreferences();
updateAutoDownloadEnabled();
ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(getActivity(), checked);
dialog.createNewDialog().show();
pref.setChecked(checked);
return false;
});
}
private void updateAutoDownloadEnabled() {
if (feed != null && feed.getPreferences() != null) {
boolean enabled = feed.getPreferences().getAutoDownload() && UserPreferences.isEnableAutodownload();
findPreference(PREF_EPISODE_FILTER).setEnabled(enabled);
}
}
private class ApplyToEpisodesDialog extends ConfirmationDialog {
private final boolean autoDownload;
ApplyToEpisodesDialog(Context context, boolean autoDownload) {
super(context, R.string.auto_download_apply_to_items_title,
R.string.auto_download_apply_to_items_message);
this.autoDownload = autoDownload;
setPositiveText(R.string.yes);
setNegativeText(R.string.no);
} }
@Override @Override
public void onConfirmButtonPressed(DialogInterface dialog) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
DBWriter.setFeedsItemsAutoDownload(feed, autoDownload); addPreferencesFromResource(R.xml.feed_settings);
setupAutoDownloadGlobalPreference(); // To prevent transition animation because of summary update
long feedId = getArguments().getLong(EXTRA_FEED_ID);
disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
Feed feed = DBReader.getFeed(feedId);
if (feed != null) {
emitter.onSuccess(feed);
} else {
emitter.onComplete();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
feed = result;
feedPreferences = feed.getPreferences();
setupAutoDownloadPreference();
setupKeepUpdatedPreference();
setupAutoDeletePreference();
setupVolumeReductionPreferences();
setupAuthentificationPreference();
setupEpisodeFilterPreference();
setupPlaybackSpeedPreference();
updateAutoDeleteSummary();
updateVolumeReductionValue();
updateAutoDownloadEnabled();
updatePlaybackSpeedPreference();
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
}
@Override
public void onDestroy() {
super.onDestroy();
if (disposable != null) {
disposable.dispose();
}
}
private void setupPlaybackSpeedPreference() {
ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED);
final String[] speeds = getResources().getStringArray(R.array.playback_speed_values);
String[] values = new String[speeds.length + 1];
values[0] = SPEED_FORMAT.format(SPEED_USE_GLOBAL);
String[] entries = new String[speeds.length + 1];
entries[0] = getString(R.string.feed_auto_download_global);
System.arraycopy(speeds, 0, values, 1, speeds.length);
System.arraycopy(speeds, 0, entries, 1, speeds.length);
feedPlaybackSpeedPreference.setEntryValues(values);
feedPlaybackSpeedPreference.setEntries(entries);
feedPlaybackSpeedPreference.setOnPreferenceChangeListener((preference, newValue) -> {
feedPreferences.setFeedPlaybackSpeed(Float.parseFloat((String) newValue));
feed.savePreferences();
updatePlaybackSpeedPreference();
EventBus.getDefault().post(
new SpeedPresetChangedEvent(feedPreferences.getFeedPlaybackSpeed(), feed.getId()));
return false;
});
}
private void setupEpisodeFilterPreference() {
findPreference(PREF_EPISODE_FILTER).setOnPreferenceClickListener(preference -> {
new EpisodeFilterDialog(getContext(), feedPreferences.getFilter()) {
@Override
protected void onConfirmed(FeedFilter filter) {
feedPreferences.setFilter(filter);
feed.savePreferences();
}
}.show();
return false;
});
}
private void setupAuthentificationPreference() {
findPreference("authentication").setOnPreferenceClickListener(preference -> {
new AuthenticationDialog(getContext(),
R.string.authentication_label, true, false,
feedPreferences.getUsername(), feedPreferences.getPassword()) {
@Override
protected void onConfirmed(String username, String password, boolean saveUsernamePassword) {
feedPreferences.setUsername(username);
feedPreferences.setPassword(password);
feed.savePreferences();
}
}.show();
return false;
});
}
private void setupAutoDeletePreference() {
ListPreference autoDeletePreference = findPreference("autoDelete");
autoDeletePreference.setOnPreferenceChangeListener((preference, newValue) -> {
switch ((String) newValue) {
case "global":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.GLOBAL);
break;
case "always":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.YES);
break;
case "never":
feedPreferences.setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
break;
}
feed.savePreferences();
updateAutoDeleteSummary();
return false;
});
}
private void updatePlaybackSpeedPreference() {
ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED);
float speedValue = feedPreferences.getFeedPlaybackSpeed();
feedPlaybackSpeedPreference.setValue(SPEED_FORMAT.format(speedValue));
}
private void updateAutoDeleteSummary() {
ListPreference autoDeletePreference = findPreference("autoDelete");
switch (feedPreferences.getAutoDeleteAction()) {
case GLOBAL:
autoDeletePreference.setSummary(R.string.feed_auto_download_global);
autoDeletePreference.setValue("global");
break;
case YES:
autoDeletePreference.setSummary(R.string.feed_auto_download_always);
autoDeletePreference.setValue("always");
break;
case NO:
autoDeletePreference.setSummary(R.string.feed_auto_download_never);
autoDeletePreference.setValue("never");
break;
}
}
private void setupVolumeReductionPreferences() {
ListPreference volumeReductionPreference = findPreference("volumeReduction");
volumeReductionPreference.setOnPreferenceChangeListener((preference, newValue) -> {
switch ((String) newValue) {
case "off":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.OFF);
break;
case "light":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
break;
case "heavy":
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.HEAVY_REDUCTION);
break;
}
feed.savePreferences();
updateVolumeReductionValue();
EventBus.getDefault().post(
new VolumeAdaptionChangedEvent(feedPreferences.getVolumeAdaptionSetting(), feed.getId()));
return false;
});
}
private void updateVolumeReductionValue() {
ListPreference volumeReductionPreference = findPreference("volumeReduction");
switch (feedPreferences.getVolumeAdaptionSetting()) {
case OFF:
volumeReductionPreference.setValue("off");
break;
case LIGHT_REDUCTION:
volumeReductionPreference.setValue("light");
break;
case HEAVY_REDUCTION:
volumeReductionPreference.setValue("heavy");
break;
}
}
private void setupKeepUpdatedPreference() {
SwitchPreference pref = findPreference("keepUpdated");
pref.setChecked(feedPreferences.getKeepUpdated());
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean checked = newValue == Boolean.TRUE;
feedPreferences.setKeepUpdated(checked);
feed.savePreferences();
pref.setChecked(checked);
return false;
});
}
private void setupAutoDownloadGlobalPreference() {
if (!UserPreferences.isEnableAutodownload()) {
SwitchPreference autodl = findPreference("autoDownload");
autodl.setChecked(false);
autodl.setEnabled(false);
autodl.setSummary(R.string.auto_download_disabled_globally);
findPreference(PREF_EPISODE_FILTER).setEnabled(false);
}
}
private void setupAutoDownloadPreference() {
SwitchPreference pref = findPreference("autoDownload");
pref.setEnabled(UserPreferences.isEnableAutodownload());
if (UserPreferences.isEnableAutodownload()) {
pref.setChecked(feedPreferences.getAutoDownload());
} else {
pref.setChecked(false);
pref.setSummary(R.string.auto_download_disabled_globally);
}
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean checked = newValue == Boolean.TRUE;
feedPreferences.setAutoDownload(checked);
feed.savePreferences();
updateAutoDownloadEnabled();
ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(getActivity(), checked);
dialog.createNewDialog().show();
pref.setChecked(checked);
return false;
});
}
private void updateAutoDownloadEnabled() {
if (feed != null && feed.getPreferences() != null) {
boolean enabled = feed.getPreferences().getAutoDownload() && UserPreferences.isEnableAutodownload();
findPreference(PREF_EPISODE_FILTER).setEnabled(enabled);
}
}
private class ApplyToEpisodesDialog extends ConfirmationDialog {
private final boolean autoDownload;
ApplyToEpisodesDialog(Context context, boolean autoDownload) {
super(context, R.string.auto_download_apply_to_items_title,
R.string.auto_download_apply_to_items_message);
this.autoDownload = autoDownload;
setPositiveText(R.string.yes);
setNegativeText(R.string.no);
}
@Override
public void onConfirmButtonPressed(DialogInterface dialog) {
DBWriter.setFeedsItemsAutoDownload(feed, autoDownload);
}
} }
} }
} }

View File

@ -9,6 +9,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter;
@ -77,6 +79,9 @@ public class ItemPagerFragment extends Fragment {
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View layout = inflater.inflate(R.layout.feeditem_pager_fragment, container, false); View layout = inflater.inflate(R.layout.feeditem_pager_fragment, container, false);
Toolbar toolbar = layout.findViewById(R.id.toolbar);
toolbar.setTitle("");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
feedItems = getArguments().getLongArray(ARG_FEEDITEMS); feedItems = getArguments().getLongArray(ARG_FEEDITEMS);
int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS); int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS);
@ -145,15 +150,12 @@ public class ItemPagerFragment extends Fragment {
((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); ((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
} }
inflater.inflate(R.menu.feeditem_options, menu); inflater.inflate(R.menu.feeditem_options, menu);
if (item.hasMedia()) {
if (menu != null && item != null) { FeedItemMenuHandler.onPrepareMenu(menu, item);
if (item.hasMedia()) { } else {
FeedItemMenuHandler.onPrepareMenu(menu, item); // these are already available via button1 and button2
} else { FeedItemMenuHandler.onPrepareMenu(menu, item,
// these are already available via button1 and button2 R.id.mark_read_item, R.id.visit_website_item);
FeedItemMenuHandler.onPrepareMenu(menu, item,
R.id.mark_read_item, R.id.visit_website_item);
}
} }
} }

View File

@ -2,50 +2,50 @@ package de.danoeh.antennapod.fragment;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.ListFragment;
import androidx.core.view.MenuItemCompat;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.PlaybackHistoryEvent; import de.danoeh.antennapod.core.event.PlaybackHistoryEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent;
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.view.EmptyViewHandler;
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.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import java.util.List; import java.util.List;
import de.danoeh.antennapod.R; public class PlaybackHistoryFragment extends Fragment implements AdapterView.OnItemClickListener {
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
public class PlaybackHistoryFragment extends ListFragment {
public static final String TAG = "PlaybackHistoryFragment"; public static final String TAG = "PlaybackHistoryFragment";
private List<FeedItem> playbackHistory; private List<FeedItem> playbackHistory;
private FeedItemlistAdapter adapter; private FeedItemlistAdapter adapter;
private List<Downloader> downloaderList;
private Disposable disposable; private Disposable disposable;
private ListView listView;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -55,26 +55,26 @@ public class PlaybackHistoryFragment extends ListFragment {
} }
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
super.onViewCreated(view, savedInstanceState); @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.simple_list_fragment, container, false);
// add padding Toolbar toolbar = root.findViewById(R.id.toolbar);
final ListView lv = getListView(); toolbar.setTitle(R.string.playback_history_label);
lv.setClipToPadding(false); ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding);
lv.setPadding(0, vertPadding, 0, vertPadding);
listView = root.findViewById(android.R.id.list);
EmptyViewHandler emptyView = new EmptyViewHandler(getActivity()); EmptyViewHandler emptyView = new EmptyViewHandler(getActivity());
emptyView.setIcon(R.attr.ic_history); emptyView.setIcon(R.attr.ic_history);
emptyView.setTitle(R.string.no_history_head_label); emptyView.setTitle(R.string.no_history_head_label);
emptyView.setMessage(R.string.no_history_label); emptyView.setMessage(R.string.no_history_label);
emptyView.attachToListView(getListView()); emptyView.attachToListView(listView);
// played items shoudln't be transparent for this fragment since, *all* items // played items shoudln't be transparent for this fragment since, *all* items
// in this fragment will, by definition, be played. So it serves no purpose and can make // in this fragment will, by definition, be played. So it serves no purpose and can make
// it harder to read. // it harder to read.
adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, false); adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, false);
setListAdapter(adapter); listView.setAdapter(adapter);
return root;
} }
@Override @Override
@ -96,15 +96,12 @@ public class PlaybackHistoryFragment extends ListFragment {
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN) @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(DownloadEvent event) { public void onEvent(DownloadEvent event) {
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
DownloaderUpdate update = event.update;
downloaderList = update.downloaders;
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
super.onListItemClick(l, v, position, id); position -= listView.getHeaderViewsCount();
position -= l.getHeaderViewsCount();
long[] ids = FeedItemUtil.getIds(playbackHistory); long[] ids = FeedItemUtil.getIds(playbackHistory);
((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(ids, position)); ((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(ids, position));
} }
@ -149,12 +146,12 @@ public class PlaybackHistoryFragment extends ListFragment {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FeedItemEvent event) { public void onEventMainThread(FeedItemEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if(playbackHistory == null) { if (playbackHistory == null) {
return; return;
} }
for(FeedItem item : event.items) { for (FeedItem item : event.items) {
int pos = FeedItemUtil.indexOfItemWithId(playbackHistory, item.getId()); int pos = FeedItemUtil.indexOfItemWithId(playbackHistory, item.getId());
if(pos >= 0) { if (pos >= 0) {
loadItems(); loadItems();
return; return;
} }
@ -196,7 +193,7 @@ public class PlaybackHistoryFragment extends ListFragment {
}; };
private void loadItems() { private void loadItems() {
if(disposable != null) { if (disposable != null) {
disposable.dispose(); disposable.dispose();
} }
disposable = Observable.fromCallable(this::loadData) disposable = Observable.fromCallable(this::loadData)

View File

@ -16,6 +16,7 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.core.view.MenuItemCompat; import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -495,9 +496,8 @@ public class QueueFragment extends Fragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.queue_label);
View root = inflater.inflate(R.layout.queue_fragment, container, false); View root = inflater.inflate(R.layout.queue_fragment, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
infoBar = root.findViewById(R.id.info_bar); infoBar = root.findViewById(R.id.info_bar);
recyclerView = root.findViewById(R.id.recyclerView); recyclerView = root.findViewById(R.id.recyclerView);
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();

View File

@ -103,9 +103,8 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.search_label);
View layout = inflater.inflate(R.layout.search_fragment, container, false); View layout = inflater.inflate(R.layout.search_fragment, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(layout.findViewById(R.id.toolbar));
ListView listView = layout.findViewById(R.id.listview); ListView listView = layout.findViewById(R.id.listview);
progressBar = layout.findViewById(R.id.progressBar); progressBar = layout.findViewById(R.id.progressBar);
searchAdapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, true); searchAdapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, true, true);
@ -141,7 +140,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label); MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); item.setShowAsAction(MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
final SearchView sv = new SearchView(getActivity()); final SearchView sv = new SearchView(getActivity());
sv.setQueryHint(getString(R.string.search_label)); sv.setQueryHint(getString(R.string.search_label));
sv.setQuery(getArguments().getString(ARG_QUERY), false); sv.setQuery(getArguments().getString(ARG_QUERY), false);
@ -159,7 +158,8 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
return false; return false;
} }
}); });
MenuItemCompat.setActionView(item, sv); sv.setIconifiedByDefault(false);
item.setActionView(sv);
} }
@Subscribe @Subscribe

View File

@ -6,6 +6,7 @@ import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
@ -85,6 +86,7 @@ public class SubscriptionFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); View root = inflater.inflate(R.layout.fragment_subscriptions, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid); subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid);
subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, 3)); subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, 3));
registerForContextMenu(subscriptionGridLayout); registerForContextMenu(subscriptionGridLayout);
@ -160,10 +162,6 @@ public class SubscriptionFragment extends Fragment {
((MainActivity) getActivity()).loadChildFragment(new AddFeedFragment()); ((MainActivity) getActivity()).loadChildFragment(new AddFeedFragment());
} }
}); });
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.subscriptions_label);
}
} }
@Override @Override

View File

@ -49,6 +49,8 @@ public class StatisticsFragment extends Fragment {
tabLayout = rootView.findViewById(R.id.sliding_tabs); tabLayout = rootView.findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);
rootView.findViewById(R.id.toolbar).setVisibility(View.GONE);
return rootView; return rootView;
} }

View File

@ -1,182 +1,193 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical">
android:scrollbars="vertical">
<LinearLayout <androidx.appcompat.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:minHeight="?attr/actionBarSize"
android:focusableInTouchMode="true" android:theme="?attr/actionBarTheme"
android:padding="8dp"> app:title="@string/add_feed_label"
android:id="@+id/toolbar"/>
<androidx.cardview.widget.CardView <ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cardCornerRadius="4dp" android:orientation="vertical"
android:elevation="16dp" android:focusableInTouchMode="true"
android:layout_margin="8dp"> android:padding="8dp">
<LinearLayout <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> app:cardCornerRadius="4dp"
android:elevation="16dp"
android:layout_margin="8dp">
<ImageView <LinearLayout
android:layout_width="40dp" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/search_podcast_hint"
app:srcCompat="?attr/action_search"
android:id="@+id/search_icon"
android:scaleType="center"/>
<EditText
android:id="@+id/combinedFeedSearchBox"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:orientation="horizontal">
android:inputType="text"
android:imeOptions="actionSearch"
android:importantForAutofill="no"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:hint="@string/search_podcast_hint"
android:background="@null"/>
</LinearLayout> <ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/search_podcast_hint"
app:srcCompat="?attr/action_search"
android:id="@+id/search_icon"
android:scaleType="center"/>
</androidx.cardview.widget.CardView> <EditText
android:id="@+id/combinedFeedSearchBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="text"
android:imeOptions="actionSearch"
android:importantForAutofill="no"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:hint="@string/search_podcast_hint"
android:background="@null"/>
<fragment </LinearLayout>
android:id="@+id/quickFeedDiscovery"
android:name="de.danoeh.antennapod.fragment.QuickFeedDiscoveryFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"/>
<androidx.cardview.widget.CardView </androidx.cardview.widget.CardView>
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
android:elevation="8dp"
android:layout_margin="8dp">
<LinearLayout <fragment
android:id="@+id/quickFeedDiscovery"
android:name="de.danoeh.antennapod.fragment.QuickFeedDiscoveryFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp" android:layout_margin="8dp"/>
android:orientation="vertical">
<TextView <androidx.cardview.widget.CardView
android:id="@+id/txtvFeedurl" android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
android:elevation="8dp"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/txtvfeedurl_label" android:padding="16dp"
android:textSize="18sp" android:orientation="vertical">
android:layout_marginBottom="8dp"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:textColor="?android:attr/textColorPrimary"/>
<EditText <TextView
android:id="@+id/etxtFeedurl" android:id="@+id/txtvFeedurl"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:cursorVisible="true" android:text="@string/txtvfeedurl_label"
android:focusable="true" android:textSize="18sp"
android:focusableInTouchMode="true" android:layout_marginBottom="8dp"
android:hint="@string/etxtFeedurlHint" android:layout_marginLeft="4dp"
android:inputType="textUri"/> android:layout_marginStart="4dp"
android:textColor="?android:attr/textColorPrimary"/>
<Button <EditText
android:id="@+id/butConfirm" android:id="@+id/etxtFeedurl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cursorVisible="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/etxtFeedurlHint"
android:inputType="textUri"/>
<Button
android:id="@+id/butConfirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
style="?android:attr/buttonBarButtonStyle"
android:text="@string/confirm_label"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
android:elevation="8dp"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end"
style="?android:attr/buttonBarButtonStyle"
android:text="@string/confirm_label"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
android:elevation="8dp"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/advanced_search"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:padding="8dp" android:padding="8dp"
android:background="?android:attr/selectableItemBackground"> android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<ImageView <LinearLayout
android:layout_width="40dp" android:id="@+id/advanced_search"
android:layout_height="match_parent" android:layout_width="120dp"
android:contentDescription="@string/advanced_search"
app:srcCompat="?attr/action_search"
android:scaleType="center"
android:layout_marginBottom="4dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/advanced_search" android:orientation="vertical"
android:textAlignment="center" android:gravity="center_horizontal"
android:textColor="?android:attr/textColorPrimary"/> android:padding="8dp"
</LinearLayout> android:background="?android:attr/selectableItemBackground">
<LinearLayout <ImageView
android:id="@+id/btn_opml_import" android:layout_width="40dp"
android:layout_width="120dp" android:layout_height="match_parent"
android:layout_height="wrap_content" android:contentDescription="@string/advanced_search"
android:orientation="vertical" app:srcCompat="?attr/action_search"
android:gravity="center_horizontal" android:scaleType="center"
android:padding="8dp" android:layout_marginBottom="4dp"/>
android:background="?android:attr/selectableItemBackground">
<ImageView <TextView
android:layout_width="40dp" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:contentDescription="@string/opml_import_label" android:text="@string/advanced_search"
app:srcCompat="?attr/av_download" android:textAlignment="center"
android:scaleType="center" android:textColor="?android:attr/textColorPrimary"/>
android:layout_marginBottom="4dp"/> </LinearLayout>
<TextView <LinearLayout
android:layout_width="match_parent" android:id="@+id/btn_opml_import"
android:layout_width="120dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/opml_import_label" android:orientation="vertical"
android:textAlignment="center" android:gravity="center_horizontal"
android:textColor="?android:attr/textColorPrimary"/> android:padding="8dp"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:contentDescription="@string/opml_import_label"
app:srcCompat="?attr/av_download"
android:scaleType="center"
android:layout_marginBottom="4dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/opml_import_label"
android:textAlignment="center"
android:textColor="?android:attr/textColorPrimary"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>
</ScrollView>
</androidx.cardview.widget.CardView> </LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -4,17 +4,27 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
app:navigationIcon="?homeAsUpIndicator"
android:id="@+id/toolbar"/>
<ListView <ListView
android:id="@android:id/list" android:id="@android:id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_below="@id/toolbar"
android:layout_marginTop="0dp" /> android:layout_marginTop="0dp" />
<com.leinardi.android.speeddial.SpeedDialOverlayLayout <com.leinardi.android.speeddial.SpeedDialOverlayLayout
android:id="@+id/fabSDOverlay" android:id="@+id/fabSDOverlay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:layout_below="@id/toolbar" />
<!-- The FAB SpeedDial <!-- The FAB SpeedDial
1. MUST be placed at the bottom of the layout xml to ensure it is at the front, 1. MUST be placed at the bottom of the layout xml to ensure it is at the front,
clickable on Pre-Lollipop devices (that do not support elevation). clickable on Pre-Lollipop devices (that do not support elevation).

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
android:id="@+id/toolbar"/>
<ListView android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:id="@android:id/list"/>
<ProgressBar
android:id="@+id/progLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateOnly="true"
android:visibility="gone"/>
</RelativeLayout>

View File

@ -1,132 +1,143 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent" android:layout_width="match_parent" android:layout_height="match_parent">
android:orientation="vertical">
<include layout="@layout/feeditemlist_header" /> <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/scrollView" android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
android:layout_weight="1" app:contentScrim="?attr/colorPrimary"
android:scrollbarStyle="outsideOverlay" app:layout_scrollFlags="scroll|exitUntilCollapsed">
android:paddingLeft="16dp"
android:paddingRight="16dp" <ImageView
android:paddingBottom="8dp" android:id="@+id/imgvBackground"
android:clipToPadding="false"> style="@style/BigBlurryBackground"
android:layout_width="match_parent"
android:layout_height="256dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6"/>
<include layout="@layout/feeditemlist_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6"/>
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:navigationIcon="?homeAsUpIndicator"
android:layout_alignParentTop="true"
android:id="@+id/toolbar"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="8dp"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.gridlayout.widget.GridLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:orientation="vertical">
app:columnCount="2"
app:rowCount="3">
<TextView <TextView
style="@style/AntennaPod.TextView.Heading"
android:id="@+id/lblAuthor" android:id="@+id/lblAuthor"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_row="0"
app:layout_column="0"
android:lines="1"
android:text="@string/author_label" android:text="@string/author_label"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light"/> tools:background="@android:color/holo_red_light"/>
<TextView <TextView
android:id="@+id/txtvDetailsAuthor" android:id="@+id/txtvDetailsAuthor"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textIsSelectable="true" android:textIsSelectable="true"
app:layout_row="0"
app:layout_column="1"
tools:text="Daniel Oeh" tools:text="Daniel Oeh"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"/>
<TextView <TextView
style="@style/AntennaPod.TextView.Heading"
android:id="@+id/lblLanguage" android:id="@+id/lblLanguage"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
app:layout_row="1"
app:layout_column="0"
android:lines="1"
android:text="@string/language_label" android:text="@string/language_label"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light"/> tools:background="@android:color/holo_red_light"/>
<TextView <TextView
android:id="@+id/txtvLanguage" android:id="@+id/txtvLanguage"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textIsSelectable="true" android:textIsSelectable="true"
app:layout_row="1"
app:layout_column="1"
tools:text="English" tools:text="English"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"/>
<TextView <TextView
style="@style/AntennaPod.TextView.Heading"
android:id="@+id/lblUrl" android:id="@+id/lblUrl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginBottom="4dp"
app:layout_row="2"
app:layout_column="0"
android:lines="1"
android:text="@string/url_label" android:text="@string/url_label"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light"/> tools:background="@android:color/holo_red_light"/>
<TextView <TextView
android:id="@+id/txtvUrl" android:id="@+id/txtvUrl"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="4dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
app:layout_row="2"
app:layout_column="1"
app:layout_gravity="fill"
android:maxLines="4" android:maxLines="4"
android:paddingTop="4dp"
android:paddingBottom="4dp"
tools:text="http://www.example.com/feed" tools:text="http://www.example.com/feed"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"/>
</androidx.gridlayout.widget.GridLayout> <TextView
style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:text="@string/description_label"/>
<TextView <TextView
style="@style/AntennaPod.TextView.Heading" android:id="@+id/txtvDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:textIsSelectable="true"
android:text="@string/description_label"/> android:text="@string/design_time_lorem_ipsum"
tools:background="@android:color/holo_green_dark"/>
<TextView
android:id="@+id/txtvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textIsSelectable="true"
android:text="@string/design_time_lorem_ipsum"
tools:background="@android:color/holo_green_dark"/>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView>
</ScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View File

@ -18,7 +18,6 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="match_parent" /> android:layout_width="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:navigationIcon="?homeAsUpIndicator"
android:id="@+id/toolbar"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/feeditemlist_header" /> <androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:title="@string/feed_settings_label"
app:navigationIcon="?homeAsUpIndicator"
android:elevation="4dp"
android:id="@+id/toolbar"/>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,10 +1,21 @@
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
app:navigationIcon="?homeAsUpIndicator"
app:title="@string/discover"
android:id="@+id/toolbar"/>
<GridView <GridView
android:layout_below="@id/toolbar"
android:id="@+id/gridView" android:id="@+id/gridView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@ -1,28 +1,39 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:orientation="vertical"
android:layout_height="match_parent"> android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
app:title="@string/subscriptions_label"
android:id="@+id/toolbar"/>
<GridView
android:layout_below="@id/toolbar"
android:id="@+id/subscriptions_grid"
android:layout_width="match_parent"
android:numColumns="3"
android:horizontalSpacing="2dp"
android:verticalSpacing="2dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:paddingBottom="88dp"
android:clipToPadding="false"/>
<GridView
android:id="@+id/subscriptions_grid"
android:layout_width="match_parent"
android:numColumns="3"
android:horizontalSpacing="2dp"
android:verticalSpacing="2dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:paddingBottom="88dp"
android:clipToPadding="false">
</GridView>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/subscriptions_add" android:id="@+id/subscriptions_add"
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_margin="16dp" android:layout_margin="16dp"
android:layout_gravity="bottom|end" android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:contentDescription="@string/add_feed_label" android:contentDescription="@string/add_feed_label"
android:src="@drawable/ic_add_white_24dp" android:src="@drawable/ic_add_white_24dp"/>
/> </RelativeLayout>
</FrameLayout>

View File

@ -19,28 +19,12 @@
tools:layout_height="64dp" tools:layout_height="64dp"
tools:background="@android:color/holo_green_light" /> tools:background="@android:color/holo_green_light" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
tools:background="@android:color/holo_blue_dark" />
<View
android:id="@+id/shadow"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_below="@id/toolbar"
android:background="@drawable/shadow" />
<FrameLayout <FrameLayout
android:id="@+id/main_view" android:id="@+id/main_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0px" android:layout_height="0px"
android:layout_above="@id/playerFragment" android:layout_above="@id/playerFragment"
android:layout_below="@id/toolbar" android:layout_alignParentTop="true"
android:foreground="?android:windowContentOverlay" android:foreground="?android:windowContentOverlay"
tools:background="@android:color/holo_red_dark" /> tools:background="@android:color/holo_red_dark" />

View File

@ -1,22 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.appcompat.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="match_parent" android:minHeight="?attr/actionBarSize"
android:orientation="vertical"> android:theme="?attr/actionBarTheme"
android:id="@+id/toolbar"/>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/sliding_tabs" android:id="@+id/sliding_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabGravity="fill" app:tabMode="fixed"
app:tabMode="fixed" /> app:tabGravity="fill"/>
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager" android:id="@+id/viewpager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0px" android:layout_height="wrap_content"/>
android:layout_weight="1" />
</LinearLayout> </LinearLayout>

View File

@ -1,17 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
app:title="@string/queue_label"
android:id="@+id/toolbar"/>
<TextView <TextView
android:layout_below="@id/toolbar"
android:id="@+id/info_bar" android:id="@+id/info_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:textSize="12sp" android:textSize="12sp"
android:text=""/> android:layout_marginTop="-8dp"
android:layout_marginLeft="72dp"
android:layout_marginStart="72dp"
android:layout_marginBottom="4dp"
tools:text="12 Episodes - Time remaining: 12 hours"/>
<View <View
android:id="@+id/divider" android:id="@+id/divider"

View File

@ -1,17 +1,30 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout
android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"> xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:navigationIcon="?homeAsUpIndicator"
app:title="@string/search_label"
android:id="@+id/toolbar"/>
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:layout_centerInParent="true"
style="?android:attr/progressBarStyle" android:id="@+id/progressBar"
android:layout_width="wrap_content" style="?android:attr/progressBarStyle"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_gravity="center" /> android:layout_height="wrap_content"
android:layout_gravity="center"/>
<ListView <ListView
android:id="@+id/listview" android:layout_below="@id/toolbar"
android:layout_width="match_parent" android:id="@+id/listview"
android:layout_height="match_parent" /> android:layout_width="match_parent"
</FrameLayout> android:layout_height="match_parent"/>
</RelativeLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
android:id="@+id/toolbar"/>
<ListView android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:id="@android:id/list"
android:clipToPadding="false"/>
<ProgressBar
android:id="@+id/progLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateOnly="true"
android:visibility="gone"/>
</RelativeLayout>

View File

@ -1,14 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu <menu xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/episode_actions" android:id="@+id/episode_actions"
android:menuCategory="container" android:menuCategory="container"
android:title="@string/multi_select" android:title="@string/multi_select"
android:icon="?attr/checkbox_multiple" android:icon="?attr/checkbox_multiple"
custom:showAsAction="always"> android:showAsAction="ifRoom" />
</item>
</menu> </menu>

View File

@ -13,7 +13,7 @@ public class MenuItemUtils {
/** /**
* Changes the appearance of a MenuItem depending on whether the given UpdateRefreshMenuItemChecker * Changes the appearance of a MenuItem depending on whether the given UpdateRefreshMenuItemChecker
* is refreshing or not. If it returns true, the menu item will be replaced by an indeterminate progress * is refreshing or not. If it returns true, the menu item will be replaced by an indeterminate progress
* bar, otherwise nothing will happen. * bar, otherwise the progress bar will be hidden.
* *
* @param menu The menu that the MenuItem belongs to * @param menu The menu that the MenuItem belongs to
* @param resId The id of the MenuItem * @param resId The id of the MenuItem
@ -22,11 +22,12 @@ public class MenuItemUtils {
*/ */
public static boolean updateRefreshMenuItem(Menu menu, int resId, UpdateRefreshMenuItemChecker checker) { public static boolean updateRefreshMenuItem(Menu menu, int resId, UpdateRefreshMenuItemChecker checker) {
// expand actionview if feeds are being downloaded, collapse otherwise // expand actionview if feeds are being downloaded, collapse otherwise
MenuItem refreshItem = menu.findItem(resId);
if (checker.isRefreshing()) { if (checker.isRefreshing()) {
MenuItem refreshItem = menu.findItem(resId);
refreshItem.setActionView(R.layout.refresh_action_view); refreshItem.setActionView(R.layout.refresh_action_view);
return true; return true;
} else { } else {
refreshItem.setActionView(null);
return false; return false;
} }
} }

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" <ProgressBar
android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_width="48dp"
android:layout_gravity="end" android:layout_height="48dp"
android:indeterminateOnly="true"> android:layout_gravity="end"
android:padding="8dp"
</ProgressBar> android:indeterminateOnly="true"/>