1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-11-26 20:19:50 +01:00

Fix views not scrollable when showing error panel

This commit is contained in:
Stypox 2021-01-15 11:26:09 +01:00
parent 463dd8ea74
commit b265cabc22
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
9 changed files with 70 additions and 48 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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
}

View File

@ -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);

View File

@ -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>