mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-22 02:53:09 +01:00
Merge pull request #5333 from Isira-Seneviratne/Convert_AnimationUtils_to_extensions
Convert AnimationUtils functions to extension functions.
This commit is contained in:
commit
b73eb9438d
@ -37,7 +37,7 @@ import icepick.State;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> {
|
||||
@State
|
||||
@ -131,35 +131,35 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
|
||||
@Override
|
||||
public void showLoading() {
|
||||
if (emptyStateView != null) {
|
||||
animateView(emptyStateView, false, 150);
|
||||
animate(emptyStateView, false, 150);
|
||||
}
|
||||
if (loadingProgressBar != null) {
|
||||
animateView(loadingProgressBar, true, 400);
|
||||
animate(loadingProgressBar, true, 400);
|
||||
}
|
||||
animateView(errorPanelRoot, false, 150);
|
||||
animate(errorPanelRoot, false, 150);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoading() {
|
||||
if (emptyStateView != null) {
|
||||
animateView(emptyStateView, false, 150);
|
||||
animate(emptyStateView, false, 150);
|
||||
}
|
||||
if (loadingProgressBar != null) {
|
||||
animateView(loadingProgressBar, false, 0);
|
||||
animate(loadingProgressBar, false, 0);
|
||||
}
|
||||
animateView(errorPanelRoot, false, 150);
|
||||
animate(errorPanelRoot, false, 150);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyState() {
|
||||
isLoading.set(false);
|
||||
if (emptyStateView != null) {
|
||||
animateView(emptyStateView, true, 200);
|
||||
animate(emptyStateView, true, 200);
|
||||
}
|
||||
if (loadingProgressBar != null) {
|
||||
animateView(loadingProgressBar, false, 0);
|
||||
animate(loadingProgressBar, false, 0);
|
||||
}
|
||||
animateView(errorPanelRoot, false, 150);
|
||||
animate(errorPanelRoot, false, 150);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -174,11 +174,11 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
|
||||
|
||||
errorTextView.setText(message);
|
||||
if (showRetryButton) {
|
||||
animateView(errorButtonRetry, true, 600);
|
||||
animate(errorButtonRetry, true, 600);
|
||||
} else {
|
||||
animateView(errorButtonRetry, false, 0);
|
||||
animate(errorButtonRetry, false, 0);
|
||||
}
|
||||
animateView(errorPanelRoot, true, 300);
|
||||
animate(errorPanelRoot, true, 300);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,11 +76,12 @@ 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;
|
||||
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
|
||||
import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.player.Player;
|
||||
import org.schabi.newpipe.player.MainPlayer;
|
||||
import org.schabi.newpipe.player.Player;
|
||||
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
||||
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||
@ -125,7 +126,7 @@ import static org.schabi.newpipe.extractor.stream.StreamExtractor.NO_AGE_LIMIT;
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.globalScreenOrientationLocked;
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.isClearingQueueConfirmationRequired;
|
||||
import static org.schabi.newpipe.player.playqueue.PlayQueueItem.RECOVERY_UNSET;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView;
|
||||
|
||||
public final class VideoDetailFragment
|
||||
@ -745,8 +746,10 @@ public final class VideoDetailFragment
|
||||
}
|
||||
|
||||
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
animateView(appendControlsDetail, true, 250, 0, () ->
|
||||
animateView(appendControlsDetail, false, 1500, 1000));
|
||||
animate(appendControlsDetail, true, 250, AnimationType.ALPHA,
|
||||
0, () ->
|
||||
animate(appendControlsDetail, false, 1500,
|
||||
AnimationType.ALPHA, 1000));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@ -1334,8 +1337,8 @@ public final class VideoDetailFragment
|
||||
|
||||
thumbnailImageView.setImageDrawable(
|
||||
AppCompatResources.getDrawable(requireContext(), imageResource));
|
||||
animateView(thumbnailImageView, false, 0, 0,
|
||||
() -> animateView(thumbnailImageView, true, 500));
|
||||
animate(thumbnailImageView, false, 0, AnimationType.ALPHA, 0,
|
||||
() -> animate(thumbnailImageView, true, 500));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1417,14 +1420,14 @@ public final class VideoDetailFragment
|
||||
contentRootLayoutHiding.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
animateView(thumbnailPlayButton, false, 50);
|
||||
animateView(detailDurationView, false, 100);
|
||||
animateView(detailPositionView, false, 100);
|
||||
animateView(positionView, false, 50);
|
||||
animate(thumbnailPlayButton, false, 50);
|
||||
animate(detailDurationView, false, 100);
|
||||
animate(detailPositionView, false, 100);
|
||||
animate(positionView, false, 50);
|
||||
|
||||
videoTitleTextView.setText(title);
|
||||
videoTitleTextView.setMaxLines(1);
|
||||
animateView(videoTitleTextView, true, 0);
|
||||
animate(videoTitleTextView, true, 0);
|
||||
|
||||
videoDescriptionRootLayout.setVisibility(View.GONE);
|
||||
videoTitleToggleArrow.setVisibility(View.GONE);
|
||||
@ -1466,7 +1469,7 @@ public final class VideoDetailFragment
|
||||
player != null && player.isFullscreen() ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
animateView(thumbnailPlayButton, true, 200);
|
||||
animate(thumbnailPlayButton, true, 200);
|
||||
videoTitleTextView.setText(title);
|
||||
|
||||
if (!isEmpty(info.getSubChannelName())) {
|
||||
@ -1530,12 +1533,12 @@ public final class VideoDetailFragment
|
||||
detailDurationView.setText(Localization.getDurationString(info.getDuration()));
|
||||
detailDurationView.setBackgroundColor(
|
||||
ContextCompat.getColor(activity, R.color.duration_background_color));
|
||||
animateView(detailDurationView, true, 100);
|
||||
animate(detailDurationView, true, 100);
|
||||
} else if (info.getStreamType() == StreamType.LIVE_STREAM) {
|
||||
detailDurationView.setText(R.string.duration_live);
|
||||
detailDurationView.setBackgroundColor(
|
||||
ContextCompat.getColor(activity, R.color.live_duration_background_color));
|
||||
animateView(detailDurationView, true, 100);
|
||||
animate(detailDurationView, true, 100);
|
||||
} else {
|
||||
detailDurationView.setVisibility(View.GONE);
|
||||
}
|
||||
@ -1703,8 +1706,8 @@ public final class VideoDetailFragment
|
||||
// Show saved position from backStack if user allows it
|
||||
showPlaybackProgress(playQueue.getItem().getRecoveryPosition(),
|
||||
playQueue.getItem().getDuration() * 1000);
|
||||
animateView(positionView, true, 500);
|
||||
animateView(detailPositionView, true, 500);
|
||||
animate(positionView, true, 500);
|
||||
animate(detailPositionView, true, 500);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1718,8 +1721,8 @@ public final class VideoDetailFragment
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(state -> {
|
||||
showPlaybackProgress(state.getProgressTime(), info.getDuration() * 1000);
|
||||
animateView(positionView, true, 500);
|
||||
animateView(detailPositionView, true, 500);
|
||||
animate(positionView, true, 500);
|
||||
animate(detailPositionView, true, 500);
|
||||
}, e -> {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
@ -1747,8 +1750,8 @@ public final class VideoDetailFragment
|
||||
detailPositionView.setText(position);
|
||||
}
|
||||
if (positionView.getVisibility() != View.VISIBLE) {
|
||||
animateView(positionView, true, 100);
|
||||
animateView(detailPositionView, true, 100);
|
||||
animate(positionView, true, 100);
|
||||
animate(detailPositionView, true, 100);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,8 +1805,8 @@ public final class VideoDetailFragment
|
||||
&& player.getPlayQueue() != null
|
||||
&& player.getPlayQueue().getItem() != null
|
||||
&& player.getPlayQueue().getItem().getUrl().equals(url)) {
|
||||
animateView(positionView, true, 100);
|
||||
animateView(detailPositionView, true, 100);
|
||||
animate(positionView, true, 100);
|
||||
animate(detailPositionView, true, 100);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
implements ListViewContract<I, N>, StateSaver.WriteRead,
|
||||
@ -406,23 +406,17 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
// Contract
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
// animateView(itemsList, false, 400);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoading() {
|
||||
super.hideLoading();
|
||||
animateView(itemsList, true, 300);
|
||||
animate(itemsList, true, 300);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showError(final String message, final boolean showRetryButton) {
|
||||
super.showError(message, showRetryButton);
|
||||
showListFooter(false);
|
||||
animateView(itemsList, false, 200);
|
||||
animate(itemsList, false, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,12 +37,12 @@ import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
|
||||
import org.schabi.newpipe.ktx.AnimationType;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
||||
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
@ -64,9 +64,9 @@ import io.reactivex.rxjava3.functions.Consumer;
|
||||
import io.reactivex.rxjava3.functions.Function;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateBackgroundColor;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateTextColor;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor;
|
||||
|
||||
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
implements View.OnClickListener {
|
||||
@ -224,7 +224,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
|
||||
private void monitorSubscription(final ChannelInfo info) {
|
||||
final Consumer<Throwable> onError = (Throwable throwable) -> {
|
||||
animateView(headerBinding.channelSubscribeButton, false, 100);
|
||||
animate(headerBinding.channelSubscribeButton, false, 100);
|
||||
showSnackBarError(throwable, UserAction.SUBSCRIPTION,
|
||||
NewPipe.getNameOfService(currentInfo.getServiceId()),
|
||||
"Get subscription status", 0);
|
||||
@ -379,8 +379,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
subscribedText);
|
||||
}
|
||||
|
||||
animateView(headerBinding.channelSubscribeButton, AnimationUtils.Type.LIGHT_SCALE_AND_ALPHA,
|
||||
true, 100);
|
||||
animate(headerBinding.channelSubscribeButton, true, 100,
|
||||
AnimationType.LIGHT_SCALE_AND_ALPHA);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -436,7 +436,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.channelBannerImage);
|
||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.channelAvatarView);
|
||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.subChannelAvatarView);
|
||||
animateView(headerBinding.channelSubscribeButton, false, 100);
|
||||
animate(headerBinding.channelSubscribeButton, false, 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,8 +16,8 @@ import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfo;
|
||||
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
@ -84,16 +84,14 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> {
|
||||
public void handleResult(@NonNull final CommentsInfo result) {
|
||||
super.handleResult(result);
|
||||
|
||||
AnimationUtils.slideUp(requireView(), 120, 150, 0.06f);
|
||||
ViewUtils.slideUp(requireView(), 120, 150, 0.06f);
|
||||
|
||||
if (!result.getErrors().isEmpty()) {
|
||||
showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS,
|
||||
NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
|
||||
}
|
||||
|
||||
if (disposables != null) {
|
||||
disposables.clear();
|
||||
}
|
||||
disposables.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,7 +28,7 @@ import org.schabi.newpipe.util.Localization;
|
||||
import icepick.State;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 23.09.17.
|
||||
@ -160,7 +160,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
|
||||
@Override
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
animateView(itemsList, false, 100);
|
||||
animate(itemsList, false, 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,7 +61,7 @@ import io.reactivex.rxjava3.core.Single;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
|
||||
|
||||
public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
@ -261,19 +261,19 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
@Override
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
animateView(headerBinding.getRoot(), false, 200);
|
||||
animateView(itemsList, false, 100);
|
||||
animate(headerBinding.getRoot(), false, 200);
|
||||
animate(itemsList, false, 100);
|
||||
|
||||
IMAGE_LOADER.cancelDisplayTask(headerBinding.uploaderAvatarView);
|
||||
animateView(headerBinding.uploaderLayout, false, 200);
|
||||
animate(headerBinding.uploaderLayout, false, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleResult(@NonNull final PlaylistInfo result) {
|
||||
super.handleResult(result);
|
||||
|
||||
animateView(headerBinding.getRoot(), true, 100);
|
||||
animateView(headerBinding.uploaderLayout, true, 300);
|
||||
animate(headerBinding.getRoot(), true, 100);
|
||||
animate(headerBinding.uploaderLayout, true, 300);
|
||||
headerBinding.uploaderLayout.setOnClickListener(null);
|
||||
// If we have an uploader put them into the UI
|
||||
if (!TextUtils.isEmpty(result.getUploaderName())) {
|
||||
|
@ -51,12 +51,12 @@ import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearch
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory;
|
||||
import org.schabi.newpipe.fragments.BackPressable;
|
||||
import org.schabi.newpipe.fragments.list.BaseListFragment;
|
||||
import org.schabi.newpipe.ktx.AnimationType;
|
||||
import org.schabi.newpipe.ktx.ExceptionUtils;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.report.ErrorInfo;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
@ -82,7 +82,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject;
|
||||
|
||||
import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView;
|
||||
|
||||
public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.InfoItemsPage<?>>
|
||||
@ -413,7 +413,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
||||
searchEditText.setText("");
|
||||
showKeyboardSearch();
|
||||
}
|
||||
animateView(errorPanelRoot, false, 200);
|
||||
animate(errorPanelRoot, false, 200);
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,8 +644,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
||||
Log.d(TAG, "showSuggestionsPanel() called");
|
||||
}
|
||||
suggestionsPanelVisible = true;
|
||||
animateView(searchBinding.suggestionsPanel, AnimationUtils.Type.LIGHT_SLIDE_AND_ALPHA,
|
||||
true, 200);
|
||||
animate(searchBinding.suggestionsPanel, true, 200,
|
||||
AnimationType.LIGHT_SLIDE_AND_ALPHA);
|
||||
}
|
||||
|
||||
private void hideSuggestionsPanel() {
|
||||
@ -653,8 +653,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
||||
Log.d(TAG, "hideSuggestionsPanel() called");
|
||||
}
|
||||
suggestionsPanelVisible = false;
|
||||
animateView(searchBinding.suggestionsPanel, AnimationUtils.Type.LIGHT_SLIDE_AND_ALPHA,
|
||||
false, 200);
|
||||
animate(searchBinding.suggestionsPanel, false, 200,
|
||||
AnimationType.LIGHT_SLIDE_AND_ALPHA);
|
||||
}
|
||||
|
||||
private void showKeyboardSearch() {
|
||||
|
@ -20,8 +20,8 @@ import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.RelatedStreamInfo;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -123,7 +123,7 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf
|
||||
if (headerBinding != null) {
|
||||
headerBinding.getRoot().setVisibility(View.VISIBLE);
|
||||
}
|
||||
AnimationUtils.slideUp(getView(), 120, 96, 0.06f);
|
||||
ViewUtils.slideUp(requireView(), 120, 96, 0.06f);
|
||||
|
||||
if (!result.getErrors().isEmpty()) {
|
||||
showSnackBarError(result.getErrors(), UserAction.REQUESTED_STREAM,
|
||||
|
@ -13,8 +13,8 @@ import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||
@ -125,10 +125,10 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
||||
} else {
|
||||
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
|
||||
.toSeconds(state.getProgressTime()));
|
||||
AnimationUtils.animateView(itemProgressView, true, 500);
|
||||
ViewUtils.animate(itemProgressView, true, 500);
|
||||
}
|
||||
} else if (itemProgressView.getVisibility() == View.VISIBLE) {
|
||||
AnimationUtils.animateView(itemProgressView, false, 500);
|
||||
ViewUtils.animate(itemProgressView, false, 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
47
app/src/main/java/org/schabi/newpipe/ktx/TextView.kt
Normal file
47
app/src/main/java/org/schabi/newpipe/ktx/TextView.kt
Normal file
@ -0,0 +1,47 @@
|
||||
@file:JvmName("TextViewUtils")
|
||||
|
||||
package org.schabi.newpipe.ktx
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.util.Log
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import org.schabi.newpipe.MainActivity
|
||||
|
||||
private const val TAG = "TextViewUtils"
|
||||
|
||||
/**
|
||||
* Animate the text color of any view that extends [TextView] (Buttons, EditText...).
|
||||
*
|
||||
* @param duration the duration of the animation
|
||||
* @param colorStart the text color to start with
|
||||
* @param colorEnd the text color to end with
|
||||
*/
|
||||
fun TextView.animateTextColor(duration: Long, @ColorInt colorStart: Int, @ColorInt colorEnd: Int) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateTextColor() called with: " +
|
||||
"view = [" + this + "], duration = [" + duration + "], " +
|
||||
"colorStart = [" + colorStart + "], colorEnd = [" + colorEnd + "]"
|
||||
)
|
||||
}
|
||||
val viewPropertyAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorStart, colorEnd)
|
||||
viewPropertyAnimator.interpolator = FastOutSlowInInterpolator()
|
||||
viewPropertyAnimator.duration = duration
|
||||
viewPropertyAnimator.addUpdateListener { setTextColor(it.animatedValue as Int) }
|
||||
viewPropertyAnimator.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
setTextColor(colorEnd)
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator) {
|
||||
setTextColor(colorEnd)
|
||||
}
|
||||
})
|
||||
viewPropertyAnimator.start()
|
||||
}
|
324
app/src/main/java/org/schabi/newpipe/ktx/View.kt
Normal file
324
app/src/main/java/org/schabi/newpipe/ktx/View.kt
Normal file
@ -0,0 +1,324 @@
|
||||
@file:JvmName("ViewUtils")
|
||||
|
||||
package org.schabi.newpipe.ktx
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.res.ColorStateList
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.FloatRange
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import org.schabi.newpipe.MainActivity
|
||||
|
||||
private const val TAG = "ViewUtils"
|
||||
|
||||
inline var View.backgroundTintListCompat: ColorStateList?
|
||||
get() = ViewCompat.getBackgroundTintList(this)
|
||||
set(value) = ViewCompat.setBackgroundTintList(this, value)
|
||||
|
||||
/**
|
||||
* Animate the view.
|
||||
*
|
||||
* @param enterOrExit true to enter, false to exit
|
||||
* @param duration how long the animation will take, in milliseconds
|
||||
* @param animationType Type of the animation
|
||||
* @param delay how long the animation will wait to start, in milliseconds
|
||||
* @param execOnEnd runnable that will be executed when the animation ends
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun View.animate(
|
||||
enterOrExit: Boolean,
|
||||
duration: Long,
|
||||
animationType: AnimationType = AnimationType.ALPHA,
|
||||
delay: Long = 0,
|
||||
execOnEnd: Runnable? = null
|
||||
) {
|
||||
if (MainActivity.DEBUG) {
|
||||
val id = try {
|
||||
resources.getResourceEntryName(id)
|
||||
} catch (e: Exception) {
|
||||
id.toString() + ""
|
||||
}
|
||||
val msg = String.format(
|
||||
"%8s → [%s:%s] [%s %s:%s] execOnEnd=%s", enterOrExit,
|
||||
javaClass.simpleName, id, animationType, duration, delay, execOnEnd
|
||||
)
|
||||
Log.d(TAG, "animate(): $msg")
|
||||
}
|
||||
if (isVisible && enterOrExit) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(TAG, "animate(): view was already visible > view = [$this]")
|
||||
}
|
||||
animate().setListener(null).cancel()
|
||||
isVisible = true
|
||||
alpha = 1f
|
||||
execOnEnd?.run()
|
||||
return
|
||||
} else if ((isGone || isInvisible) && !enterOrExit) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(TAG, "animate(): view was already gone > view = [$this]")
|
||||
}
|
||||
animate().setListener(null).cancel()
|
||||
isGone = true
|
||||
alpha = 0f
|
||||
execOnEnd?.run()
|
||||
return
|
||||
}
|
||||
animate().setListener(null).cancel()
|
||||
isVisible = true
|
||||
when (animationType) {
|
||||
AnimationType.ALPHA -> animateAlpha(enterOrExit, duration, delay, execOnEnd)
|
||||
AnimationType.SCALE_AND_ALPHA -> animateScaleAndAlpha(enterOrExit, duration, delay, execOnEnd)
|
||||
AnimationType.LIGHT_SCALE_AND_ALPHA -> animateLightScaleAndAlpha(enterOrExit, duration, delay, execOnEnd)
|
||||
AnimationType.SLIDE_AND_ALPHA -> animateSlideAndAlpha(enterOrExit, duration, delay, execOnEnd)
|
||||
AnimationType.LIGHT_SLIDE_AND_ALPHA -> animateLightSlideAndAlpha(enterOrExit, duration, delay, execOnEnd)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the background color of a view.
|
||||
*
|
||||
* @param duration the duration of the animation
|
||||
* @param colorStart the background color to start with
|
||||
* @param colorEnd the background color to end with
|
||||
*/
|
||||
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 + "]"
|
||||
)
|
||||
}
|
||||
val empty = arrayOf(IntArray(0))
|
||||
val viewPropertyAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorStart, colorEnd)
|
||||
viewPropertyAnimator.interpolator = FastOutSlowInInterpolator()
|
||||
viewPropertyAnimator.duration = duration
|
||||
viewPropertyAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
backgroundTintListCompat = ColorStateList(empty, intArrayOf(animation.animatedValue as Int))
|
||||
}
|
||||
viewPropertyAnimator.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
backgroundTintListCompat = ColorStateList(empty, intArrayOf(colorEnd))
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator) {
|
||||
onAnimationEnd(animation)
|
||||
}
|
||||
})
|
||||
viewPropertyAnimator.start()
|
||||
}
|
||||
|
||||
fun View.animateHeight(duration: Long, targetHeight: Int): ValueAnimator {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateHeight: duration = [" + duration + "], " +
|
||||
"from " + height + " to → " + targetHeight + " in: " + this
|
||||
)
|
||||
}
|
||||
val animator = ValueAnimator.ofFloat(height.toFloat(), targetHeight.toFloat())
|
||||
animator.interpolator = FastOutSlowInInterpolator()
|
||||
animator.duration = duration
|
||||
animator.addUpdateListener { animation: ValueAnimator ->
|
||||
val value = animation.animatedValue as Float
|
||||
layoutParams.height = value.toInt()
|
||||
requestLayout()
|
||||
}
|
||||
animator.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
layoutParams.height = targetHeight
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator) {
|
||||
layoutParams.height = targetHeight
|
||||
requestLayout()
|
||||
}
|
||||
})
|
||||
animator.start()
|
||||
return animator
|
||||
}
|
||||
|
||||
fun View.animateRotation(duration: Long, targetRotation: Int) {
|
||||
if (MainActivity.DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"animateRotation: duration = [" + duration + "], " +
|
||||
"from " + rotation + " to → " + targetRotation + " in: " + this
|
||||
)
|
||||
}
|
||||
animate().setListener(null).cancel()
|
||||
animate()
|
||||
.rotation(targetRotation.toFloat()).setDuration(duration)
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationCancel(animation: Animator) {
|
||||
rotation = targetRotation.toFloat()
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
rotation = targetRotation.toFloat()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun View.animateAlpha(enterOrExit: Boolean, duration: Long, delay: Long, execOnEnd: Runnable?) {
|
||||
if (enterOrExit) {
|
||||
animate().setInterpolator(FastOutSlowInInterpolator()).alpha(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
animate().setInterpolator(FastOutSlowInInterpolator()).alpha(0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isGone = true
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.animateScaleAndAlpha(enterOrExit: Boolean, duration: Long, delay: Long, execOnEnd: Runnable?) {
|
||||
if (enterOrExit) {
|
||||
scaleX = .8f
|
||||
scaleY = .8f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(1f).scaleX(1f).scaleY(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
scaleX = 1f
|
||||
scaleY = 1f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(0f).scaleX(.8f).scaleY(.8f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isGone = true
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.animateLightScaleAndAlpha(enterOrExit: Boolean, duration: Long, delay: Long, execOnEnd: Runnable?) {
|
||||
if (enterOrExit) {
|
||||
alpha = .5f
|
||||
scaleX = .95f
|
||||
scaleY = .95f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(1f).scaleX(1f).scaleY(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
alpha = 1f
|
||||
scaleX = 1f
|
||||
scaleY = 1f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(0f).scaleX(.95f).scaleY(.95f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isGone = true
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.animateSlideAndAlpha(enterOrExit: Boolean, duration: Long, delay: Long, execOnEnd: Runnable?) {
|
||||
if (enterOrExit) {
|
||||
translationY = -height.toFloat()
|
||||
alpha = 0f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator()).alpha(1f).translationY(0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(0f).translationY(-height.toFloat())
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isGone = true
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun View.animateLightSlideAndAlpha(enterOrExit: Boolean, duration: Long, delay: Long, execOnEnd: Runnable?) {
|
||||
if (enterOrExit) {
|
||||
translationY = -height / 2.0f
|
||||
alpha = 0f
|
||||
animate()
|
||||
.setInterpolator(FastOutSlowInInterpolator()).alpha(1f).translationY(0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
animate().setInterpolator(FastOutSlowInInterpolator())
|
||||
.alpha(0f).translationY(-height / 2.0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
isGone = true
|
||||
execOnEnd?.run()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.slideUp(duration: Long, delay: Long, @FloatRange(from = 0.0, to = 1.0) translationPercent: Float) {
|
||||
val newTranslationY = (resources.displayMetrics.heightPixels * translationPercent).toInt()
|
||||
animate().setListener(null).cancel()
|
||||
alpha = 0f
|
||||
translationY = newTranslationY.toFloat()
|
||||
visibility = View.VISIBLE
|
||||
animate()
|
||||
.alpha(1f)
|
||||
.translationY(0f)
|
||||
.setStartDelay(delay)
|
||||
.setDuration(duration)
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.start()
|
||||
}
|
||||
|
||||
enum class AnimationType {
|
||||
ALPHA, SCALE_AND_ALPHA, LIGHT_SCALE_AND_ALPHA, SLIDE_AND_ALPHA, LIGHT_SLIDE_AND_ALPHA
|
||||
}
|
@ -24,7 +24,7 @@ import org.schabi.newpipe.databinding.PignateFooterBinding;
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||
import org.schabi.newpipe.fragments.list.ListViewContract;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
/**
|
||||
* This fragment is design to be used with persistent data such as
|
||||
@ -185,10 +185,10 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
if (itemsList != null) {
|
||||
animateView(itemsList, false, 200);
|
||||
animate(itemsList, false, 200);
|
||||
}
|
||||
if (headerRootBinding != null) {
|
||||
animateView(headerRootBinding.getRoot(), false, 200);
|
||||
animate(headerRootBinding.getRoot(), false, 200);
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,10 +196,10 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||
public void hideLoading() {
|
||||
super.hideLoading();
|
||||
if (itemsList != null) {
|
||||
animateView(itemsList, true, 200);
|
||||
animate(itemsList, true, 200);
|
||||
}
|
||||
if (headerRootBinding != null) {
|
||||
animateView(headerRootBinding.getRoot(), true, 200);
|
||||
animate(headerRootBinding.getRoot(), true, 200);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,10 +209,10 @@ public abstract class BaseLocalListFragment<I, N> extends BaseStateFragment<I>
|
||||
showListFooter(false);
|
||||
|
||||
if (itemsList != null) {
|
||||
animateView(itemsList, false, 200);
|
||||
animate(itemsList, false, 200);
|
||||
}
|
||||
if (headerRootBinding != null) {
|
||||
animateView(headerRootBinding.getRoot(), false, 200);
|
||||
animate(headerRootBinding.getRoot(), false, 200);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,9 @@ import org.schabi.newpipe.database.feed.model.FeedGroupEntity
|
||||
import org.schabi.newpipe.databinding.ErrorRetryBinding
|
||||
import org.schabi.newpipe.databinding.FragmentFeedBinding
|
||||
import org.schabi.newpipe.fragments.list.BaseListFragment
|
||||
import org.schabi.newpipe.ktx.animate
|
||||
import org.schabi.newpipe.local.feed.service.FeedLoadService
|
||||
import org.schabi.newpipe.report.UserAction
|
||||
import org.schabi.newpipe.util.AnimationUtils.animateView
|
||||
import org.schabi.newpipe.util.Localization
|
||||
import java.util.Calendar
|
||||
|
||||
@ -180,50 +180,50 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
override fun showLoading() {
|
||||
animateView(feedBinding.refreshRootView, false, 0)
|
||||
animateView(feedBinding.itemsList, false, 0)
|
||||
feedBinding.refreshRootView.animate(false, 0)
|
||||
feedBinding.itemsList.animate(false, 0)
|
||||
|
||||
animateView(feedBinding.loadingProgressBar, true, 200)
|
||||
animateView(feedBinding.loadingProgressText, true, 200)
|
||||
feedBinding.loadingProgressBar.animate(true, 200)
|
||||
feedBinding.loadingProgressText.animate(true, 200)
|
||||
|
||||
animateView(feedBinding.emptyStateView.root, false, 0)
|
||||
animateView(errorBinding.root, false, 0)
|
||||
feedBinding.emptyStateView.root.animate(false, 0)
|
||||
errorBinding.root.animate(false, 0)
|
||||
}
|
||||
|
||||
override fun hideLoading() {
|
||||
animateView(feedBinding.refreshRootView, true, 200)
|
||||
animateView(feedBinding.itemsList, true, 300)
|
||||
feedBinding.refreshRootView.animate(true, 200)
|
||||
feedBinding.itemsList.animate(true, 300)
|
||||
|
||||
animateView(feedBinding.loadingProgressBar, false, 0)
|
||||
animateView(feedBinding.loadingProgressText, false, 0)
|
||||
feedBinding.loadingProgressBar.animate(false, 0)
|
||||
feedBinding.loadingProgressText.animate(false, 0)
|
||||
|
||||
animateView(feedBinding.emptyStateView.root, false, 0)
|
||||
animateView(errorBinding.root, false, 0)
|
||||
feedBinding.emptyStateView.root.animate(false, 0)
|
||||
errorBinding.root.animate(false, 0)
|
||||
feedBinding.swiperefresh.isRefreshing = false
|
||||
}
|
||||
|
||||
override fun showEmptyState() {
|
||||
animateView(feedBinding.refreshRootView, true, 200)
|
||||
animateView(feedBinding.itemsList, false, 0)
|
||||
feedBinding.refreshRootView.animate(true, 200)
|
||||
feedBinding.itemsList.animate(false, 0)
|
||||
|
||||
animateView(feedBinding.loadingProgressBar, false, 0)
|
||||
animateView(feedBinding.loadingProgressText, false, 0)
|
||||
feedBinding.loadingProgressBar.animate(false, 0)
|
||||
feedBinding.loadingProgressText.animate(false, 0)
|
||||
|
||||
animateView(feedBinding.emptyStateView.root, true, 800)
|
||||
animateView(errorBinding.root, false, 0)
|
||||
feedBinding.emptyStateView.root.animate(true, 800)
|
||||
errorBinding.root.animate(false, 0)
|
||||
}
|
||||
|
||||
override fun showError(message: String, showRetryButton: Boolean) {
|
||||
infoListAdapter.clearStreamItemList()
|
||||
animateView(feedBinding.refreshRootView, false, 120)
|
||||
animateView(feedBinding.itemsList, false, 120)
|
||||
feedBinding.refreshRootView.animate(false, 120)
|
||||
feedBinding.itemsList.animate(false, 120)
|
||||
|
||||
animateView(feedBinding.loadingProgressBar, false, 120)
|
||||
animateView(feedBinding.loadingProgressText, false, 120)
|
||||
feedBinding.loadingProgressBar.animate(false, 120)
|
||||
feedBinding.loadingProgressText.animate(false, 120)
|
||||
|
||||
errorBinding.errorMessageView.text = message
|
||||
animateView(errorBinding.errorButtonRetry, showRetryButton, if (showRetryButton) 600 else 0)
|
||||
animateView(errorBinding.root, true, 300)
|
||||
errorBinding.errorButtonRetry.animate(showRetryButton, if (showRetryButton) 600 else 0)
|
||||
errorBinding.root.animate(true, 300)
|
||||
}
|
||||
|
||||
override fun handleResult(result: FeedState) {
|
||||
|
@ -12,9 +12,9 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.database.LocalItem;
|
||||
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||
@ -117,10 +117,10 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
|
||||
} else {
|
||||
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
|
||||
.toSeconds(item.getProgressTime()));
|
||||
AnimationUtils.animateView(itemProgressView, true, 500);
|
||||
ViewUtils.animate(itemProgressView, true, 500);
|
||||
}
|
||||
} else if (itemProgressView.getVisibility() == View.VISIBLE) {
|
||||
AnimationUtils.animateView(itemProgressView, false, 500);
|
||||
ViewUtils.animate(itemProgressView, false, 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,9 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.database.LocalItem;
|
||||
import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||
@ -148,10 +148,10 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
||||
} else {
|
||||
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
|
||||
.toSeconds(item.getProgressTime()));
|
||||
AnimationUtils.animateView(itemProgressView, true, 500);
|
||||
ViewUtils.animate(itemProgressView, true, 500);
|
||||
}
|
||||
} else if (itemProgressView.getVisibility() == View.VISIBLE) {
|
||||
AnimationUtils.animateView(itemProgressView, false, 500);
|
||||
ViewUtils.animate(itemProgressView, false, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,14 +58,14 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import icepick.State;
|
||||
import io.reactivex.rxjava3.core.Flowable;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.core.Flowable;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject;
|
||||
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
|
||||
// Save the list 10 seconds after the last change occurred
|
||||
@ -201,8 +201,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
||||
public void showLoading() {
|
||||
super.showLoading();
|
||||
if (headerBinding != null) {
|
||||
animateView(headerBinding.getRoot(), false, 200);
|
||||
animateView(playlistControlBinding.getRoot(), false, 200);
|
||||
animate(headerBinding.getRoot(), false, 200);
|
||||
animate(playlistControlBinding.getRoot(), false, 200);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,8 +210,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
||||
public void hideLoading() {
|
||||
super.hideLoading();
|
||||
if (headerBinding != null) {
|
||||
animateView(headerBinding.getRoot(), true, 200);
|
||||
animateView(playlistControlBinding.getRoot(), true, 200);
|
||||
animate(headerBinding.getRoot(), true, 200);
|
||||
animate(playlistControlBinding.getRoot(), true, 200);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ import org.schabi.newpipe.databinding.DialogTitleBinding
|
||||
import org.schabi.newpipe.databinding.FragmentSubscriptionBinding
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem
|
||||
import org.schabi.newpipe.fragments.BaseStateFragment
|
||||
import org.schabi.newpipe.ktx.animate
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionViewModel.SubscriptionState
|
||||
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog
|
||||
import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialog
|
||||
@ -56,7 +57,6 @@ import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
|
||||
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
|
||||
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
|
||||
import org.schabi.newpipe.report.UserAction
|
||||
import org.schabi.newpipe.util.AnimationUtils.animateView
|
||||
import org.schabi.newpipe.util.FilePickerActivityHelper
|
||||
import org.schabi.newpipe.util.NavigationHelper
|
||||
import org.schabi.newpipe.util.OnClickGesture
|
||||
@ -407,12 +407,12 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||
|
||||
override fun showLoading() {
|
||||
super.showLoading()
|
||||
animateView(binding.itemsList, false, 100)
|
||||
binding.itemsList.animate(false, 100)
|
||||
}
|
||||
|
||||
override fun hideLoading() {
|
||||
super.hideLoading()
|
||||
animateView(binding.itemsList, true, 200)
|
||||
binding.itemsList.animate(true, 200)
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
@ -17,7 +17,7 @@ import kotlinx.android.synthetic.main.feed_import_export_group.import_from_optio
|
||||
import org.schabi.newpipe.R
|
||||
import org.schabi.newpipe.extractor.NewPipe
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException
|
||||
import org.schabi.newpipe.util.AnimationUtils
|
||||
import org.schabi.newpipe.ktx.animateRotation
|
||||
import org.schabi.newpipe.util.ServiceHelper
|
||||
import org.schabi.newpipe.util.ThemeHelper
|
||||
import org.schabi.newpipe.views.CollapsibleView
|
||||
@ -49,8 +49,7 @@ class FeedImportExportItem(
|
||||
|
||||
expandIconListener?.let { viewHolder.import_export_options.removeListener(it) }
|
||||
expandIconListener = CollapsibleView.StateListener { newState ->
|
||||
AnimationUtils.animateRotation(
|
||||
viewHolder.import_export_expand_icon,
|
||||
viewHolder.import_export_expand_icon.animateRotation(
|
||||
250, if (newState == CollapsibleView.COLLAPSED) 0 else 180
|
||||
)
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import kotlinx.android.synthetic.main.picker_subscription_item.*
|
||||
import kotlinx.android.synthetic.main.picker_subscription_item.view.*
|
||||
import org.schabi.newpipe.R
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
||||
import org.schabi.newpipe.util.AnimationUtils
|
||||
import org.schabi.newpipe.util.AnimationUtils.animateView
|
||||
import org.schabi.newpipe.ktx.AnimationType
|
||||
import org.schabi.newpipe.ktx.animate
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants
|
||||
|
||||
data class PickerSubscriptionItem(
|
||||
@ -41,9 +41,6 @@ data class PickerSubscriptionItem(
|
||||
|
||||
fun updateSelected(containerView: View, isSelected: Boolean) {
|
||||
this.isSelected = isSelected
|
||||
animateView(
|
||||
containerView.selected_highlight,
|
||||
AnimationUtils.Type.LIGHT_SCALE_AND_ALPHA, isSelected, 150
|
||||
)
|
||||
containerView.selected_highlight.animate(isSelected, 150, AnimationType.LIGHT_SCALE_AND_ALPHA)
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
|
||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||
import org.schabi.newpipe.info_list.StreamSegmentAdapter;
|
||||
import org.schabi.newpipe.ktx.AnimationType;
|
||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.player.MainPlayer.PlayerType;
|
||||
import org.schabi.newpipe.player.event.PlayerEventListener;
|
||||
@ -116,7 +117,6 @@ import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback;
|
||||
import org.schabi.newpipe.player.resolver.AudioPlaybackResolver;
|
||||
import org.schabi.newpipe.player.resolver.MediaSourceTag;
|
||||
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.KoreUtil;
|
||||
@ -150,6 +150,8 @@ import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
|
||||
import static com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateRotation;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_CLOSE;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD;
|
||||
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND;
|
||||
@ -176,9 +178,6 @@ import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlayerTypeFr
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePopupLayoutParamsFromPrefs;
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.retrieveSeekDurationFromPreferences;
|
||||
import static org.schabi.newpipe.player.helper.PlayerHelper.savePlaybackParametersToPrefs;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.Type.SLIDE_AND_ALPHA;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateRotation;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex;
|
||||
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
|
||||
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||
@ -1560,8 +1559,8 @@ public final class Player implements
|
||||
}
|
||||
|
||||
showControls(0);
|
||||
animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, true,
|
||||
DEFAULT_CONTROLS_DURATION);
|
||||
animate(binding.currentDisplaySeek, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
}
|
||||
|
||||
@Override // seekbar listener
|
||||
@ -1576,7 +1575,7 @@ public final class Player implements
|
||||
}
|
||||
|
||||
binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress()));
|
||||
animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200);
|
||||
animate(binding.currentDisplaySeek, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
|
||||
if (currentState == STATE_PAUSED_SEEK) {
|
||||
changeState(STATE_BUFFERING);
|
||||
@ -1682,8 +1681,8 @@ public final class Player implements
|
||||
: DPAD_CONTROLS_HIDE_TIME;
|
||||
|
||||
showHideShadow(true, DEFAULT_CONTROLS_DURATION);
|
||||
animateView(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, 0,
|
||||
() -> hideControls(DEFAULT_CONTROLS_DURATION, hideTime));
|
||||
animate(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.ALPHA, 0, () -> hideControls(DEFAULT_CONTROLS_DURATION, hideTime));
|
||||
}
|
||||
|
||||
public void showControls(final long duration) {
|
||||
@ -1694,7 +1693,7 @@ public final class Player implements
|
||||
showSystemUIPartially();
|
||||
controlsVisibilityHandler.removeCallbacksAndMessages(null);
|
||||
showHideShadow(true, duration);
|
||||
animateView(binding.playbackControlRoot, true, duration);
|
||||
animate(binding.playbackControlRoot, true, duration);
|
||||
}
|
||||
|
||||
public void hideControls(final long duration, final long delay) {
|
||||
@ -1708,14 +1707,14 @@ public final class Player implements
|
||||
controlsVisibilityHandler.removeCallbacksAndMessages(null);
|
||||
controlsVisibilityHandler.postDelayed(() -> {
|
||||
showHideShadow(false, duration);
|
||||
animateView(binding.playbackControlRoot, false, duration, 0,
|
||||
this::hideSystemUIIfNeeded);
|
||||
animate(binding.playbackControlRoot, false, duration, AnimationType.ALPHA,
|
||||
0, this::hideSystemUIIfNeeded);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
private void showHideShadow(final boolean show, final long duration) {
|
||||
animateView(binding.playerTopShadow, show, duration, 0, null);
|
||||
animateView(binding.playerBottomShadow, show, duration, 0, null);
|
||||
animate(binding.playerTopShadow, show, duration, AnimationType.ALPHA, 0, null);
|
||||
animate(binding.playerBottomShadow, show, duration, AnimationType.ALPHA, 0, null);
|
||||
}
|
||||
|
||||
private void showOrHideButtons() {
|
||||
@ -1913,15 +1912,15 @@ public final class Player implements
|
||||
}
|
||||
|
||||
controlsVisibilityHandler.removeCallbacksAndMessages(null);
|
||||
animateView(binding.playbackControlRoot, false, DEFAULT_CONTROLS_DURATION);
|
||||
animate(binding.playbackControlRoot, false, DEFAULT_CONTROLS_DURATION);
|
||||
|
||||
binding.playbackSeekBar.setEnabled(false);
|
||||
binding.playbackSeekBar.getThumb()
|
||||
.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
|
||||
|
||||
binding.loadingPanel.setBackgroundColor(Color.BLACK);
|
||||
animateView(binding.loadingPanel, true, 0);
|
||||
animateView(binding.surfaceForeground, true, 100);
|
||||
animate(binding.loadingPanel, true, 0);
|
||||
animate(binding.surfaceForeground, true, 100);
|
||||
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
animatePlayButtons(false, 100);
|
||||
@ -1948,9 +1947,9 @@ public final class Player implements
|
||||
|
||||
binding.loadingPanel.setVisibility(View.GONE);
|
||||
|
||||
animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200);
|
||||
animate(binding.currentDisplaySeek, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
|
||||
animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0,
|
||||
animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0,
|
||||
() -> {
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp);
|
||||
animatePlayButtons(true, 200);
|
||||
@ -1991,7 +1990,7 @@ public final class Player implements
|
||||
showControls(400);
|
||||
binding.loadingPanel.setVisibility(View.GONE);
|
||||
|
||||
animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0,
|
||||
animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0,
|
||||
() -> {
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
animatePlayButtons(true, 200);
|
||||
@ -2029,7 +2028,7 @@ public final class Player implements
|
||||
Log.d(TAG, "onCompleted() called");
|
||||
}
|
||||
|
||||
animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0,
|
||||
animate(binding.playPauseButton, false, 0, AnimationType.SCALE_AND_ALPHA, 0,
|
||||
() -> {
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_replay_white_24dp);
|
||||
animatePlayButtons(true, DEFAULT_CONTROLS_DURATION);
|
||||
@ -2051,13 +2050,13 @@ public final class Player implements
|
||||
}
|
||||
|
||||
showControls(500);
|
||||
animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200);
|
||||
animate(binding.currentDisplaySeek, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
binding.loadingPanel.setVisibility(View.GONE);
|
||||
animateView(binding.surfaceForeground, true, 100);
|
||||
animate(binding.surfaceForeground, true, 100);
|
||||
}
|
||||
|
||||
private void animatePlayButtons(final boolean show, final int duration) {
|
||||
animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration);
|
||||
animate(binding.playPauseButton, show, duration, AnimationType.SCALE_AND_ALPHA);
|
||||
|
||||
boolean showQueueButtons = show;
|
||||
if (playQueue == null) {
|
||||
@ -2065,18 +2064,18 @@ public final class Player implements
|
||||
}
|
||||
|
||||
if (!showQueueButtons || playQueue.getIndex() > 0) {
|
||||
animateView(
|
||||
animate(
|
||||
binding.playPreviousButton,
|
||||
AnimationUtils.Type.SCALE_AND_ALPHA,
|
||||
showQueueButtons,
|
||||
duration);
|
||||
duration,
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
}
|
||||
if (!showQueueButtons || playQueue.getIndex() + 1 < playQueue.getStreams().size()) {
|
||||
animateView(
|
||||
animate(
|
||||
binding.playNextButton,
|
||||
AnimationUtils.Type.SCALE_AND_ALPHA,
|
||||
showQueueButtons,
|
||||
duration);
|
||||
duration,
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
@ -2274,7 +2273,7 @@ public final class Player implements
|
||||
@Override
|
||||
public void onRenderedFirstFrame() {
|
||||
//TODO check if this causes black screen when switching to fullscreen
|
||||
animateView(binding.surfaceForeground, false, DEFAULT_CONTROLS_DURATION);
|
||||
animate(binding.surfaceForeground, false, DEFAULT_CONTROLS_DURATION);
|
||||
}
|
||||
//endregion
|
||||
|
||||
@ -2871,8 +2870,8 @@ public final class Player implements
|
||||
|
||||
hideControls(0, 0);
|
||||
binding.itemsListPanel.requestFocus();
|
||||
animateView(binding.itemsListPanel, SLIDE_AND_ALPHA, true,
|
||||
DEFAULT_CONTROLS_DURATION);
|
||||
animate(binding.itemsListPanel, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SLIDE_AND_ALPHA);
|
||||
|
||||
binding.itemsList.scrollToPosition(playQueue.getIndex());
|
||||
}
|
||||
@ -2905,8 +2904,8 @@ public final class Player implements
|
||||
|
||||
hideControls(0, 0);
|
||||
binding.itemsListPanel.requestFocus();
|
||||
animateView(binding.itemsListPanel, SLIDE_AND_ALPHA, true,
|
||||
DEFAULT_CONTROLS_DURATION);
|
||||
animate(binding.itemsListPanel, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SLIDE_AND_ALPHA);
|
||||
|
||||
final int adapterPosition = getNearestStreamSegmentPosition(simpleExoPlayer
|
||||
.getCurrentPosition());
|
||||
@ -2942,8 +2941,8 @@ public final class Player implements
|
||||
itemTouchHelper.attachToRecyclerView(null);
|
||||
}
|
||||
|
||||
animateView(binding.itemsListPanel, SLIDE_AND_ALPHA, false,
|
||||
DEFAULT_CONTROLS_DURATION, 0, () -> {
|
||||
animate(binding.itemsListPanel, false, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SLIDE_AND_ALPHA, 0, () -> {
|
||||
// Even when queueLayout is GONE it receives touch events
|
||||
// and ruins normal behavior of the app. This line fixes it
|
||||
binding.itemsListPanel.setTranslationY(
|
||||
@ -3451,18 +3450,19 @@ public final class Player implements
|
||||
if (currentState != STATE_COMPLETED) {
|
||||
controlsVisibilityHandler.removeCallbacksAndMessages(null);
|
||||
showHideShadow(true, DEFAULT_CONTROLS_DURATION);
|
||||
animateView(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, 0, () -> {
|
||||
if (currentState == STATE_PLAYING && !isSomePopupMenuVisible) {
|
||||
if (v.getId() == binding.playPauseButton.getId()
|
||||
// Hide controls in fullscreen immediately
|
||||
|| (v.getId() == binding.screenRotationButton.getId()
|
||||
&& isFullscreen)) {
|
||||
hideControls(0, 0);
|
||||
} else {
|
||||
hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
}
|
||||
});
|
||||
animate(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.ALPHA, 0, () -> {
|
||||
if (currentState == STATE_PLAYING && !isSomePopupMenuVisible) {
|
||||
if (v.getId() == binding.playPauseButton.getId()
|
||||
// Hide controls in fullscreen immediately
|
||||
|| (v.getId() == binding.screenRotationButton.getId()
|
||||
&& isFullscreen)) {
|
||||
hideControls(0, 0);
|
||||
} else {
|
||||
hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -3531,9 +3531,8 @@ public final class Player implements
|
||||
|
||||
animateRotation(binding.moreOptionsButton, DEFAULT_CONTROLS_DURATION,
|
||||
isMoreControlsVisible ? 0 : 180);
|
||||
animateView(binding.secondaryControls, SLIDE_AND_ALPHA, !isMoreControlsVisible,
|
||||
DEFAULT_CONTROLS_DURATION, 0,
|
||||
() -> {
|
||||
animate(binding.secondaryControls, !isMoreControlsVisible, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SLIDE_AND_ALPHA, 0, () -> {
|
||||
// Fix for a ripple effect on background drawable.
|
||||
// When view returns from GONE state it takes more milliseconds than returning
|
||||
// from INVISIBLE state. And the delay makes ripple background end to fast
|
||||
|
@ -7,11 +7,11 @@ import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewConfiguration
|
||||
import org.schabi.newpipe.ktx.animate
|
||||
import org.schabi.newpipe.player.MainPlayer
|
||||
import org.schabi.newpipe.player.Player
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper.savePopupPositionAndSizeToPrefs
|
||||
import org.schabi.newpipe.util.AnimationUtils
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.hypot
|
||||
import kotlin.math.max
|
||||
@ -364,7 +364,7 @@ abstract class BasePlayerGestureListener(
|
||||
}
|
||||
|
||||
if (!isMovingInPopup) {
|
||||
AnimationUtils.animateView(player.closeOverlayButton, true, 200)
|
||||
player.closeOverlayButton.animate(true, 200)
|
||||
}
|
||||
|
||||
isMovingInPopup = true
|
||||
|
@ -17,11 +17,12 @@ import org.schabi.newpipe.player.MainPlayer;
|
||||
import org.schabi.newpipe.player.Player;
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||
|
||||
import static org.schabi.newpipe.player.Player.STATE_PLAYING;
|
||||
import static org.schabi.newpipe.ktx.AnimationType.ALPHA;
|
||||
import static org.schabi.newpipe.ktx.AnimationType.SCALE_AND_ALPHA;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_DURATION;
|
||||
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_HIDE_TIME;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA;
|
||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||
import static org.schabi.newpipe.player.Player.STATE_PLAYING;
|
||||
|
||||
/**
|
||||
* GestureListener for the player
|
||||
@ -123,11 +124,11 @@ public class PlayerGestureListener
|
||||
final View closingOverlayView = player.getClosingOverlayView();
|
||||
if (player.isInsideClosingRadius(movingEvent)) {
|
||||
if (closingOverlayView.getVisibility() == View.GONE) {
|
||||
animateView(closingOverlayView, true, 250);
|
||||
animate(closingOverlayView, true, 250);
|
||||
}
|
||||
} else {
|
||||
if (closingOverlayView.getVisibility() == View.VISIBLE) {
|
||||
animateView(closingOverlayView, false, 0);
|
||||
animate(closingOverlayView, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,7 +154,7 @@ public class PlayerGestureListener
|
||||
);
|
||||
|
||||
if (player.getVolumeRelativeLayout().getVisibility() != View.VISIBLE) {
|
||||
animateView(player.getVolumeRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
||||
animate(player.getVolumeRelativeLayout(), true, 200, SCALE_AND_ALPHA);
|
||||
}
|
||||
if (player.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||
player.getBrightnessRelativeLayout().setVisibility(View.GONE);
|
||||
@ -195,7 +196,7 @@ public class PlayerGestureListener
|
||||
);
|
||||
|
||||
if (player.getBrightnessRelativeLayout().getVisibility() != View.VISIBLE) {
|
||||
animateView(player.getBrightnessRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
||||
animate(player.getBrightnessRelativeLayout(), true, 200, SCALE_AND_ALPHA);
|
||||
}
|
||||
if (player.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||
player.getVolumeRelativeLayout().setVisibility(View.GONE);
|
||||
@ -215,21 +216,18 @@ public class PlayerGestureListener
|
||||
}
|
||||
|
||||
if (player.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||
animateView(player.getVolumeRelativeLayout(), SCALE_AND_ALPHA,
|
||||
false, 200, 200);
|
||||
animate(player.getVolumeRelativeLayout(), false, 200, SCALE_AND_ALPHA,
|
||||
200);
|
||||
}
|
||||
if (player.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||
animateView(player.getBrightnessRelativeLayout(), SCALE_AND_ALPHA,
|
||||
false, 200, 200);
|
||||
animate(player.getBrightnessRelativeLayout(), false, 200, SCALE_AND_ALPHA,
|
||||
200);
|
||||
}
|
||||
|
||||
if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
|
||||
player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
} else {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
|
||||
player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
@ -237,10 +235,10 @@ public class PlayerGestureListener
|
||||
if (player.isInsideClosingRadius(event)) {
|
||||
player.closePopup();
|
||||
} else {
|
||||
animateView(player.getClosingOverlayView(), false, 0);
|
||||
animate(player.getClosingOverlayView(), false, 0);
|
||||
|
||||
if (!player.isPopupClosing()) {
|
||||
animateView(player.getCloseOverlayButton(), false, 200);
|
||||
animate(player.getCloseOverlayButton(), false, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,8 +253,8 @@ public class PlayerGestureListener
|
||||
player.getLoadingPanel().setVisibility(View.GONE);
|
||||
|
||||
player.hideControls(0, 0);
|
||||
animateView(player.getCurrentDisplaySeek(), false, 0, 0);
|
||||
animateView(player.getResizingIndicator(), true, 200, 0);
|
||||
animate(player.getCurrentDisplaySeek(), false, 0, ALPHA, 0);
|
||||
animate(player.getResizingIndicator(), true, 200, ALPHA, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -264,7 +262,7 @@ public class PlayerGestureListener
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onPopupResizingEnd called");
|
||||
}
|
||||
animateView(player.getResizingIndicator(), false, 100, 0);
|
||||
animate(player.getResizingIndicator(), false, 100, ALPHA, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,478 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
|
||||
* AnimationUtils.java is part of NewPipe
|
||||
*
|
||||
* License: GPL-3.0+
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.schabi.newpipe.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
|
||||
public final class AnimationUtils {
|
||||
private static final String TAG = "AnimationUtils";
|
||||
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||
|
||||
private AnimationUtils() { }
|
||||
|
||||
public static void animateView(final View view, final boolean enterOrExit,
|
||||
final long duration) {
|
||||
animateView(view, Type.ALPHA, enterOrExit, duration, 0, null);
|
||||
}
|
||||
|
||||
public static void animateView(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay) {
|
||||
animateView(view, Type.ALPHA, enterOrExit, duration, delay, null);
|
||||
}
|
||||
|
||||
public static void animateView(final View view, final boolean enterOrExit, final long duration,
|
||||
final long delay, final Runnable execOnEnd) {
|
||||
animateView(view, Type.ALPHA, enterOrExit, duration, delay, execOnEnd);
|
||||
}
|
||||
|
||||
public static void animateView(final View view, final Type animationType,
|
||||
final boolean enterOrExit, final long duration) {
|
||||
animateView(view, animationType, enterOrExit, duration, 0, null);
|
||||
}
|
||||
|
||||
public static void animateView(final View view, final Type animationType,
|
||||
final boolean enterOrExit, final long duration,
|
||||
final long delay) {
|
||||
animateView(view, animationType, enterOrExit, duration, delay, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the view.
|
||||
*
|
||||
* @param view view that will be animated
|
||||
* @param animationType {@link Type} of the animation
|
||||
* @param enterOrExit true to enter, false to exit
|
||||
* @param duration how long the animation will take, in milliseconds
|
||||
* @param delay how long the animation will wait to start, in milliseconds
|
||||
* @param execOnEnd runnable that will be executed when the animation ends
|
||||
*/
|
||||
public static void animateView(final View view, final Type animationType,
|
||||
final boolean enterOrExit, final long duration,
|
||||
final long delay, final Runnable execOnEnd) {
|
||||
if (DEBUG) {
|
||||
String id;
|
||||
try {
|
||||
id = view.getResources().getResourceEntryName(view.getId());
|
||||
} catch (final Exception e) {
|
||||
id = view.getId() + "";
|
||||
}
|
||||
|
||||
final String msg = String.format("%8s → [%s:%s] [%s %s:%s] execOnEnd=%s", enterOrExit,
|
||||
view.getClass().getSimpleName(), id, animationType, duration, delay, execOnEnd);
|
||||
Log.d(TAG, "animateView()" + msg);
|
||||
}
|
||||
|
||||
if (view.getVisibility() == View.VISIBLE && enterOrExit) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateView() view was already visible > view = [" + view + "]");
|
||||
}
|
||||
view.animate().setListener(null).cancel();
|
||||
view.setVisibility(View.VISIBLE);
|
||||
view.setAlpha(1f);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
return;
|
||||
} else if ((view.getVisibility() == View.GONE || view.getVisibility() == View.INVISIBLE)
|
||||
&& !enterOrExit) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateView() view was already gone > view = [" + view + "]");
|
||||
}
|
||||
view.animate().setListener(null).cancel();
|
||||
view.setVisibility(View.GONE);
|
||||
view.setAlpha(0f);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
view.animate().setListener(null).cancel();
|
||||
view.setVisibility(View.VISIBLE);
|
||||
|
||||
switch (animationType) {
|
||||
case ALPHA:
|
||||
animateAlpha(view, enterOrExit, duration, delay, execOnEnd);
|
||||
break;
|
||||
case SCALE_AND_ALPHA:
|
||||
animateScaleAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
|
||||
break;
|
||||
case LIGHT_SCALE_AND_ALPHA:
|
||||
animateLightScaleAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
|
||||
break;
|
||||
case SLIDE_AND_ALPHA:
|
||||
animateSlideAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
|
||||
break;
|
||||
case LIGHT_SLIDE_AND_ALPHA:
|
||||
animateLightSlideAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the background color of a view.
|
||||
*
|
||||
* @param view the view to animate
|
||||
* @param duration the duration of the animation
|
||||
* @param colorStart the background color to start with
|
||||
* @param colorEnd the background color to end with
|
||||
*/
|
||||
public static void animateBackgroundColor(final View view, final long duration,
|
||||
@ColorInt final int colorStart,
|
||||
@ColorInt final int colorEnd) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateBackgroundColor() called with: "
|
||||
+ "view = [" + view + "], duration = [" + duration + "], "
|
||||
+ "colorStart = [" + colorStart + "], colorEnd = [" + colorEnd + "]");
|
||||
}
|
||||
|
||||
final int[][] empty = {new int[0]};
|
||||
final ValueAnimator viewPropertyAnimator = ValueAnimator
|
||||
.ofObject(new ArgbEvaluator(), colorStart, colorEnd);
|
||||
viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator());
|
||||
viewPropertyAnimator.setDuration(duration);
|
||||
viewPropertyAnimator.addUpdateListener(animation ->
|
||||
ViewCompat.setBackgroundTintList(view,
|
||||
new ColorStateList(empty, new int[]{(int) animation.getAnimatedValue()})));
|
||||
viewPropertyAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
ViewCompat.setBackgroundTintList(view,
|
||||
new ColorStateList(empty, new int[]{colorEnd}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(final Animator animation) {
|
||||
onAnimationEnd(animation);
|
||||
}
|
||||
});
|
||||
viewPropertyAnimator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the text color of any view that extends {@link TextView} (Buttons, EditText...).
|
||||
*
|
||||
* @param view the text view to animate
|
||||
* @param duration the duration of the animation
|
||||
* @param colorStart the text color to start with
|
||||
* @param colorEnd the text color to end with
|
||||
*/
|
||||
public static void animateTextColor(final TextView view, final long duration,
|
||||
@ColorInt final int colorStart,
|
||||
@ColorInt final int colorEnd) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateTextColor() called with: "
|
||||
+ "view = [" + view + "], duration = [" + duration + "], "
|
||||
+ "colorStart = [" + colorStart + "], colorEnd = [" + colorEnd + "]");
|
||||
}
|
||||
|
||||
final ValueAnimator viewPropertyAnimator = ValueAnimator
|
||||
.ofObject(new ArgbEvaluator(), colorStart, colorEnd);
|
||||
viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator());
|
||||
viewPropertyAnimator.setDuration(duration);
|
||||
viewPropertyAnimator.addUpdateListener(animation ->
|
||||
view.setTextColor((int) animation.getAnimatedValue()));
|
||||
viewPropertyAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setTextColor(colorEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(final Animator animation) {
|
||||
view.setTextColor(colorEnd);
|
||||
}
|
||||
});
|
||||
viewPropertyAnimator.start();
|
||||
}
|
||||
|
||||
public static ValueAnimator animateHeight(final View view, final long duration,
|
||||
final int targetHeight) {
|
||||
final int height = view.getHeight();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateHeight: duration = [" + duration + "], "
|
||||
+ "from " + height + " to → " + targetHeight + " in: " + view);
|
||||
}
|
||||
|
||||
final ValueAnimator animator = ValueAnimator.ofFloat(height, targetHeight);
|
||||
animator.setInterpolator(new FastOutSlowInInterpolator());
|
||||
animator.setDuration(duration);
|
||||
animator.addUpdateListener(animation -> {
|
||||
final float value = (float) animation.getAnimatedValue();
|
||||
view.getLayoutParams().height = (int) value;
|
||||
view.requestLayout();
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.getLayoutParams().height = targetHeight;
|
||||
view.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(final Animator animation) {
|
||||
view.getLayoutParams().height = targetHeight;
|
||||
view.requestLayout();
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
|
||||
return animator;
|
||||
}
|
||||
|
||||
public static void animateRotation(final View view, final long duration,
|
||||
final int targetRotation) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "animateRotation: duration = [" + duration + "], "
|
||||
+ "from " + view.getRotation() + " to → " + targetRotation + " in: " + view);
|
||||
}
|
||||
view.animate().setListener(null).cancel();
|
||||
|
||||
view.animate()
|
||||
.rotation(targetRotation).setDuration(duration)
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationCancel(final Animator animation) {
|
||||
view.setRotation(targetRotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setRotation(targetRotation);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private static void animateAlpha(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay,
|
||||
final Runnable execOnEnd) {
|
||||
if (enterOrExit) {
|
||||
view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Internals
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
private static void animateScaleAndAlpha(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay,
|
||||
final Runnable execOnEnd) {
|
||||
if (enterOrExit) {
|
||||
view.setScaleX(.8f);
|
||||
view.setScaleY(.8f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(1f).scaleX(1f).scaleY(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
view.setScaleX(1f);
|
||||
view.setScaleY(1f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(0f).scaleX(.8f).scaleY(.8f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void animateLightScaleAndAlpha(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay,
|
||||
final Runnable execOnEnd) {
|
||||
if (enterOrExit) {
|
||||
view.setAlpha(.5f);
|
||||
view.setScaleX(.95f);
|
||||
view.setScaleY(.95f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(1f).scaleX(1f).scaleY(1f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
view.setAlpha(1f);
|
||||
view.setScaleX(1f);
|
||||
view.setScaleY(1f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(0f).scaleX(.95f).scaleY(.95f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void animateSlideAndAlpha(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay,
|
||||
final Runnable execOnEnd) {
|
||||
if (enterOrExit) {
|
||||
view.setTranslationY(-view.getHeight());
|
||||
view.setAlpha(0f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(0f).translationY(-view.getHeight())
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void animateLightSlideAndAlpha(final View view, final boolean enterOrExit,
|
||||
final long duration, final long delay,
|
||||
final Runnable execOnEnd) {
|
||||
if (enterOrExit) {
|
||||
view.setTranslationY(-view.getHeight() / 2.0f);
|
||||
view.setAlpha(0f);
|
||||
view.animate()
|
||||
.setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
view.animate().setInterpolator(new FastOutSlowInInterpolator())
|
||||
.alpha(0f).translationY(-view.getHeight() / 2.0f)
|
||||
.setDuration(duration).setStartDelay(delay)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(final Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
if (execOnEnd != null) {
|
||||
execOnEnd.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void slideUp(final View view, final long duration, final long delay,
|
||||
@FloatRange(from = 0.0f, to = 1.0f)
|
||||
final float translationPercent) {
|
||||
final int translationY = (int) (view.getResources().getDisplayMetrics().heightPixels
|
||||
* (translationPercent));
|
||||
|
||||
view.animate().setListener(null).cancel();
|
||||
view.setAlpha(0f);
|
||||
view.setTranslationY(translationY);
|
||||
view.setVisibility(View.VISIBLE);
|
||||
view.animate()
|
||||
.alpha(1f)
|
||||
.translationY(0)
|
||||
.setStartDelay(delay)
|
||||
.setDuration(duration)
|
||||
.setInterpolator(new FastOutSlowInInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
ALPHA,
|
||||
SCALE_AND_ALPHA, LIGHT_SCALE_AND_ALPHA,
|
||||
SLIDE_AND_ALPHA, LIGHT_SLIDE_AND_ALPHA
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.ktx.ViewUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.ArrayList;
|
||||
@ -128,7 +128,7 @@ public class CollapsibleView extends LinearLayout {
|
||||
if (currentAnimator != null && currentAnimator.isRunning()) {
|
||||
currentAnimator.cancel();
|
||||
}
|
||||
currentAnimator = AnimationUtils.animateHeight(this, ANIMATION_DURATION, 0);
|
||||
currentAnimator = ViewUtils.animateHeight(this, ANIMATION_DURATION, 0);
|
||||
|
||||
setCurrentState(COLLAPSED);
|
||||
}
|
||||
@ -151,7 +151,7 @@ public class CollapsibleView extends LinearLayout {
|
||||
if (currentAnimator != null && currentAnimator.isRunning()) {
|
||||
currentAnimator.cancel();
|
||||
}
|
||||
currentAnimator = AnimationUtils.animateHeight(this, ANIMATION_DURATION, this.targetHeight);
|
||||
currentAnimator = ViewUtils.animateHeight(this, ANIMATION_DURATION, this.targetHeight);
|
||||
setCurrentState(EXPANDED);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user