Going down the BottomSheetBehavior rabbit hole...
BottomSheetBehavior only supports one scrolling child. Add support for a ViewPager. ViewPager.getChildAt sometimes does not match the actual position. Make sure that it keeps all children using setOffscreenPageLimit
This commit is contained in:
parent
6b79daacfe
commit
5ad7228b4e
@ -0,0 +1,75 @@
|
||||
package com.google.android.material.bottomsheet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Override {@link #findScrollingChild(View)} to support {@link ViewPager}'s nested scrolling.
|
||||
* By the way, In order to override package level method and field.
|
||||
* This class put in the same package path where {@link BottomSheetBehavior} located.
|
||||
* Source: https://medium.com/@hanru.yeh/funny-solution-that-makes-bottomsheetdialog-support-viewpager-with-nestedscrollingchilds-bfdca72235c3
|
||||
*/
|
||||
public class ViewPagerBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
|
||||
|
||||
public ViewPagerBottomSheetBehavior() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ViewPagerBottomSheetBehavior(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
View findScrollingChild(View view) {
|
||||
if (ViewCompat.isNestedScrollingEnabled(view)) {
|
||||
return view;
|
||||
}
|
||||
|
||||
if (view instanceof ViewPager) {
|
||||
ViewPager viewPager = (ViewPager) view;
|
||||
View currentViewPagerChild = viewPager.getChildAt(viewPager.getCurrentItem());
|
||||
return findScrollingChild(currentViewPagerChild);
|
||||
} else if (view instanceof ViewGroup) {
|
||||
ViewGroup group = (ViewGroup) view;
|
||||
for (int i = 0, count = group.getChildCount(); i < count; i++) {
|
||||
View scrollingChild = findScrollingChild(group.getChildAt(i));
|
||||
if (scrollingChild != null) {
|
||||
return scrollingChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateScrollingChild() {
|
||||
final View scrollingChild = findScrollingChild(viewRef.get());
|
||||
nestedScrollingChildRef = new WeakReference<>(scrollingChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility function to get the {@link ViewPagerBottomSheetBehavior} associated with the {@code view}.
|
||||
*
|
||||
* @param view The {@link View} with {@link ViewPagerBottomSheetBehavior}.
|
||||
* @return The {@link ViewPagerBottomSheetBehavior} associated with the {@code view}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V extends View> ViewPagerBottomSheetBehavior<V> from(V view) {
|
||||
ViewGroup.LayoutParams params = view.getLayoutParams();
|
||||
if (!(params instanceof CoordinatorLayout.LayoutParams)) {
|
||||
throw new IllegalArgumentException("The view is not a child of CoordinatorLayout");
|
||||
}
|
||||
CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior();
|
||||
if (!(behavior instanceof ViewPagerBottomSheetBehavior)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The view is not associated with ViewPagerBottomSheetBehavior");
|
||||
}
|
||||
return (ViewPagerBottomSheetBehavior<V>) behavior;
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -116,7 +115,6 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (media == null || media.getChapters() == null) {
|
||||
Log.d("aaaaa", "0");
|
||||
return 0;
|
||||
}
|
||||
// ignore invalid chapters
|
||||
@ -126,7 +124,6 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
Log.d("aaaaa", "0"+counter);
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import de.danoeh.antennapod.R;
|
||||
@ -119,6 +119,14 @@ public class AudioPlayerFragment extends Fragment implements
|
||||
pager = root.findViewById(R.id.pager);
|
||||
AudioPlayerPagerAdapter pagerAdapter = new AudioPlayerPagerAdapter(getFragmentManager());
|
||||
pager.setAdapter(pagerAdapter);
|
||||
// Required for getChildAt(int) in ViewPagerBottomSheetBehavior to return the correct page
|
||||
pager.setOffscreenPageLimit(NUM_CONTENT_FRAGMENTS);
|
||||
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
pager.post(() -> ((MainActivity) getActivity()).getBottomSheet().updateScrollingChild());
|
||||
}
|
||||
});
|
||||
pageIndicator = root.findViewById(R.id.page_indicator);
|
||||
pageIndicator.setViewPager(pager);
|
||||
pageIndicator.setOnClickListener(v ->
|
||||
@ -468,7 +476,7 @@ public class AudioPlayerFragment extends Fragment implements
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class AudioPlayerPagerAdapter extends FragmentStatePagerAdapter {
|
||||
private static class AudioPlayerPagerAdapter extends FragmentPagerAdapter {
|
||||
private static final String TAG = "AudioPlayerPagerAdapter";
|
||||
|
||||
public AudioPlayerPagerAdapter(FragmentManager fm) {
|
||||
|
@ -10,6 +10,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||
import de.danoeh.antennapod.core.util.playback.Timeline;
|
||||
import de.danoeh.antennapod.view.ShownotesWebView;
|
||||
@ -35,7 +36,8 @@ public class ItemDescriptionFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
Log.d(TAG, "Creating view");
|
||||
webvDescription = new ShownotesWebView(getActivity().getApplicationContext());
|
||||
View root = inflater.inflate(R.layout.item_description_fragment, container, false);
|
||||
webvDescription = root.findViewById(R.id.webview);
|
||||
webvDescription.setTimecodeSelectedListener(time -> {
|
||||
if (controller != null) {
|
||||
controller.seekTo(time);
|
||||
@ -46,7 +48,7 @@ public class ItemDescriptionFragment extends Fragment {
|
||||
webvDescription.postDelayed(ItemDescriptionFragment.this::restoreFromPreference, 50);
|
||||
});
|
||||
registerForContextMenu(webvDescription);
|
||||
return webvDescription;
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,14 +5,13 @@ import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.ViewPagerBottomSheetBehavior;
|
||||
|
||||
/**
|
||||
* Based on https://stackoverflow.com/a/40798214
|
||||
*/
|
||||
public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
|
||||
|
||||
private boolean mLocked = false;
|
||||
public class LockableBottomSheetBehavior<V extends View> extends ViewPagerBottomSheetBehavior<V> {
|
||||
private boolean isLocked = false;
|
||||
|
||||
public LockableBottomSheetBehavior() {}
|
||||
|
||||
@ -21,14 +20,14 @@ public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBeha
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
mLocked = locked;
|
||||
isLocked = locked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
|
||||
boolean handled = false;
|
||||
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
handled = super.onInterceptTouchEvent(parent, child, event);
|
||||
}
|
||||
|
||||
@ -39,7 +38,7 @@ public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBeha
|
||||
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
|
||||
boolean handled = false;
|
||||
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
handled = super.onTouchEvent(parent, child, event);
|
||||
}
|
||||
|
||||
@ -51,7 +50,7 @@ public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBeha
|
||||
View target, int nestedScrollAxes) {
|
||||
boolean handled = false;
|
||||
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
|
||||
}
|
||||
|
||||
@ -61,14 +60,14 @@ public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBeha
|
||||
@Override
|
||||
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target,
|
||||
int dx, int dy, int[] consumed) {
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
super.onStopNestedScroll(coordinatorLayout, child, target);
|
||||
}
|
||||
}
|
||||
@ -78,11 +77,10 @@ public class LockableBottomSheetBehavior<V extends View> extends BottomSheetBeha
|
||||
float velocityX, float velocityY) {
|
||||
boolean handled = false;
|
||||
|
||||
if (!mLocked) {
|
||||
if (!isLocked) {
|
||||
handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
||||
}
|
||||
}
|
||||
|
11
app/src/main/res/layout/item_description_fragment.xml
Normal file
11
app/src/main/res/layout/item_description_fragment.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="false">
|
||||
<de.danoeh.antennapod.view.ShownotesWebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</androidx.core.widget.NestedScrollView>
|
Loading…
x
Reference in New Issue
Block a user