mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 08:30:44 +00:00
Fix views not scrollable when showing error panel
This commit is contained in:
parent
463dd8ea74
commit
b265cabc22
@ -1,9 +1,11 @@
|
||||
package org.schabi.newpipe.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -135,7 +137,12 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
|
||||
public void handleError() {
|
||||
isLoading.set(false);
|
||||
InfoCache.getInstance().clearCache();
|
||||
hideLoading();
|
||||
if (emptyStateView != null) {
|
||||
animateView(emptyStateView, false, 150);
|
||||
}
|
||||
if (loadingProgressBar != null) {
|
||||
animateView(loadingProgressBar, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -178,7 +185,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
|
||||
|
||||
/**
|
||||
* Show a SnackBar and only call
|
||||
* {@link ErrorActivity.reportErrorInSnackbar(androidx.fragment.app.Fragment, ErrorInfo)}
|
||||
* {@link ErrorActivity#reportErrorInSnackbar(androidx.fragment.app.Fragment, ErrorInfo)}
|
||||
* IF we a find a valid view (otherwise the error screen appears).
|
||||
*
|
||||
* @param errorInfo The error information
|
||||
|
@ -11,9 +11,18 @@ import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
public class EmptyFragment extends BaseFragment {
|
||||
final boolean showMessage;
|
||||
|
||||
public EmptyFragment(final boolean showMessage) {
|
||||
this.showMessage = showMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_empty, container, false);
|
||||
final View view = inflater.inflate(R.layout.fragment_empty, container, false);
|
||||
view.findViewById(R.id.empty_state_view).setVisibility(
|
||||
showMessage ? View.VISIBLE : View.GONE);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
@ -71,6 +70,7 @@ import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.fragments.BackPressable;
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.fragments.EmptyFragment;
|
||||
import org.schabi.newpipe.fragments.list.comments.CommentsFragment;
|
||||
import org.schabi.newpipe.fragments.list.videos.RelatedVideosFragment;
|
||||
import org.schabi.newpipe.ktx.AnimationType;
|
||||
@ -926,18 +926,22 @@ public final class VideoDetailFragment
|
||||
}
|
||||
|
||||
if (showRelatedStreams && binding.relatedStreamsLayout == null) {
|
||||
//temp empty fragment. will be updated in handleResult
|
||||
pageAdapter.addFragment(new Fragment(), RELATED_TAB_TAG);
|
||||
// temp empty fragment. will be updated in handleResult
|
||||
pageAdapter.addFragment(new EmptyFragment(false), RELATED_TAB_TAG);
|
||||
tabIcons.add(R.drawable.ic_art_track_white_24dp);
|
||||
tabContentDescriptions.add(R.string.related_streams_tab_description);
|
||||
}
|
||||
|
||||
if (showDescription) {
|
||||
// temp empty fragment. will be updated in handleResult
|
||||
pageAdapter.addFragment(new Fragment(), DESCRIPTION_TAB_TAG);
|
||||
pageAdapter.addFragment(new EmptyFragment(false), DESCRIPTION_TAB_TAG);
|
||||
tabIcons.add(R.drawable.ic_description_white_24dp);
|
||||
tabContentDescriptions.add(R.string.description_tab_description);
|
||||
}
|
||||
|
||||
if (pageAdapter.getCount() == 0) {
|
||||
pageAdapter.addFragment(new EmptyFragment(true), EMPTY_TAB_TAG);
|
||||
}
|
||||
pageAdapter.notifyDataSetUpdate();
|
||||
|
||||
if (pageAdapter.getCount() >= 2) {
|
||||
|
@ -46,6 +46,7 @@ import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||
|
||||
public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
implements ListViewContract<I, N>, StateSaver.WriteRead,
|
||||
@ -407,6 +408,12 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
// Contract
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoading() {
|
||||
super.hideLoading();
|
||||
@ -417,6 +424,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
public void showEmptyState() {
|
||||
super.showEmptyState();
|
||||
showListFooter(false);
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -437,7 +445,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
public void handleError() {
|
||||
super.handleError();
|
||||
showListFooter(false);
|
||||
animate(itemsList, false, 200);
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,8 +29,6 @@ import org.schabi.newpipe.util.Localization;
|
||||
import icepick.State;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 23.09.17.
|
||||
* <p>
|
||||
@ -160,12 +158,6 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
|
||||
// Contract
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
animate(itemsList, false, 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleResult(@NonNull final KioskInfo result) {
|
||||
super.handleResult(result);
|
||||
|
@ -60,6 +60,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||
import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
|
||||
|
||||
public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
@ -264,7 +265,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
animate(headerBinding.getRoot(), false, 200);
|
||||
animate(itemsList, false, 100);
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
|
||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.uploaderAvatarView);
|
||||
animate(headerBinding.uploaderLayout, false, 200);
|
||||
|
@ -35,11 +35,11 @@ inline var View.backgroundTintListCompat: ColorStateList?
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun View.animate(
|
||||
enterOrExit: Boolean,
|
||||
duration: Long,
|
||||
animationType: AnimationType = AnimationType.ALPHA,
|
||||
delay: Long = 0,
|
||||
execOnEnd: Runnable? = null
|
||||
enterOrExit: Boolean,
|
||||
duration: Long,
|
||||
animationType: AnimationType = AnimationType.ALPHA,
|
||||
delay: Long = 0,
|
||||
execOnEnd: Runnable? = null
|
||||
) {
|
||||
if (MainActivity.DEBUG) {
|
||||
val id = try {
|
||||
@ -48,8 +48,8 @@ fun View.animate(
|
||||
id.toString()
|
||||
}
|
||||
val msg = String.format(
|
||||
"%8s → [%s:%s] [%s %s:%s] execOnEnd=%s", enterOrExit,
|
||||
javaClass.simpleName, id, animationType, duration, delay, execOnEnd
|
||||
"%8s → [%s:%s] [%s %s:%s] execOnEnd=%s", enterOrExit,
|
||||
javaClass.simpleName, id, animationType, duration, delay, execOnEnd
|
||||
)
|
||||
Log.d(TAG, "animate(): $msg")
|
||||
}
|
||||
@ -93,10 +93,10 @@ fun View.animate(
|
||||
fun View.animateBackgroundColor(duration: Long, @ColorInt colorStart: Int, @ColorInt colorEnd: Int) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateBackgroundColor() called with: " +
|
||||
"view = [" + this + "], duration = [" + duration + "], " +
|
||||
"colorStart = [" + colorStart + "], colorEnd = [" + colorEnd + "]"
|
||||
TAG,
|
||||
"animateBackgroundColor() called with: " +
|
||||
"view = [" + this + "], duration = [" + duration + "], " +
|
||||
"colorStart = [" + colorStart + "], colorEnd = [" + colorEnd + "]"
|
||||
)
|
||||
}
|
||||
val empty = arrayOf(IntArray(0))
|
||||
@ -121,9 +121,9 @@ fun View.animateBackgroundColor(duration: Long, @ColorInt colorStart: Int, @Colo
|
||||
fun View.animateHeight(duration: Long, targetHeight: Int): ValueAnimator {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateHeight: duration = [" + duration + "], " +
|
||||
"from " + height + " to → " + targetHeight + " in: " + this
|
||||
TAG,
|
||||
"animateHeight: duration = [" + duration + "], " +
|
||||
"from " + height + " to → " + targetHeight + " in: " + this
|
||||
)
|
||||
}
|
||||
val animator = ValueAnimator.ofFloat(height.toFloat(), targetHeight.toFloat())
|
||||
@ -152,9 +152,9 @@ fun View.animateHeight(duration: Long, targetHeight: Int): ValueAnimator {
|
||||
fun View.animateRotation(duration: Long, targetRotation: Int) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateRotation: duration = [" + duration + "], " +
|
||||
"from " + rotation + " to → " + targetRotation + " in: " + this
|
||||
TAG,
|
||||
"animateRotation: duration = [" + duration + "], " +
|
||||
"from " + rotation + " to → " + targetRotation + " in: " + this
|
||||
)
|
||||
}
|
||||
animate().setListener(null).cancel()
|
||||
@ -319,6 +319,17 @@ fun View.slideUp(duration: Long, delay: Long, @FloatRange(from = 0.0, to = 1.0)
|
||||
.start()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instead of hiding normally using [animate], which would make
|
||||
* the recycler view unable to capture touches after being hidden, this just animates the alpha
|
||||
* value setting it to `0.0` after `200` milliseconds.
|
||||
*/
|
||||
fun View.animateHideRecyclerViewAllowingScrolling() {
|
||||
// not hiding normally because the view needs to still capture touches and allow scroll
|
||||
animate().alpha(0.0f).setDuration(200).start()
|
||||
}
|
||||
|
||||
enum class AnimationType {
|
||||
ALPHA, SCALE_AND_ALPHA, LIGHT_SCALE_AND_ALPHA, SLIDE_AND_ALPHA, LIGHT_SLIDE_AND_ALPHA
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.fragments.list.ListViewContract;
|
||||
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||
|
||||
/**
|
||||
* This fragment is design to be used with persistent data such as
|
||||
@ -184,7 +185,7 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
if (itemsList != null) {
|
||||
animate(itemsList, false, 200);
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
}
|
||||
if (headerRootBinding != null) {
|
||||
animate(headerRootBinding.getRoot(), false, 200);
|
||||
@ -243,7 +244,7 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||
showListFooter(false);
|
||||
|
||||
if (itemsList != null) {
|
||||
animate(itemsList, false, 200);
|
||||
animateHideRecyclerViewAllowingScrolling(itemsList);
|
||||
}
|
||||
if (headerRootBinding != null) {
|
||||
animate(headerRootBinding.getRoot(), false, 200);
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@ -14,16 +13,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="90dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
android:layout_marginTop="90dp" />
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="4dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?attr/toolbar_shadow"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
Loading…
Reference in New Issue
Block a user