AppBarLayout scrolling awesomeness, PlayQueue layout touches interception, player's controls' margin

- made scrolling in appBarLayout awesome
- PlayQueue layout was intercepting touches while it was in GONE visibility state. Now it's not gonna happen
- removed margin between two lines of player's controls
- when a user leaves the app with two back presses the app will not stop MainPlayer service if popup or background players play
This commit is contained in:
Avently 2020-02-12 22:33:23 +03:00
parent f334a2740f
commit a47e6dd8c5
8 changed files with 69 additions and 102 deletions

View file

@ -23,14 +23,14 @@ public final class FlingBehavior extends AppBarLayout.Behavior {
}
private boolean allowScroll = true;
private Rect playQueueRect = new Rect();
private Rect globalRect = new Rect();
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
ViewGroup playQueue = child.findViewById(R.id.playQueue);
ViewGroup playQueue = child.findViewById(R.id.playQueuePanel);
if (playQueue != null) {
playQueue.getGlobalVisibleRect(playQueueRect);
if (playQueueRect.contains((int) ev.getRawX(), (int) ev.getRawY())) {
boolean visible = playQueue.getGlobalVisibleRect(globalRect);
if (visible && globalRect.contains((int) ev.getRawX(), (int) ev.getRawY())) {
allowScroll = false;
return false;
}

View file

@ -403,8 +403,9 @@ public class VideoDetailFragment
public void onDestroy() {
super.onDestroy();
if (!activity.isFinishing()) unbind();
else stopService();
// Stop the service when user leaves the app with double back press if video player is selected. Otherwise unbind
if (activity.isFinishing() && player != null && player.videoPlayerSelected()) stopService();
else unbind();
PreferenceManager.getDefaultSharedPreferences(activity)
.unregisterOnSharedPreferenceChangeListener(this);

View file

@ -306,6 +306,7 @@ public class VideoPlayerImpl extends VideoPlayer
playerCloseButton.setVisibility(View.GONE);
getTopControlsRoot().bringToFront();
getBottomControlsRoot().bringToFront();
onQueueClosed();
} else {
fullscreenButton.setVisibility(View.GONE);
setupScreenRotationButton(service.isLandscape());
@ -678,7 +679,10 @@ public class VideoPlayerImpl extends VideoPlayer
private void onQueueClosed() {
animateView(queueLayout, SLIDE_AND_ALPHA, /*visible=*/false,
DEFAULT_CONTROLS_DURATION);
DEFAULT_CONTROLS_DURATION, 0, () -> {
// Even when queueLayout is GONE it receives touch events and ruins normal behavior of the app. This line fixes it
queueLayout.setTranslationY(-queueLayout.getHeight() * 5);
});
queueVisible = false;
}

View file

@ -4,61 +4,46 @@ import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import org.schabi.newpipe.R;
public class CustomBottomSheetBehavior extends BottomSheetBehavior {
import java.util.Arrays;
import java.util.List;
public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout> {
public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
boolean skippingInterception = false;
boolean visible;
Rect globalRect = new Rect();
private boolean skippingInterception = false;
private List<Integer> skipInterceptionOfElements = Arrays.asList(
R.id.detail_content_root_layout, R.id.relatedStreamsLayout, R.id.playQueuePanel, R.id.viewpager);
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent event) {
// Behavior of globalVisibleRect is different on different APIs.
// For example, on API 19 getGlobalVisibleRect returns a filled rect of a collapsed view while on the latest API
// it returns empty rect in that case. So check visibility with return value too
boolean visible;
Rect rect = new Rect();
// Drop folowing when actions ends
public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull FrameLayout child, MotionEvent event) {
// Drop following when action ends
if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP)
skippingInterception = false;
// Found that user still swipping, continue folowing
// Found that user still swiping, continue following
if (skippingInterception) return false;
// Without overriding scrolling will not work in detail_content_root_layout
ViewGroup controls = child.findViewById(R.id.detail_content_root_layout);
if (controls != null) {
visible = controls.getGlobalVisibleRect(rect);
if (rect.contains((int) event.getRawX(), (int) event.getRawY()) && visible) {
skippingInterception = true;
return false;
}
}
// Without overriding scrolling will not work on relatedStreamsLayout
ViewGroup relatedStreamsLayout = child.findViewById(R.id.relatedStreamsLayout);
if (relatedStreamsLayout != null) {
visible = relatedStreamsLayout.getGlobalVisibleRect(rect);
if (rect.contains((int) event.getRawX(), (int) event.getRawY()) && visible) {
skippingInterception = true;
return false;
}
}
ViewGroup playQueue = child.findViewById(R.id.playQueue);
if (playQueue != null) {
visible = playQueue.getGlobalVisibleRect(rect);
if (rect.contains((int) event.getRawX(), (int) event.getRawY()) && visible) {
skippingInterception = true;
return false;
// Without overriding scrolling will not work when user touches these elements
for (Integer element : skipInterceptionOfElements) {
ViewGroup viewGroup = child.findViewById(element);
if (viewGroup != null) {
visible = viewGroup.getGlobalVisibleRect(globalRect);
if (visible && globalRect.contains((int) event.getRawX(), (int) event.getRawY())) {
skippingInterception = true;
return false;
}
}
}