Bottom navigation (#7176)
This commit is contained in:
parent
60f6e175a8
commit
6cbc58ba78
|
@ -52,6 +52,7 @@ public class NavigationDrawerTest {
|
|||
|
||||
EspressoTestUtils.clearPreferences();
|
||||
EspressoTestUtils.clearDatabase();
|
||||
UserPreferences.setBottomNavigationEnabled(false);
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -10,14 +10,19 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RelativeLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.view.menu.MenuBuilder;
|
||||
import androidx.appcompat.widget.ListPopupWindow;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
|
@ -32,48 +37,62 @@ import androidx.work.WorkInfo;
|
|||
import androidx.work.WorkManager;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.navigation.NavigationBarView;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.net.download.service.feed.FeedUpdateManagerImpl;
|
||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.net.sync.serviceinterface.SynchronizationQueueSink;
|
||||
import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter;
|
||||
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
|
||||
import de.danoeh.antennapod.ui.screen.rating.RatingDialogManager;
|
||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
|
||||
import de.danoeh.antennapod.event.MessageEvent;
|
||||
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
||||
import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
|
||||
import de.danoeh.antennapod.ui.screen.playback.audio.AudioPlayerFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.DownloadLogFragment;
|
||||
import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
|
||||
import de.danoeh.antennapod.ui.screen.InboxFragment;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
|
||||
import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
|
||||
import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
|
||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||
import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
|
||||
import de.danoeh.antennapod.ui.TransitionEffect;
|
||||
import de.danoeh.antennapod.model.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.net.download.service.feed.FeedUpdateManagerImpl;
|
||||
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
|
||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.net.sync.serviceinterface.SynchronizationQueueSink;
|
||||
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.importexport.AutomaticDatabaseExportWorker;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.TransitionEffect;
|
||||
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
|
||||
import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter;
|
||||
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
|
||||
import de.danoeh.antennapod.ui.common.ThemeUtils;
|
||||
import de.danoeh.antennapod.ui.discovery.DiscoveryFragment;
|
||||
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
||||
import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
|
||||
import de.danoeh.antennapod.ui.screen.InboxFragment;
|
||||
import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
|
||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.DownloadLogFragment;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.BottomNavigationMoreAdapter;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.DrawerPreferencesDialog;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.NavListAdapter;
|
||||
import de.danoeh.antennapod.ui.screen.drawer.NavigationNames;
|
||||
import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
|
||||
import de.danoeh.antennapod.ui.screen.home.HomeFragment;
|
||||
import de.danoeh.antennapod.ui.screen.playback.audio.AudioPlayerFragment;
|
||||
import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
|
||||
import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
|
||||
import de.danoeh.antennapod.ui.screen.rating.RatingDialogManager;
|
||||
import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
|
||||
import de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -94,11 +113,12 @@ public class MainActivity extends CastEnabledActivity {
|
|||
|
||||
private @Nullable DrawerLayout drawerLayout;
|
||||
private @Nullable ActionBarDrawerToggle drawerToggle;
|
||||
private BottomNavigationView bottomNavigationView;
|
||||
private View navDrawer;
|
||||
private LockableBottomSheetBehavior sheetBehavior;
|
||||
private RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
|
||||
private int lastTheme = 0;
|
||||
private Insets navigationBarInsets = Insets.NONE;
|
||||
private Insets systemBarInsets = Insets.NONE;
|
||||
|
||||
@NonNull
|
||||
public static Intent getIntentToOpenFeed(@NonNull Context context, long feedId) {
|
||||
|
@ -122,11 +142,24 @@ public class MainActivity extends CastEnabledActivity {
|
|||
|
||||
drawerLayout = findViewById(R.id.drawer_layout);
|
||||
navDrawer = findViewById(R.id.navDrawerFragment);
|
||||
setNavDrawerSize();
|
||||
bottomNavigationView = findViewById(R.id.bottomNavigationView);
|
||||
if (UserPreferences.isBottomNavigationEnabled()) {
|
||||
buildBottomNavigationMenu();
|
||||
if (drawerLayout == null) { // Tablet mode
|
||||
navDrawer.setVisibility(View.GONE);
|
||||
} else {
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
|
||||
}
|
||||
drawerLayout = null;
|
||||
} else {
|
||||
bottomNavigationView.setVisibility(View.GONE);
|
||||
bottomNavigationView = null;
|
||||
setNavDrawerSize();
|
||||
}
|
||||
|
||||
// Consume navigation bar insets - we apply them in setPlayerVisible()
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main_view), (v, insets) -> {
|
||||
navigationBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
|
||||
systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
updateInsets();
|
||||
return new WindowInsetsCompat.Builder(insets)
|
||||
.setInsets(WindowInsetsCompat.Type.navigationBars(), Insets.NONE)
|
||||
|
@ -320,28 +353,35 @@ public class MainActivity extends CastEnabledActivity {
|
|||
|
||||
private void updateInsets() {
|
||||
setPlayerVisible(findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE);
|
||||
int playerHeight = (int) getResources().getDimension(R.dimen.external_player_height);
|
||||
sheetBehavior.setPeekHeight(playerHeight + navigationBarInsets.bottom);
|
||||
}
|
||||
|
||||
public void setPlayerVisible(boolean visible) {
|
||||
getBottomSheet().setLocked(!visible);
|
||||
findViewById(R.id.audioplayerFragment).setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
if (visible) {
|
||||
bottomSheetCallback.onStateChanged(null, getBottomSheet().getState()); // Update toolbar visibility
|
||||
} else {
|
||||
getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
}
|
||||
FragmentContainerView mainView = findViewById(R.id.main_view);
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mainView.getLayoutParams();
|
||||
View bottomPaddingView = findViewById(R.id.bottom_padding);
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) bottomPaddingView.getLayoutParams();
|
||||
params.height = systemBarInsets.bottom;
|
||||
bottomPaddingView.setLayoutParams(params);
|
||||
|
||||
int externalPlayerHeight = (int) getResources().getDimension(R.dimen.external_player_height);
|
||||
params.setMargins(navigationBarInsets.left, 0, navigationBarInsets.right,
|
||||
navigationBarInsets.bottom + (visible ? externalPlayerHeight : 0));
|
||||
FragmentContainerView mainView = findViewById(R.id.main_content_view);
|
||||
params = (ViewGroup.MarginLayoutParams) mainView.getLayoutParams();
|
||||
params.setMargins(systemBarInsets.left, 0, systemBarInsets.right, (visible ? externalPlayerHeight : 0));
|
||||
mainView.setLayoutParams(params);
|
||||
sheetBehavior.setPeekHeight(externalPlayerHeight);
|
||||
sheetBehavior.setGestureInsetBottomIgnored(true);
|
||||
|
||||
FragmentContainerView playerView = findViewById(R.id.playerFragment);
|
||||
ViewGroup.MarginLayoutParams playerParams = (ViewGroup.MarginLayoutParams) playerView.getLayoutParams();
|
||||
playerParams.setMargins(navigationBarInsets.left, 0, navigationBarInsets.right, 0);
|
||||
playerParams.setMargins(systemBarInsets.left, 0, systemBarInsets.right, 0);
|
||||
playerView.setLayoutParams(playerParams);
|
||||
findViewById(R.id.audioplayerFragment).setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
RelativeLayout playerContent = findViewById(R.id.playerContent);
|
||||
playerContent.setPadding(systemBarInsets.left, systemBarInsets.top, systemBarInsets.right, 0);
|
||||
}
|
||||
|
||||
public RecyclerView.RecycledViewPool getRecycledViewPool() {
|
||||
|
@ -393,6 +433,15 @@ public class MainActivity extends CastEnabledActivity {
|
|||
|
||||
public void loadFragment(String tag, Bundle args) {
|
||||
NavDrawerFragment.saveLastNavFragment(this, tag);
|
||||
if (bottomNavigationView != null) {
|
||||
int bottomSelectedItem = NavigationNames.getBottomNavigationItemId(tag);
|
||||
if (bottomNavigationView.getMenu().findItem(bottomSelectedItem) == null) {
|
||||
bottomSelectedItem = R.id.bottom_navigation_more;
|
||||
}
|
||||
bottomNavigationView.setOnItemSelectedListener(null);
|
||||
bottomNavigationView.setSelectedItemId(bottomSelectedItem);
|
||||
bottomNavigationView.setOnItemSelectedListener(bottomItemSelectedListener);
|
||||
}
|
||||
loadFragment(createFragmentInstance(tag, args));
|
||||
}
|
||||
|
||||
|
@ -412,7 +461,7 @@ public class MainActivity extends CastEnabledActivity {
|
|||
fragmentManager.popBackStack();
|
||||
}
|
||||
FragmentTransaction t = fragmentManager.beginTransaction();
|
||||
t.replace(R.id.main_view, fragment, MAIN_FRAGMENT_TAG);
|
||||
t.replace(R.id.main_content_view, fragment, MAIN_FRAGMENT_TAG);
|
||||
fragmentManager.popBackStack();
|
||||
// TODO: we have to allow state loss here
|
||||
// since this function can get called from an AsyncTask which
|
||||
|
@ -443,7 +492,7 @@ public class MainActivity extends CastEnabledActivity {
|
|||
|
||||
transaction
|
||||
.hide(getSupportFragmentManager().findFragmentByTag(MAIN_FRAGMENT_TAG))
|
||||
.add(R.id.main_view, fragment, MAIN_FRAGMENT_TAG)
|
||||
.add(R.id.main_content_view, fragment, MAIN_FRAGMENT_TAG)
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
}
|
||||
|
@ -452,6 +501,85 @@ public class MainActivity extends CastEnabledActivity {
|
|||
loadChildFragment(fragment, TransitionEffect.NONE);
|
||||
}
|
||||
|
||||
private void buildBottomNavigationMenu() {
|
||||
List<String> drawerItems = UserPreferences.getVisibleDrawerItemOrder();
|
||||
drawerItems.remove(NavListAdapter.SUBSCRIPTION_LIST_TAG);
|
||||
|
||||
Menu menu = bottomNavigationView.getMenu();
|
||||
menu.clear();
|
||||
for (int i = 0; i < drawerItems.size() && i < bottomNavigationView.getMaxItemCount() - 1; i++) {
|
||||
String tag = drawerItems.get(i);
|
||||
MenuItem item = menu.add(0, NavigationNames.getBottomNavigationItemId(tag),
|
||||
0, getString(NavigationNames.getLabel(tag)));
|
||||
item.setIcon(NavigationNames.getDrawable(tag));
|
||||
}
|
||||
MenuItem moreItem = menu.add(0, R.id.bottom_navigation_more, 0, getString(R.string.searchpreference_more));
|
||||
moreItem.setIcon(R.drawable.dots_vertical);
|
||||
bottomNavigationView.setOnItemSelectedListener(bottomItemSelectedListener);
|
||||
|
||||
if (bottomNavigationView.getMenu().findItem(R.id.bottom_navigation_inbox) != null) {
|
||||
Observable.fromCallable(() -> DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.NEW)))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result ->
|
||||
bottomNavigationView.getOrCreateBadge(R.id.bottom_navigation_inbox).setNumber(result),
|
||||
error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
}
|
||||
|
||||
private final NavigationBarView.OnItemSelectedListener bottomItemSelectedListener = item -> {
|
||||
sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
if (item.getItemId() == R.id.bottom_navigation_more) {
|
||||
showBottomNavigationMorePopup();
|
||||
return false;
|
||||
} else {
|
||||
loadFragment(NavigationNames.getBottomNavigationFragmentTag(item.getItemId()), null);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private void showBottomNavigationMorePopup() {
|
||||
List<String> drawerItems = UserPreferences.getVisibleDrawerItemOrder();
|
||||
drawerItems.remove(NavListAdapter.SUBSCRIPTION_LIST_TAG);
|
||||
|
||||
final List<MenuItem> popupMenuItems = new ArrayList<>();
|
||||
for (int i = bottomNavigationView.getMaxItemCount() - 1; i < drawerItems.size(); i++) {
|
||||
String tag = drawerItems.get(i);
|
||||
MenuItem item = new MenuBuilder(this).add(0, NavigationNames.getBottomNavigationItemId(tag),
|
||||
0, getString(NavigationNames.getLabel(tag)));
|
||||
item.setIcon(NavigationNames.getDrawable(tag));
|
||||
popupMenuItems.add(item);
|
||||
}
|
||||
MenuItem customizeItem = new MenuBuilder(this).add(0, R.id.bottom_navigation_settings,
|
||||
0, getString(R.string.pref_nav_drawer_items_title));
|
||||
customizeItem.setIcon(R.drawable.ic_pencil);
|
||||
popupMenuItems.add(customizeItem);
|
||||
|
||||
MenuItem settingsItem = new MenuBuilder(this).add(0, R.id.bottom_navigation_settings,
|
||||
0, getString(R.string.settings_label));
|
||||
settingsItem.setIcon(R.drawable.ic_settings);
|
||||
popupMenuItems.add(settingsItem);
|
||||
|
||||
final ListPopupWindow listPopupWindow = new ListPopupWindow(this);
|
||||
listPopupWindow.setWidth((int) (250 * getResources().getDisplayMetrics().density));
|
||||
listPopupWindow.setAnchorView(bottomNavigationView);
|
||||
listPopupWindow.setAdapter(new BottomNavigationMoreAdapter(this, popupMenuItems));
|
||||
listPopupWindow.setOnItemClickListener((parent, view, position, id) -> {
|
||||
if (position == popupMenuItems.size() - 1) {
|
||||
startActivity(new Intent(this, PreferenceActivity.class));
|
||||
} else if (position == popupMenuItems.size() - 2) {
|
||||
new DrawerPreferencesDialog(this, this::buildBottomNavigationMenu).show();
|
||||
} else {
|
||||
loadFragment(NavigationNames.getBottomNavigationFragmentTag(
|
||||
popupMenuItems.get(position).getItemId()), null);
|
||||
}
|
||||
listPopupWindow.dismiss();
|
||||
});
|
||||
listPopupWindow.setDropDownGravity(Gravity.END | Gravity.BOTTOM);
|
||||
listPopupWindow.setModal(true);
|
||||
listPopupWindow.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
|
@ -507,7 +635,9 @@ public class MainActivity extends CastEnabledActivity {
|
|||
super.onResume();
|
||||
handleNavIntent();
|
||||
|
||||
if (lastTheme != ThemeSwitcher.getNoTitleTheme(this)) {
|
||||
boolean hasBottomNavigation = bottomNavigationView != null;
|
||||
if (lastTheme != ThemeSwitcher.getNoTitleTheme(this)
|
||||
|| hasBottomNavigation != UserPreferences.isBottomNavigationEnabled()) {
|
||||
finish();
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
}
|
||||
|
@ -566,7 +696,7 @@ public class MainActivity extends CastEnabledActivity {
|
|||
String toPage = UserPreferences.getDefaultPage();
|
||||
if (NavDrawerFragment.getLastNavFragment(this).equals(toPage)
|
||||
|| UserPreferences.DEFAULT_PAGE_REMEMBER.equals(toPage)) {
|
||||
if (UserPreferences.backButtonOpensDrawer() && drawerLayout != null) {
|
||||
if (UserPreferences.backButtonOpensDrawer() && drawerLayout != null && bottomNavigationView == null) {
|
||||
drawerLayout.openDrawer(navDrawer);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
|
@ -644,7 +774,7 @@ public class MainActivity extends CastEnabledActivity {
|
|||
public Snackbar showSnackbarAbovePlayer(CharSequence text, int duration) {
|
||||
Snackbar s;
|
||||
if (getBottomSheet().getState() == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
s = Snackbar.make(findViewById(R.id.main_view), text, duration);
|
||||
s = Snackbar.make(findViewById(R.id.main_content_view), text, duration);
|
||||
if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
|
||||
s.setAnchorView(findViewById(R.id.audioplayerFragment));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.elevation.SurfaceColors;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.ui.CoverLoader;
|
||||
|
@ -56,8 +55,7 @@ public class HorizontalItemViewHolder extends RecyclerView.ViewHolder {
|
|||
this.item = item;
|
||||
|
||||
card.setAlpha(1.0f);
|
||||
float density = activity.getResources().getDisplayMetrics().density;
|
||||
card.setCardBackgroundColor(SurfaceColors.getColorForElevation(activity, 1 * density));
|
||||
card.setCardBackgroundColor(ThemeUtils.getColorFromAttr(activity, R.attr.colorSurfaceContainer));
|
||||
new CoverLoader()
|
||||
.withUri(ImageResourceUtils.getEpisodeListImageLocation(item))
|
||||
.withFallbackUri(item.getFeed().getImageUrl())
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package de.danoeh.antennapod.ui.screen.drawer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import de.danoeh.antennapod.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BottomNavigationMoreAdapter extends ArrayAdapter<MenuItem> {
|
||||
private final Context context;
|
||||
private final List<MenuItem> listItems;
|
||||
|
||||
public BottomNavigationMoreAdapter(Context context, List<MenuItem> listItems) {
|
||||
super(context, R.layout.bottom_navigation_more_listitem, listItems);
|
||||
this.context = context;
|
||||
this.listItems = listItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
if (view == null) {
|
||||
view = View.inflate(context, R.layout.bottom_navigation_more_listitem, null);
|
||||
}
|
||||
|
||||
MenuItem item = listItems.get(position);
|
||||
((ImageView) view.findViewById(R.id.coverImage)).setImageDrawable(item.getIcon());
|
||||
((TextView) view.findViewById(R.id.titleLabel)).setText(item.getTitle());
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ public class DrawerPreferencesDialog extends ReorderDialog {
|
|||
final List<String> drawerItemOrder = UserPreferences.getVisibleDrawerItemOrder();
|
||||
for (String tag : drawerItemOrder) {
|
||||
settingsDialogItems.add(new ReorderDialogItem(ReorderDialogItem.ViewType.Section,
|
||||
tag, context.getString(NavListAdapter.getLabel(tag))));
|
||||
tag, context.getString(NavigationNames.getLabel(tag))));
|
||||
}
|
||||
|
||||
settingsDialogItems.add(new ReorderDialogItem(ReorderDialogItem.ViewType.Header,
|
||||
|
@ -44,7 +44,7 @@ public class DrawerPreferencesDialog extends ReorderDialog {
|
|||
final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
|
||||
for (String sectionTag : hiddenDrawerItems) {
|
||||
settingsDialogItems.add(new ReorderDialogItem(ReorderDialogItem.ViewType.Section,
|
||||
sectionTag, context.getString(NavListAdapter.getLabel(sectionTag))));
|
||||
sectionTag, context.getString(NavigationNames.getLabel(sectionTag))));
|
||||
}
|
||||
return settingsDialogItems;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
@ -29,12 +28,8 @@ import de.danoeh.antennapod.model.feed.Feed;
|
|||
import de.danoeh.antennapod.storage.database.NavDrawerData;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.common.ImagePlaceholder;
|
||||
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
||||
import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
|
||||
import de.danoeh.antennapod.ui.screen.InboxFragment;
|
||||
import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.ui.screen.home.HomeFragment;
|
||||
import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
|
||||
import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
|
||||
import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
|
||||
|
@ -100,54 +95,6 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public static @StringRes int getLabel(String tag) {
|
||||
switch (tag) {
|
||||
case HomeFragment.TAG:
|
||||
return R.string.home_label;
|
||||
case QueueFragment.TAG:
|
||||
return R.string.queue_label;
|
||||
case InboxFragment.TAG:
|
||||
return R.string.inbox_label;
|
||||
case AllEpisodesFragment.TAG:
|
||||
return R.string.episodes_label;
|
||||
case SubscriptionFragment.TAG:
|
||||
return R.string.subscriptions_label;
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.string.downloads_label;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.string.playback_history_label;
|
||||
case AddFeedFragment.TAG:
|
||||
return R.string.add_feed_label;
|
||||
case NavListAdapter.SUBSCRIPTION_LIST_TAG:
|
||||
return R.string.subscriptions_list_label;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static @DrawableRes int getDrawable(String tag) {
|
||||
switch (tag) {
|
||||
case HomeFragment.TAG:
|
||||
return R.drawable.ic_home;
|
||||
case QueueFragment.TAG:
|
||||
return R.drawable.ic_playlist_play;
|
||||
case InboxFragment.TAG:
|
||||
return R.drawable.ic_inbox;
|
||||
case AllEpisodesFragment.TAG:
|
||||
return R.drawable.ic_feed;
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.drawable.ic_download;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.drawable.ic_history;
|
||||
case SubscriptionFragment.TAG:
|
||||
return R.drawable.ic_subscriptions;
|
||||
case AddFeedFragment.TAG:
|
||||
return R.drawable.ic_add;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getFragmentTags() {
|
||||
return Collections.unmodifiableList(fragmentTags);
|
||||
}
|
||||
|
@ -207,7 +154,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
|||
|
||||
holder.itemView.setOnCreateContextMenuListener(null);
|
||||
if (viewType == VIEW_TYPE_NAV) {
|
||||
bindNavView(getLabel(fragmentTags.get(position)), position, (NavHolder) holder);
|
||||
bindNavView(NavigationNames.getLabel(fragmentTags.get(position)), position, (NavHolder) holder);
|
||||
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
|
||||
bindSectionDivider((DividerHolder) holder);
|
||||
} else {
|
||||
|
@ -292,7 +239,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
|||
}
|
||||
}
|
||||
|
||||
holder.image.setImageResource(getDrawable(fragmentTags.get(position)));
|
||||
holder.image.setImageResource(NavigationNames.getDrawable(fragmentTags.get(position)));
|
||||
}
|
||||
|
||||
private void bindSectionDivider(DividerHolder holder) {
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package de.danoeh.antennapod.ui.screen.drawer;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
||||
import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
|
||||
import de.danoeh.antennapod.ui.screen.InboxFragment;
|
||||
import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
|
||||
import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.ui.screen.home.HomeFragment;
|
||||
import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
|
||||
import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
|
||||
|
||||
public abstract class NavigationNames {
|
||||
public static @DrawableRes int getDrawable(String tag) {
|
||||
switch (tag) {
|
||||
case HomeFragment.TAG:
|
||||
return R.drawable.ic_home;
|
||||
case QueueFragment.TAG:
|
||||
return R.drawable.ic_playlist_play;
|
||||
case InboxFragment.TAG:
|
||||
return R.drawable.ic_inbox;
|
||||
case AllEpisodesFragment.TAG:
|
||||
return R.drawable.ic_feed;
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.drawable.ic_download;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.drawable.ic_history;
|
||||
case SubscriptionFragment.TAG:
|
||||
return R.drawable.ic_subscriptions;
|
||||
case AddFeedFragment.TAG:
|
||||
return R.drawable.ic_add;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static @StringRes int getLabel(String tag) {
|
||||
switch (tag) {
|
||||
case HomeFragment.TAG:
|
||||
return R.string.home_label;
|
||||
case QueueFragment.TAG:
|
||||
return R.string.queue_label;
|
||||
case InboxFragment.TAG:
|
||||
return R.string.inbox_label;
|
||||
case AllEpisodesFragment.TAG:
|
||||
return R.string.episodes_label;
|
||||
case SubscriptionFragment.TAG:
|
||||
return R.string.subscriptions_label;
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.string.downloads_label;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.string.playback_history_label;
|
||||
case AddFeedFragment.TAG:
|
||||
return R.string.add_feed_label;
|
||||
case NavListAdapter.SUBSCRIPTION_LIST_TAG:
|
||||
return R.string.subscriptions_list_label;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getBottomNavigationItemId(String tag) {
|
||||
switch (tag) {
|
||||
case QueueFragment.TAG:
|
||||
return R.id.bottom_navigation_queue;
|
||||
case InboxFragment.TAG:
|
||||
return R.id.bottom_navigation_inbox;
|
||||
case AllEpisodesFragment.TAG:
|
||||
return R.id.bottom_navigation_episodes;
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.id.bottom_navigation_downloads;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.id.bottom_navigation_history;
|
||||
case AddFeedFragment.TAG:
|
||||
return R.id.bottom_navigation_addfeed;
|
||||
case SubscriptionFragment.TAG:
|
||||
return R.id.bottom_navigation_subscriptions;
|
||||
case HomeFragment.TAG: // fall-through
|
||||
default:
|
||||
return R.id.bottom_navigation_home;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBottomNavigationFragmentTag(int id) {
|
||||
if (id == R.id.bottom_navigation_queue) {
|
||||
return QueueFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_inbox) {
|
||||
return InboxFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_episodes) {
|
||||
return AllEpisodesFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_downloads) {
|
||||
return CompletedDownloadsFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_history) {
|
||||
return PlaybackHistoryFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_addfeed) {
|
||||
return AddFeedFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_subscriptions) {
|
||||
return SubscriptionFragment.TAG;
|
||||
} else if (id == R.id.bottom_navigation_home) {
|
||||
return HomeFragment.TAG;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@ import androidx.viewpager2.widget.ViewPager2;
|
|||
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.elevation.SurfaceColors;
|
||||
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.playback.service.PlaybackController;
|
||||
|
@ -121,8 +120,6 @@ public class AudioPlayerFragment extends Fragment implements
|
|||
getChildFragmentManager().beginTransaction()
|
||||
.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG)
|
||||
.commit();
|
||||
root.findViewById(R.id.playerFragment).setBackgroundColor(
|
||||
SurfaceColors.getColorForElevation(getContext(), 8 * getResources().getDisplayMetrics().density));
|
||||
|
||||
butPlaybackSpeed = root.findViewById(R.id.butPlaybackSpeed);
|
||||
txtvPlaybackSpeed = root.findViewById(R.id.txtvPlaybackSpeed);
|
||||
|
|
|
@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
|
|||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.ui.common.ThemeUtils;
|
||||
|
||||
/**
|
||||
* Workaround for app:liftOnScroll flickering when in SwipeRefreshLayout
|
||||
|
@ -16,8 +18,9 @@ public class LiftOnScrollListener extends RecyclerView.OnScrollListener
|
|||
private boolean animatingToScrolled = false;
|
||||
|
||||
public LiftOnScrollListener(View appBar) {
|
||||
animator = ValueAnimator.ofFloat(0, appBar.getContext().getResources().getDisplayMetrics().density * 8);
|
||||
animator.addUpdateListener(animation -> appBar.setElevation((float) animation.getAnimatedValue()));
|
||||
int colorLifted = ThemeUtils.getColorFromAttr(appBar.getContext(), R.attr.colorSurfaceContainer);
|
||||
animator = ValueAnimator.ofArgb(colorLifted & 0x00ffffff, colorLifted);
|
||||
animator.addUpdateListener(animation -> appBar.setBackgroundColor((int) animation.getAnimatedValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,45 +3,66 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:orientation="vertical"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/navDrawerFragment"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:orientation="vertical" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/navDrawerFragment"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/overview_coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/main_content_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:foreground="?android:windowContentOverlay"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/audioplayerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:elevation="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomNavigationView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:labelVisibilityMode="labeled" />
|
||||
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/overview_coordinator_layout"
|
||||
android:id="@+id/bottom_padding"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/main_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:foreground="?android:windowContentOverlay"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/audioplayerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:elevation="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
android:layout_height="0dp"
|
||||
android:background="?attr/colorSurfaceContainer" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="28dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
|
@ -49,7 +50,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="?attr/colorPrimaryContainer">
|
||||
android:background="?attr/colorSurfaceContainer">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/searchButton"
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
android:layout_gravity="top"
|
||||
android:elevation="8dp"
|
||||
android:outlineProvider="none"
|
||||
android:background="?attr/colorSurfaceContainer"
|
||||
tools:layout_height="@dimen/external_player_height" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/playerContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/coverImage"
|
||||
android:layout_width="@dimen/thumbnail_length_navlist"
|
||||
android:layout_height="@dimen/thumbnail_length_navlist"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:scaleType="centerInside"
|
||||
tools:src="@drawable/ic_download_black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_navdrawer"
|
||||
tools:text="Navigation item title" />
|
||||
|
||||
</LinearLayout>
|
|
@ -6,8 +6,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:padding="4dp">
|
||||
android:clipToPadding="false">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card"
|
||||
|
@ -15,8 +14,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:layout_margin="4dp"
|
||||
app:cardBackgroundColor="?attr/colorSurfaceContainer"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="0dp">
|
||||
app:cardElevation="1dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,46 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:id="@+id/main_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="InconsistentLayout"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<!-- InconsistentLayout: Tablet layout does not have a drawer -->
|
||||
<!-- viewBindingIgnore: Configurations for main.xml must
|
||||
agree on the root element's ID -->
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/overview_coordinator_layout"
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/overview_coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/main_content_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:foreground="?android:windowContentOverlay"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/audioplayerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:elevation="8dp"
|
||||
android:visibility="gone"
|
||||
android:fitsSystemWindows="false"
|
||||
app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/main_view"
|
||||
android:id="@+id/navDrawerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:foreground="?android:windowContentOverlay"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
android:layout_gravity="start"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/audioplayerFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:elevation="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/navDrawerFragment"
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomNavigationView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:orientation="vertical" />
|
||||
android:layout_height="wrap_content"
|
||||
app:labelVisibilityMode="labeled" />
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
<View
|
||||
android:id="@+id/bottom_padding"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="?attr/colorSurfaceContainer" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -17,4 +17,16 @@
|
|||
<item name="view_type_subscription_grid_with_title" type="id"/>
|
||||
<item name="view_type_subscription_grid_without_title" type="id"/>
|
||||
<item name="view_type_subscription_list" type="id"/>
|
||||
|
||||
<!-- Bottom navigation -->
|
||||
<item name="bottom_navigation_home" type="id"/>
|
||||
<item name="bottom_navigation_queue" type="id"/>
|
||||
<item name="bottom_navigation_inbox" type="id"/>
|
||||
<item name="bottom_navigation_episodes" type="id"/>
|
||||
<item name="bottom_navigation_downloads" type="id"/>
|
||||
<item name="bottom_navigation_history" type="id"/>
|
||||
<item name="bottom_navigation_addfeed" type="id"/>
|
||||
<item name="bottom_navigation_subscriptions" type="id"/>
|
||||
<item name="bottom_navigation_more" type="id"/>
|
||||
<item name="bottom_navigation_settings" type="id"/>
|
||||
</resources>
|
||||
|
|
|
@ -21,7 +21,7 @@ project.ext {
|
|||
recyclerViewVersion = "1.2.1"
|
||||
viewPager2Version = "1.1.0-beta01"
|
||||
workManagerVersion = "2.7.1"
|
||||
googleMaterialVersion = "1.7.0"
|
||||
googleMaterialVersion = "1.12.0"
|
||||
|
||||
// Third-party
|
||||
commonslangVersion = "3.6"
|
||||
|
|
|
@ -62,6 +62,7 @@ public abstract class UserPreferences {
|
|||
public static final String PREF_FILTER_FEED = "prefSubscriptionsFilter";
|
||||
public static final String PREF_SUBSCRIPTION_TITLE = "prefSubscriptionTitle";
|
||||
public static final String PREF_BACK_OPENS_DRAWER = "prefBackButtonOpensDrawer";
|
||||
public static final String PREF_BOTTOM_NAVIGATION = "prefBottomNavigation";
|
||||
|
||||
public static final String PREF_QUEUE_KEEP_SORTED = "prefQueueKeepSorted";
|
||||
public static final String PREF_QUEUE_KEEP_SORTED_ORDER = "prefQueueKeepSortedOrder";
|
||||
|
@ -758,6 +759,14 @@ public abstract class UserPreferences {
|
|||
return prefs.getBoolean(PREF_BACK_OPENS_DRAWER, false);
|
||||
}
|
||||
|
||||
public static boolean isBottomNavigationEnabled() {
|
||||
return prefs.getBoolean(PREF_BOTTOM_NAVIGATION, false);
|
||||
}
|
||||
|
||||
public static void setBottomNavigationEnabled(boolean enabled) {
|
||||
prefs.edit().putBoolean(PREF_BOTTOM_NAVIGATION, enabled).apply();
|
||||
}
|
||||
|
||||
public static boolean timeRespectsSpeed() {
|
||||
return prefs.getBoolean(PREF_TIME_RESPECTS_SPEED, false);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z" />
|
||||
|
||||
</vector>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="?attr/action_icon_color"
|
||||
android:pathData="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" />
|
||||
|
||||
</vector>
|
|
@ -3,7 +3,5 @@
|
|||
<style name="Theme.AntennaPod.Dynamic.Light" parent="Theme.Base.AntennaPod.Dynamic.Light">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<!-- To make icons visible -->
|
||||
<item name="android:navigationBarColor">@color/grey600</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
<style name="Theme.AntennaPod.Dynamic.Light" parent="Theme.Base.AntennaPod.Dynamic.Light">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<item name="android:navigationBarColor">@color/background_light</item>
|
||||
<item name="android:navigationBarDividerColor">@color/navigation_bar_divider_light</item>
|
||||
<item name="android:windowLightNavigationBar">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -11,14 +11,13 @@
|
|||
<color name="feed_text_bg">#55333333</color>
|
||||
|
||||
<!-- Theme colors -->
|
||||
<color name="background_light">#FFFFFF</color>
|
||||
<color name="background_light">#f9fcff</color>
|
||||
<color name="background_elevated_light">#EFEEEE</color>
|
||||
<color name="background_darktheme">#21272b</color>
|
||||
<color name="background_elevated_darktheme">#2D3337</color>
|
||||
<color name="non_square_icon_background">#22777777</color>
|
||||
<color name="seek_background_light">#90000000</color>
|
||||
<color name="seek_background_dark">#905B5B5B</color>
|
||||
<color name="navigation_bar_divider_light">#1F000000</color>
|
||||
|
||||
<color name="accent_light">#0078C2</color>
|
||||
<color name="accent_dark">#3D8BFF</color>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<item name="android:splitMotionEvents">false</item>
|
||||
<item name="android:fitsSystemWindows">false</item>
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="toolbarStyle">@style/Style.AntennaPod.Toolbar</item>
|
||||
<item name="preferenceTheme">@style/AppPreferenceThemeOverlay</item>
|
||||
</style>
|
||||
|
@ -44,6 +45,8 @@
|
|||
<item name="android:colorBackground">@color/background_light</item>
|
||||
<item name="colorSurface">@color/background_light</item>
|
||||
<item name="colorSurfaceVariant">#D3DCE0</item>
|
||||
<item name="colorSurfaceContainer">#EBEEF3</item>
|
||||
<item name="colorSecondaryContainer">#D3DCE0</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.Dynamic.Dark" parent="Theme.Base.AntennaPod.Dynamic.Dark">
|
||||
|
@ -70,7 +73,7 @@
|
|||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:navigationBarColor">@color/background_darktheme</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="toolbarStyle">@style/Style.AntennaPod.Toolbar</item>
|
||||
<item name="preferenceTheme">@style/AppPreferenceThemeOverlay</item>
|
||||
</style>
|
||||
|
@ -88,6 +91,8 @@
|
|||
<item name="android:colorBackground">@color/background_darktheme</item>
|
||||
<item name="colorSurface">@color/background_darktheme</item>
|
||||
<item name="colorSurfaceVariant">#2F3B4F</item>
|
||||
<item name="colorSurfaceContainer">#1C2024</item>
|
||||
<item name="colorSecondaryContainer">#2F3B4F</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.Dynamic.TrueBlack" parent="Theme.AntennaPod.Dynamic.Dark">
|
||||
|
|
|
@ -454,8 +454,10 @@
|
|||
<string name="pref_black_theme_message">Use full black for the dark theme</string>
|
||||
<string name="pref_tinted_theme_title">Dynamic colors</string>
|
||||
<string name="pref_tinted_theme_message">Adapt app colors based on the wallpaper</string>
|
||||
<string name="pref_nav_drawer_items_title">Set navigation drawer items</string>
|
||||
<string name="pref_nav_drawer_items_sum">Change which items appear in the navigation drawer</string>
|
||||
<string name="bottom_navigation">Bottom navigation</string>
|
||||
<string name="bottom_navigation_summary">Beta feature: Access the most important screens from everywhere, in a single tap</string>
|
||||
<string name="pref_nav_drawer_items_title">Customize navigation</string>
|
||||
<string name="pref_nav_drawer_items_sum">Change which items appear in the navigation drawer or bottom navigation</string>
|
||||
<string name="pref_nav_drawer_feed_order_title">Set subscription order</string>
|
||||
<string name="pref_nav_drawer_feed_order_sum">Change the order of your subscriptions</string>
|
||||
<string name="pref_nav_drawer_feed_counter_title">Set subscription counter</string>
|
||||
|
|
|
@ -80,10 +80,14 @@
|
|||
android:title="@string/pref_default_page"
|
||||
android:summary="@string/pref_default_page_sum"
|
||||
android:defaultValue="HomeFragment"/>
|
||||
<SwitchPreferenceCompat
|
||||
android:title="@string/bottom_navigation"
|
||||
android:summary="@string/bottom_navigation_summary"
|
||||
android:key="prefBottomNavigation" />
|
||||
<Preference
|
||||
android:key="prefHiddenDrawerItems"
|
||||
android:summary="@string/pref_nav_drawer_items_sum"
|
||||
android:title="@string/pref_nav_drawer_items_title"/>
|
||||
android:key="prefHiddenDrawerItems"
|
||||
android:summary="@string/pref_nav_drawer_items_sum"
|
||||
android:title="@string/pref_nav_drawer_items_title"/>
|
||||
<SwitchPreferenceCompat
|
||||
android:key="prefBackButtonOpensDrawer"
|
||||
android:title="@string/pref_back_button_opens_drawer"
|
||||
|
|
Loading…
Reference in New Issue