Merge branch 'develop' into develop
This commit is contained in:
commit
d6d8ec43e1
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -32,7 +32,7 @@ If you are experiencing a crash, including the stacktrace will likely get it fix
|
|||||||
1. Than that
|
1. Than that
|
||||||
1. Then
|
1. Then
|
||||||
|
|
||||||
**Environment**: [Settings you have changed, e.g. Auto Download. "Unusual" devices you use, e.g. Bluetooth headphones. Do you still use Prestissimo? Did you select another media player?]
|
**Environment**: [Settings you have changed, e.g. Auto Download. "Unusual" devices you use, e.g. Bluetooth headphones. Did you select another media player?]
|
||||||
|
|
||||||
**Stacktrace/Logcat**:
|
**Stacktrace/Logcat**:
|
||||||
```
|
```
|
||||||
|
10
.github/workflows/gradle-wrapper-validation.yml
vendored
Normal file
10
.github/workflows/gradle-wrapper-validation.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
name: "Validate Gradle Wrapper"
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validation:
|
||||||
|
name: "Validation"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: gradle/wrapper-validation-action@v1
|
@ -145,6 +145,7 @@ dependencies {
|
|||||||
implementation 'androidx.media:media:1.1.0'
|
implementation 'androidx.media:media:1.1.0'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||||
|
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
||||||
implementation "androidx.work:work-runtime:$workManagerVersion"
|
implementation "androidx.work:work-runtime:$workManagerVersion"
|
||||||
implementation 'com.google.android.material:material:1.1.0'
|
implementation 'com.google.android.material:material:1.1.0'
|
||||||
|
|
||||||
|
@ -4,8 +4,10 @@ import android.content.Context;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@ -31,9 +33,10 @@ public class ViewPagerBottomSheetBehavior<V extends View> extends BottomSheetBeh
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view instanceof ViewPager) {
|
if (view instanceof ViewPager2) {
|
||||||
ViewPager viewPager = (ViewPager) view;
|
ViewPager2 viewPager = (ViewPager2) view;
|
||||||
View currentViewPagerChild = viewPager.getChildAt(viewPager.getCurrentItem());
|
RecyclerView recycler = (RecyclerView) viewPager.getChildAt(0);
|
||||||
|
View currentViewPagerChild = recycler.getChildAt(viewPager.getCurrentItem());
|
||||||
if (currentViewPagerChild != null) {
|
if (currentViewPagerChild != null) {
|
||||||
return findScrollingChild(currentViewPagerChild);
|
return findScrollingChild(currentViewPagerChild);
|
||||||
}
|
}
|
||||||
|
@ -410,7 +410,8 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
|
ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
|
||||||
showSpeedDialIfAnyChecked();
|
showSpeedDialIfAnyChecked();
|
||||||
toolbar.setTitle(getString(R.string.num_selected_label, checkedIds.size()));
|
toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label,
|
||||||
|
checkedIds.size(), checkedIds.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueChecked() {
|
private void queueChecked() {
|
||||||
|
@ -13,20 +13,28 @@ import android.widget.ImageButton;
|
|||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.CastEnabledActivity;
|
import de.danoeh.antennapod.activity.CastEnabledActivity;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.core.event.FavoritesEvent;
|
import de.danoeh.antennapod.core.event.FavoritesEvent;
|
||||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||||
import de.danoeh.antennapod.core.feed.Chapter;
|
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
||||||
@ -50,12 +58,6 @@ import io.reactivex.Maybe;
|
|||||||
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.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the audio player.
|
* Shows the audio player.
|
||||||
@ -73,7 +75,7 @@ public class AudioPlayerFragment extends Fragment implements
|
|||||||
|
|
||||||
PlaybackSpeedIndicatorView butPlaybackSpeed;
|
PlaybackSpeedIndicatorView butPlaybackSpeed;
|
||||||
TextView txtvPlaybackSpeed;
|
TextView txtvPlaybackSpeed;
|
||||||
private ViewPager pager;
|
private ViewPager2 pager;
|
||||||
private PagerIndicatorView pageIndicator;
|
private PagerIndicatorView pageIndicator;
|
||||||
private TextView txtvPosition;
|
private TextView txtvPosition;
|
||||||
private TextView txtvLength;
|
private TextView txtvLength;
|
||||||
@ -127,11 +129,10 @@ public class AudioPlayerFragment extends Fragment implements
|
|||||||
sbPosition.setOnSeekBarChangeListener(this);
|
sbPosition.setOnSeekBarChangeListener(this);
|
||||||
|
|
||||||
pager = root.findViewById(R.id.pager);
|
pager = root.findViewById(R.id.pager);
|
||||||
AudioPlayerPagerAdapter pagerAdapter = new AudioPlayerPagerAdapter(getChildFragmentManager());
|
pager.setAdapter(new AudioPlayerPagerAdapter(this));
|
||||||
pager.setAdapter(pagerAdapter);
|
|
||||||
// Required for getChildAt(int) in ViewPagerBottomSheetBehavior to return the correct page
|
// Required for getChildAt(int) in ViewPagerBottomSheetBehavior to return the correct page
|
||||||
pager.setOffscreenPageLimit(NUM_CONTENT_FRAGMENTS);
|
pager.setOffscreenPageLimit((int) NUM_CONTENT_FRAGMENTS);
|
||||||
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(int position) {
|
public void onPageSelected(int position) {
|
||||||
pager.post(() -> ((MainActivity) getActivity()).getBottomSheet().updateScrollingChild());
|
pager.post(() -> ((MainActivity) getActivity()).getBottomSheet().updateScrollingChild());
|
||||||
@ -502,30 +503,30 @@ public class AudioPlayerFragment extends Fragment implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AudioPlayerPagerAdapter extends FragmentPagerAdapter {
|
private static class AudioPlayerPagerAdapter extends FragmentStateAdapter {
|
||||||
private static final String TAG = "AudioPlayerPagerAdapter";
|
private static final String TAG = "AudioPlayerPagerAdapter";
|
||||||
|
|
||||||
public AudioPlayerPagerAdapter(FragmentManager fm) {
|
public AudioPlayerPagerAdapter(@NonNull Fragment fragment) {
|
||||||
super(fm);
|
super(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
Log.d(TAG, "getItem(" + position + ")");
|
Log.d(TAG, "getItem(" + position + ")");
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case POS_COVER:
|
case POS_COVER:
|
||||||
return new CoverFragment();
|
return new CoverFragment();
|
||||||
case POS_DESCR:
|
case POS_DESCR:
|
||||||
return new ItemDescriptionFragment();
|
return new ItemDescriptionFragment();
|
||||||
|
default:
|
||||||
case POS_CHAPTERS:
|
case POS_CHAPTERS:
|
||||||
return new ChaptersFragment();
|
return new ChaptersFragment();
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return NUM_CONTENT_FRAGMENTS;
|
return NUM_CONTENT_FRAGMENTS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,10 +86,15 @@ public class CompletedDownloadsFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
setHasOptionsMenu(true);
|
|
||||||
loadItems();
|
loadItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
@ -50,6 +50,12 @@ public class DownloadLogFragment extends ListFragment {
|
|||||||
loadItems();
|
loadItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
@ -61,8 +67,6 @@ public class DownloadLogFragment extends ListFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
// add padding
|
// add padding
|
||||||
final ListView lv = getListView();
|
final ListView lv = getListView();
|
||||||
lv.setClipToPadding(false);
|
lv.setClipToPadding(false);
|
||||||
|
@ -2,19 +2,21 @@ 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.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
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.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,10 +31,11 @@ public class DownloadsFragment extends Fragment {
|
|||||||
public static final int POS_RUNNING = 0;
|
public static final int POS_RUNNING = 0;
|
||||||
private static final int POS_COMPLETED = 1;
|
private static final int POS_COMPLETED = 1;
|
||||||
public static final int POS_LOG = 2;
|
public static final int POS_LOG = 2;
|
||||||
|
private static final int TOTAL_COUNT = 3;
|
||||||
|
|
||||||
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
||||||
|
|
||||||
private ViewPager viewPager;
|
private ViewPager2 viewPager;
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,12 +47,30 @@ public class DownloadsFragment extends Fragment {
|
|||||||
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
||||||
|
|
||||||
viewPager = root.findViewById(R.id.viewpager);
|
viewPager = root.findViewById(R.id.viewpager);
|
||||||
DownloadsPagerAdapter pagerAdapter = new DownloadsPagerAdapter(getChildFragmentManager(), getResources());
|
viewPager.setAdapter(new DownloadsPagerAdapter(this));
|
||||||
viewPager.setAdapter(pagerAdapter);
|
|
||||||
|
|
||||||
// Give the TabLayout the ViewPager
|
// Give the TabLayout the ViewPager
|
||||||
tabLayout = root.findViewById(R.id.sliding_tabs);
|
tabLayout = root.findViewById(R.id.sliding_tabs);
|
||||||
tabLayout.setupWithViewPager(viewPager);
|
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||||
|
switch (position) {
|
||||||
|
case POS_RUNNING:
|
||||||
|
tab.setText(R.string.downloads_running_label);
|
||||||
|
break;
|
||||||
|
case POS_COMPLETED:
|
||||||
|
tab.setText(R.string.downloads_completed_label);
|
||||||
|
break;
|
||||||
|
case POS_LOG:
|
||||||
|
tab.setText(R.string.downloads_log_label);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}).attach();
|
||||||
|
|
||||||
|
// restore our last position
|
||||||
|
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||||
|
int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
|
||||||
|
viewPager.setCurrentItem(lastPosition, false);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@ -73,56 +94,29 @@ public class DownloadsFragment extends Fragment {
|
|||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static class DownloadsPagerAdapter extends FragmentStateAdapter {
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
// restore our last position
|
DownloadsPagerAdapter(@NonNull Fragment fragment) {
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
super(fragment);
|
||||||
int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
|
|
||||||
viewPager.setCurrentItem(lastPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DownloadsPagerAdapter extends FragmentPagerAdapter {
|
|
||||||
|
|
||||||
final Resources resources;
|
|
||||||
|
|
||||||
public DownloadsPagerAdapter(FragmentManager fm, Resources resources) {
|
|
||||||
super(fm);
|
|
||||||
this.resources = resources;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case POS_RUNNING:
|
case POS_RUNNING:
|
||||||
return new RunningDownloadsFragment();
|
return new RunningDownloadsFragment();
|
||||||
case POS_COMPLETED:
|
case POS_COMPLETED:
|
||||||
return new CompletedDownloadsFragment();
|
return new CompletedDownloadsFragment();
|
||||||
|
default:
|
||||||
case POS_LOG:
|
case POS_LOG:
|
||||||
return new DownloadLogFragment();
|
return new DownloadLogFragment();
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return 3;
|
return TOTAL_COUNT;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getPageTitle(int position) {
|
|
||||||
switch (position) {
|
|
||||||
case POS_RUNNING:
|
|
||||||
return resources.getString(R.string.downloads_running_label);
|
|
||||||
case POS_COMPLETED:
|
|
||||||
return resources.getString(R.string.downloads_completed_label);
|
|
||||||
case POS_LOG:
|
|
||||||
return resources.getString(R.string.downloads_log_label);
|
|
||||||
default:
|
|
||||||
return super.getPageTitle(position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,17 @@ import android.os.Bundle;
|
|||||||
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.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
|
||||||
public class EpisodesFragment extends Fragment {
|
public class EpisodesFragment extends Fragment {
|
||||||
@ -27,7 +31,7 @@ public class EpisodesFragment extends Fragment {
|
|||||||
|
|
||||||
|
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
private ViewPager viewPager;
|
private ViewPager2 viewPager;
|
||||||
|
|
||||||
//Mandatory Constructor
|
//Mandatory Constructor
|
||||||
public EpisodesFragment() {
|
public EpisodesFragment() {
|
||||||
@ -46,11 +50,32 @@ public class EpisodesFragment extends Fragment {
|
|||||||
toolbar.setTitle(R.string.episodes_label);
|
toolbar.setTitle(R.string.episodes_label);
|
||||||
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
||||||
viewPager = rootView.findViewById(R.id.viewpager);
|
viewPager = rootView.findViewById(R.id.viewpager);
|
||||||
viewPager.setAdapter(new EpisodesPagerAdapter());
|
viewPager.setAdapter(new EpisodesPagerAdapter(this));
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||||
|
switch (position) {
|
||||||
|
case POS_NEW_EPISODES:
|
||||||
|
tab.setText(R.string.new_episodes_label);
|
||||||
|
break;
|
||||||
|
case POS_ALL_EPISODES:
|
||||||
|
tab.setText(R.string.all_episodes_short_label);
|
||||||
|
break;
|
||||||
|
case POS_FAV_EPISODES:
|
||||||
|
tab.setText(R.string.favorite_episodes_label);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}).attach();
|
||||||
|
|
||||||
|
// restore our last position
|
||||||
|
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||||
|
int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
|
||||||
|
viewPager.setCurrentItem(lastPosition, false);
|
||||||
|
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,52 +89,29 @@ public class EpisodesFragment extends Fragment {
|
|||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static class EpisodesPagerAdapter extends FragmentStateAdapter {
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
// restore our last position
|
EpisodesPagerAdapter(@NonNull Fragment fragment) {
|
||||||
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
super(fragment);
|
||||||
int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
|
|
||||||
viewPager.setCurrentItem(lastPosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EpisodesPagerAdapter extends FragmentPagerAdapter {
|
|
||||||
|
|
||||||
public EpisodesPagerAdapter() {
|
|
||||||
super(getChildFragmentManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Fragment getItem(int position) {
|
@Override
|
||||||
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case POS_NEW_EPISODES:
|
||||||
return new NewEpisodesFragment();
|
return new NewEpisodesFragment();
|
||||||
case 1:
|
case POS_ALL_EPISODES:
|
||||||
return new AllEpisodesFragment();
|
return new AllEpisodesFragment();
|
||||||
default:
|
default:
|
||||||
|
case POS_FAV_EPISODES:
|
||||||
return new FavoriteEpisodesFragment();
|
return new FavoriteEpisodesFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return TOTAL_COUNT;
|
return TOTAL_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getPageTitle(int position) {
|
|
||||||
switch (position) {
|
|
||||||
case POS_ALL_EPISODES:
|
|
||||||
return getString(R.string.all_episodes_short_label);
|
|
||||||
case POS_NEW_EPISODES:
|
|
||||||
return getString(R.string.new_episodes_label);
|
|
||||||
case POS_FAV_EPISODES:
|
|
||||||
return getString(R.string.favorite_episodes_label);
|
|
||||||
default:
|
|
||||||
return super.getPageTitle(position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,6 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
setHasOptionsMenu(true);
|
|
||||||
EventBus.getDefault().register(this);
|
EventBus.getDefault().register(this);
|
||||||
loadItems();
|
loadItems();
|
||||||
}
|
}
|
||||||
@ -91,6 +90,7 @@ public abstract class EpisodesListFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
setHasOptionsMenu(true);
|
||||||
registerForContextMenu(recyclerView);
|
registerForContextMenu(recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,29 +7,30 @@ 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.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.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
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.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.CastEnabledActivity;
|
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.util.Flavors;
|
|
||||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||||
import io.reactivex.Observable;
|
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.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays information about a list of FeedItems.
|
* Displays information about a list of FeedItems.
|
||||||
@ -76,31 +77,21 @@ public class ItemPagerFragment extends Fragment {
|
|||||||
feedItems = getArguments().getLongArray(ARG_FEEDITEMS);
|
feedItems = getArguments().getLongArray(ARG_FEEDITEMS);
|
||||||
int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS);
|
int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS);
|
||||||
|
|
||||||
ViewPager pager = layout.findViewById(R.id.pager);
|
ViewPager2 pager = layout.findViewById(R.id.pager);
|
||||||
// FragmentStatePagerAdapter documentation:
|
// FragmentStatePagerAdapter documentation:
|
||||||
// > When using FragmentStatePagerAdapter the host ViewPager must have a valid ID set.
|
// > When using FragmentStatePagerAdapter the host ViewPager must have a valid ID set.
|
||||||
// When opening multiple ItemPagerFragments by clicking "item" -> "visit podcast" -> "item" -> etc,
|
// When opening multiple ItemPagerFragments by clicking "item" -> "visit podcast" -> "item" -> etc,
|
||||||
// the ID is no longer unique and FragmentStatePagerAdapter does not display any pages.
|
// the ID is no longer unique and FragmentStatePagerAdapter does not display any pages.
|
||||||
int newId = ViewCompat.generateViewId();
|
int newId = ViewCompat.generateViewId();
|
||||||
pager.setId(newId);
|
pager.setId(newId);
|
||||||
pager.setAdapter(new ItemPagerAdapter());
|
pager.setAdapter(new ItemPagerAdapter(this));
|
||||||
pager.setCurrentItem(feedItemPos);
|
pager.setCurrentItem(feedItemPos, false);
|
||||||
loadItem(feedItems[feedItemPos]);
|
loadItem(feedItems[feedItemPos]);
|
||||||
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||||
@Override
|
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(int position) {
|
public void onPageSelected(int position) {
|
||||||
loadItem(feedItems[position]);
|
loadItem(feedItems[position]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrollStateChanged(int state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EventBus.getDefault().register(this);
|
EventBus.getDefault().register(this);
|
||||||
@ -173,20 +164,20 @@ public class ItemPagerFragment extends Fragment {
|
|||||||
((MainActivity) getActivity()).loadChildFragment(fragment);
|
((MainActivity) getActivity()).loadChildFragment(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ItemPagerAdapter extends FragmentStatePagerAdapter {
|
private class ItemPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
ItemPagerAdapter() {
|
ItemPagerAdapter(@NonNull Fragment fragment) {
|
||||||
super(getFragmentManager(), BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
super(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
return ItemFragment.newInstance(feedItems[position]);
|
return ItemFragment.newInstance(feedItems[position]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return feedItems.length;
|
return feedItems.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,17 @@ import android.os.Bundle;
|
|||||||
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.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,6 +22,11 @@ import de.danoeh.antennapod.R;
|
|||||||
*/
|
*/
|
||||||
public class GpodnetMainFragment extends Fragment {
|
public class GpodnetMainFragment extends Fragment {
|
||||||
|
|
||||||
|
private static final int NUM_PAGES = 2;
|
||||||
|
private static final int POS_TOPLIST = 0;
|
||||||
|
private static final int POS_TAGS = 1;
|
||||||
|
private static final int POS_SUGGESTIONS = 2;
|
||||||
|
|
||||||
@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);
|
||||||
@ -26,63 +35,59 @@ public class GpodnetMainFragment extends Fragment {
|
|||||||
toolbar.setTitle(R.string.gpodnet_main_label);
|
toolbar.setTitle(R.string.gpodnet_main_label);
|
||||||
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
||||||
|
|
||||||
ViewPager viewPager = root.findViewById(R.id.viewpager);
|
ViewPager2 viewPager = root.findViewById(R.id.viewpager);
|
||||||
GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(getChildFragmentManager());
|
GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(this);
|
||||||
viewPager.setAdapter(pagerAdapter);
|
viewPager.setAdapter(pagerAdapter);
|
||||||
|
|
||||||
// Give the TabLayout the ViewPager
|
// Give the TabLayout the ViewPager
|
||||||
TabLayout tabLayout = root.findViewById(R.id.sliding_tabs);
|
TabLayout tabLayout = root.findViewById(R.id.sliding_tabs);
|
||||||
tabLayout.setupWithViewPager(viewPager);
|
|
||||||
|
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||||
|
switch (position) {
|
||||||
|
case POS_TAGS:
|
||||||
|
tab.setText(R.string.gpodnet_taglist_header);
|
||||||
|
break;
|
||||||
|
case POS_TOPLIST:
|
||||||
|
tab.setText(R.string.gpodnet_toplist_header);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case POS_SUGGESTIONS:
|
||||||
|
tab.setText(R.string.gpodnet_suggestions_header);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}).attach();
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GpodnetPagerAdapter extends FragmentPagerAdapter {
|
public static class GpodnetPagerAdapter extends FragmentStateAdapter {
|
||||||
private static final int NUM_PAGES = 2;
|
|
||||||
private static final int POS_TOPLIST = 0;
|
|
||||||
private static final int POS_TAGS = 1;
|
|
||||||
private static final int POS_SUGGESTIONS = 2;
|
|
||||||
|
|
||||||
public GpodnetPagerAdapter(FragmentManager fm) {
|
GpodnetPagerAdapter(@NonNull Fragment fragment) {
|
||||||
super(fm);
|
super(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int i) {
|
public Fragment createFragment(int position) {
|
||||||
Bundle arguments = new Bundle();
|
Bundle arguments = new Bundle();
|
||||||
arguments.putBoolean(PodcastListFragment.ARGUMENT_HIDE_TOOLBAR, true);
|
arguments.putBoolean(PodcastListFragment.ARGUMENT_HIDE_TOOLBAR, true);
|
||||||
switch (i) {
|
switch (position) {
|
||||||
case POS_TAGS:
|
case POS_TAGS:
|
||||||
return new TagListFragment();
|
return new TagListFragment();
|
||||||
case POS_TOPLIST:
|
case POS_TOPLIST:
|
||||||
PodcastListFragment topListFragment = new PodcastTopListFragment();
|
PodcastListFragment topListFragment = new PodcastTopListFragment();
|
||||||
topListFragment.setArguments(arguments);
|
topListFragment.setArguments(arguments);
|
||||||
return topListFragment;
|
return topListFragment;
|
||||||
|
default:
|
||||||
case POS_SUGGESTIONS:
|
case POS_SUGGESTIONS:
|
||||||
PodcastListFragment suggestionsFragment = new SuggestionListFragment();
|
PodcastListFragment suggestionsFragment = new SuggestionListFragment();
|
||||||
suggestionsFragment.setArguments(arguments);
|
suggestionsFragment.setArguments(arguments);
|
||||||
return suggestionsFragment;
|
return suggestionsFragment;
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getPageTitle(int position) {
|
public int getItemCount() {
|
||||||
switch (position) {
|
|
||||||
case POS_TAGS:
|
|
||||||
return getString(R.string.gpodnet_taglist_header);
|
|
||||||
case POS_TOPLIST:
|
|
||||||
return getString(R.string.gpodnet_toplist_header);
|
|
||||||
case POS_SUGGESTIONS:
|
|
||||||
return getString(R.string.gpodnet_suggestions_header);
|
|
||||||
default:
|
|
||||||
return super.getPageTitle(position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return NUM_PAGES;
|
return NUM_PAGES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package de.danoeh.antennapod.fragment.preferences;
|
package de.danoeh.antennapod.fragment.preferences;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
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.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||||
@ -29,25 +29,35 @@ public class StatisticsFragment extends Fragment {
|
|||||||
|
|
||||||
|
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
private ViewPager viewPager;
|
private ViewPager2 viewPager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
|
View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
|
||||||
viewPager = rootView.findViewById(R.id.viewpager);
|
viewPager = rootView.findViewById(R.id.viewpager);
|
||||||
viewPager.setAdapter(new StatisticsPagerAdapter(getChildFragmentManager(), getResources()));
|
viewPager.setAdapter(new StatisticsPagerAdapter(this));
|
||||||
|
|
||||||
// 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);
|
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||||
|
switch (position) {
|
||||||
|
case POS_LISTENED_HOURS:
|
||||||
|
tab.setText(R.string.playback_statistics_label);
|
||||||
|
break;
|
||||||
|
case POS_SPACE_TAKEN:
|
||||||
|
tab.setText(R.string.download_statistics_label);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}).attach();
|
||||||
|
|
||||||
rootView.findViewById(R.id.toolbar).setVisibility(View.GONE);
|
rootView.findViewById(R.id.toolbar).setVisibility(View.GONE);
|
||||||
|
|
||||||
@ -60,39 +70,27 @@ public class StatisticsFragment extends Fragment {
|
|||||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StatisticsPagerAdapter extends FragmentPagerAdapter {
|
public static class StatisticsPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
private final Resources resources;
|
StatisticsPagerAdapter(@NonNull Fragment fragment) {
|
||||||
|
super(fragment);
|
||||||
public StatisticsPagerAdapter(FragmentManager fm, Resources resources) {
|
|
||||||
super(fm);
|
|
||||||
this.resources = resources;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
if (position == 0) {
|
switch (position) {
|
||||||
|
case POS_LISTENED_HOURS:
|
||||||
return new PlaybackStatisticsFragment();
|
return new PlaybackStatisticsFragment();
|
||||||
} else {
|
default:
|
||||||
|
case POS_SPACE_TAKEN:
|
||||||
return new DownloadStatisticsFragment();
|
return new DownloadStatisticsFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getItemCount() {
|
||||||
return TOTAL_COUNT;
|
return TOTAL_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getPageTitle(int position) {
|
|
||||||
switch (position) {
|
|
||||||
case POS_LISTENED_HOURS:
|
|
||||||
return resources.getString(R.string.playback_statistics_label);
|
|
||||||
case POS_SPACE_TAKEN:
|
|
||||||
return resources.getString(R.string.download_statistics_label);
|
|
||||||
default:
|
|
||||||
return super.getPageTitle(position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Source: https://github.com/android/views-widgets-samples/blob/87e58d1/ViewPager2/app/src/main/java/androidx/viewpager2/integration/testapp/NestedScrollableHost.kt
|
||||||
|
* And modified for our need
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.danoeh.antennapod.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
import android.view.ViewParent;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
import static androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL;
|
||||||
|
import static androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout to wrap a scrollable component inside a ViewPager2. Provided as a solution to the problem
|
||||||
|
* where pages of ViewPager2 have nested scrollable elements that scroll in the same direction as
|
||||||
|
* ViewPager2. The scrollable element needs to be the immediate and only child of this host layout.
|
||||||
|
*
|
||||||
|
* <p>This solution has limitations when using multiple levels of nested scrollable elements
|
||||||
|
* (e.g. a horizontal RecyclerView in a vertical RecyclerView in a horizontal ViewPager2).
|
||||||
|
*/
|
||||||
|
class NestedScrollableHost extends FrameLayout {
|
||||||
|
|
||||||
|
public NestedScrollableHost(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NestedScrollableHost(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int touchSlop = 0;
|
||||||
|
private float initialX = 0f;
|
||||||
|
private float initialY = 0f;
|
||||||
|
|
||||||
|
private ViewPager2 getParentViewPager() {
|
||||||
|
View v = (View) getParent();
|
||||||
|
while (v != null && !(v instanceof ViewPager2)) {
|
||||||
|
v = (View) v.getParent();
|
||||||
|
}
|
||||||
|
return v == null ? null : (ViewPager2) v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent e) {
|
||||||
|
ViewPager2 parentViewPager = getParentViewPager();
|
||||||
|
if (parentViewPager == null) {
|
||||||
|
return super.onInterceptTouchEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewParent parent = getParent();
|
||||||
|
int orientation = parentViewPager.getOrientation();
|
||||||
|
|
||||||
|
if (e.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
initialX = e.getX();
|
||||||
|
initialY = e.getY();
|
||||||
|
parent.requestDisallowInterceptTouchEvent(true);
|
||||||
|
} else if (e.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
int dx = (int) (e.getX() - initialX);
|
||||||
|
int dy = (int) (e.getY() - initialY);
|
||||||
|
boolean isVpHorizontal = orientation == ORIENTATION_HORIZONTAL;
|
||||||
|
|
||||||
|
// assuming ViewPager2 touch-slop is 2x touch-slop of child
|
||||||
|
float scaledDx = Math.abs(dx) * (isVpHorizontal ? .5f : 1f);
|
||||||
|
float scaledDy = Math.abs(dy) * (isVpHorizontal ? 1f : .5f);
|
||||||
|
if (scaledDx > touchSlop || scaledDy > touchSlop) {
|
||||||
|
int value = isVpHorizontal ? dy : dx;
|
||||||
|
if (isVpHorizontal == (scaledDy > scaledDx)) {
|
||||||
|
// Gesture is perpendicular
|
||||||
|
orientation = orientation == ORIENTATION_VERTICAL
|
||||||
|
? ORIENTATION_HORIZONTAL : ORIENTATION_VERTICAL;
|
||||||
|
value = isVpHorizontal ? dy : dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int direction = (int) -Math.copySign(1, value);
|
||||||
|
View child = getChildAt(0);
|
||||||
|
if (orientation == ORIENTATION_HORIZONTAL) {
|
||||||
|
parent.requestDisallowInterceptTouchEvent(child.canScrollHorizontally(direction));
|
||||||
|
} else {
|
||||||
|
parent.requestDisallowInterceptTouchEvent(child.canScrollVertically(direction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onInterceptTouchEvent(e);
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,20 @@
|
|||||||
package de.danoeh.antennapod.view;
|
package de.danoeh.antennapod.view;
|
||||||
|
|
||||||
|
import android.animation.ArgbEvaluator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.database.DataSetObserver;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.vectordrawable.graphics.drawable.ArgbEvaluator;
|
import androidx.core.text.TextUtilsCompat;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class PagerIndicatorView extends View {
|
public class PagerIndicatorView extends View {
|
||||||
private final Paint paint = new Paint();
|
private final Paint paint = new Paint();
|
||||||
@ -45,19 +50,24 @@ public class PagerIndicatorView extends View {
|
|||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setViewPager(ViewPager pager) {
|
public void setViewPager(ViewPager2 pager) {
|
||||||
numPages = pager.getAdapter().getCount();
|
numPages = pager.getAdapter().getItemCount();
|
||||||
pager.getAdapter().registerDataSetObserver(new DataSetObserver() {
|
pager.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged() {
|
public void onChanged() {
|
||||||
numPages = pager.getAdapter().getCount();
|
numPages = pager.getAdapter().getItemCount();
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
boolean isLocaleRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
|
||||||
|
== ViewCompat.LAYOUT_DIRECTION_RTL;
|
||||||
|
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
PagerIndicatorView.this.position = position + positionOffset;
|
PagerIndicatorView.this.position = position + positionOffset;
|
||||||
|
if (isLocaleRtl) {
|
||||||
|
PagerIndicatorView.this.position = numPages - 1 - PagerIndicatorView.this.position;
|
||||||
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
tools:background="@android:color/holo_green_light"
|
tools:background="@android:color/holo_green_light"
|
||||||
android:elevation="8dp"/>
|
android:elevation="8dp"/>
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/pager"
|
android:id="@+id/pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:cropToPadding="true"
|
android:cropToPadding="true"
|
||||||
android:scaleType="centerCrop"
|
android:maxWidth="96dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
tools:src="@tools:sample/avatars"/>
|
tools:src="@tools:sample/avatars"/>
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,13 +171,19 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<de.danoeh.antennapod.view.NestedScrollableHost
|
||||||
|
android:layout_below="@id/header"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<de.danoeh.antennapod.view.ShownotesWebView
|
<de.danoeh.antennapod.view.ShownotesWebView
|
||||||
android:id="@+id/webvDescription"
|
android:id="@+id/webvDescription"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_below="@id/header"
|
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:foreground="?android:windowContentOverlay" />
|
android:foreground="?android:windowContentOverlay" />
|
||||||
|
|
||||||
|
</de.danoeh.antennapod.view.NestedScrollableHost>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
app:navigationIcon="?homeAsUpIndicator"
|
app:navigationIcon="?homeAsUpIndicator"
|
||||||
android:id="@+id/toolbar"/>
|
android:id="@+id/toolbar"/>
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/pager"
|
android:id="@+id/pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
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"
|
||||||
android:fillViewport="false">
|
android:fillViewport="false">
|
||||||
|
|
||||||
|
<de.danoeh.antennapod.view.NestedScrollableHost
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<de.danoeh.antennapod.view.ShownotesWebView
|
<de.danoeh.antennapod.view.ShownotesWebView
|
||||||
android:id="@+id/webview"
|
android:id="@+id/webview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</de.danoeh.antennapod.view.NestedScrollableHost>
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
@ -21,9 +21,9 @@
|
|||||||
app:tabMode="fixed"
|
app:tabMode="fixed"
|
||||||
app:tabGravity="fill"/>
|
app:tabGravity="fill"/>
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/viewpager"
|
android:id="@+id/viewpager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
app:tabGravity="fill"
|
app:tabGravity="fill"
|
||||||
app:tabMode="fixed" />
|
app:tabMode="fixed" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
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="0px"
|
||||||
|
@ -116,7 +116,9 @@
|
|||||||
<item quantity="one">1 day after finishing</item>
|
<item quantity="one">1 day after finishing</item>
|
||||||
<item quantity="other">%d days after finishing</item>
|
<item quantity="other">%d days after finishing</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="num_selected_label">%d selected</string>
|
<plurals name="num_selected_label">
|
||||||
|
<item quantity="other">%d selected</item>
|
||||||
|
</plurals>
|
||||||
<string name="loading_more">Loading more…</string>
|
<string name="loading_more">Loading more…</string>
|
||||||
|
|
||||||
<!-- Actions on feeds -->
|
<!-- Actions on feeds -->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user