Add fullscreen mode to post view
This commit is contained in:
parent
3dde61d91a
commit
5744a1a687
@ -1,11 +1,17 @@
|
||||
package awais.instagrabber.adapters;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
|
||||
public class SliderCallbackAdapter implements SliderItemsAdapter.SliderCallback {
|
||||
@Override
|
||||
public void onThumbnailLoaded(final int position) {}
|
||||
|
||||
@Override
|
||||
public void onItemClicked(final int position) {}
|
||||
public void onItemClicked(final int position, final Media media, final View view) {}
|
||||
|
||||
@Override
|
||||
public void onPlayerPlay(final int position) {}
|
||||
@ -15,4 +21,12 @@ public class SliderCallbackAdapter implements SliderItemsAdapter.SliderCallback
|
||||
|
||||
@Override
|
||||
public void onPlayerRelease(final int position) {}
|
||||
|
||||
@Override
|
||||
public void onFullScreenModeChanged(final boolean isFullScreen, final StyledPlayerView playerView) {}
|
||||
|
||||
@Override
|
||||
public boolean isInFullScreen() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
package awais.instagrabber.adapters;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
|
||||
import awais.instagrabber.adapters.viewholder.SliderItemViewHolder;
|
||||
import awais.instagrabber.adapters.viewholder.SliderPhotoViewHolder;
|
||||
import awais.instagrabber.adapters.viewholder.SliderVideoViewHolder;
|
||||
import awais.instagrabber.customviews.VerticalDragHelper;
|
||||
import awais.instagrabber.databinding.ItemSliderPhotoBinding;
|
||||
import awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding;
|
||||
import awais.instagrabber.models.enums.MediaItemType;
|
||||
@ -18,10 +20,8 @@ import awais.instagrabber.repositories.responses.Media;
|
||||
|
||||
public final class SliderItemsAdapter extends ListAdapter<Media, SliderItemViewHolder> {
|
||||
|
||||
private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener;
|
||||
private final boolean loadVideoOnItemClick;
|
||||
private final SliderCallback sliderCallback;
|
||||
// private final LayoutExoCustomControlsBinding controlsBinding;
|
||||
|
||||
private static final DiffUtil.ItemCallback<Media> DIFF_CALLBACK = new DiffUtil.ItemCallback<Media>() {
|
||||
@Override
|
||||
@ -35,15 +35,11 @@ public final class SliderItemsAdapter extends ListAdapter<Media, SliderItemViewH
|
||||
}
|
||||
};
|
||||
|
||||
public SliderItemsAdapter(final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener,
|
||||
// final LayoutExoCustomControlsBinding controlsBinding,
|
||||
final boolean loadVideoOnItemClick,
|
||||
public SliderItemsAdapter(final boolean loadVideoOnItemClick,
|
||||
final SliderCallback sliderCallback) {
|
||||
super(DIFF_CALLBACK);
|
||||
this.onVerticalDragListener = onVerticalDragListener;
|
||||
this.loadVideoOnItemClick = loadVideoOnItemClick;
|
||||
this.sliderCallback = sliderCallback;
|
||||
// this.controlsBinding = controlsBinding;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -54,12 +50,12 @@ public final class SliderItemsAdapter extends ListAdapter<Media, SliderItemViewH
|
||||
switch (mediaItemType) {
|
||||
case MEDIA_TYPE_VIDEO: {
|
||||
final LayoutVideoPlayerWithThumbnailBinding binding = LayoutVideoPlayerWithThumbnailBinding.inflate(inflater, parent, false);
|
||||
return new SliderVideoViewHolder(binding, onVerticalDragListener, loadVideoOnItemClick);
|
||||
return new SliderVideoViewHolder(binding, loadVideoOnItemClick);
|
||||
}
|
||||
case MEDIA_TYPE_IMAGE:
|
||||
default:
|
||||
final ItemSliderPhotoBinding binding = ItemSliderPhotoBinding.inflate(inflater, parent, false);
|
||||
return new SliderPhotoViewHolder(binding, onVerticalDragListener);
|
||||
return new SliderPhotoViewHolder(binding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,12 +138,16 @@ public final class SliderItemsAdapter extends ListAdapter<Media, SliderItemViewH
|
||||
public interface SliderCallback {
|
||||
void onThumbnailLoaded(int position);
|
||||
|
||||
void onItemClicked(int position);
|
||||
void onItemClicked(int position, final Media media, final View view);
|
||||
|
||||
void onPlayerPlay(int position);
|
||||
|
||||
void onPlayerPause(int position);
|
||||
|
||||
void onPlayerRelease(int position);
|
||||
|
||||
void onFullScreenModeChanged(boolean isFullScreen, final StyledPlayerView playerView);
|
||||
|
||||
boolean isInFullScreen();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package awais.instagrabber.adapters.viewholder;
|
||||
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.net.Uri;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -14,8 +13,8 @@ import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
|
||||
import awais.instagrabber.adapters.SliderItemsAdapter;
|
||||
import awais.instagrabber.customviews.VerticalDragHelper;
|
||||
import awais.instagrabber.customviews.drawee.AnimatedZoomableController;
|
||||
import awais.instagrabber.customviews.drawee.DoubleTapGestureListener;
|
||||
import awais.instagrabber.databinding.ItemSliderPhotoBinding;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||
@ -24,13 +23,10 @@ public class SliderPhotoViewHolder extends SliderItemViewHolder {
|
||||
private static final String TAG = "FeedSliderPhotoViewHolder";
|
||||
|
||||
private final ItemSliderPhotoBinding binding;
|
||||
private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener;
|
||||
|
||||
public SliderPhotoViewHolder(@NonNull final ItemSliderPhotoBinding binding,
|
||||
final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener) {
|
||||
public SliderPhotoViewHolder(@NonNull final ItemSliderPhotoBinding binding) {
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
this.onVerticalDragListener = onVerticalDragListener;
|
||||
}
|
||||
|
||||
public void bind(@NonNull final Media model,
|
||||
@ -62,74 +58,19 @@ public class SliderPhotoViewHolder extends SliderItemViewHolder {
|
||||
})
|
||||
.setLowResImageRequest(ImageRequest.fromUri(ResponseBodyUtils.getThumbUrl(model)))
|
||||
.build());
|
||||
// binding.getRoot().setOnClickListener(v -> {
|
||||
// if (sliderCallback != null) {
|
||||
// sliderCallback.onItemClicked(position);
|
||||
// }
|
||||
// });
|
||||
binding.getRoot().setTapListener(new GestureDetector.SimpleOnGestureListener() {
|
||||
final DoubleTapGestureListener tapListener = new DoubleTapGestureListener(binding.getRoot()) {
|
||||
@Override
|
||||
public boolean onSingleTapUp(final MotionEvent e) {
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
if (sliderCallback != null) {
|
||||
sliderCallback.onItemClicked(position);
|
||||
return true;
|
||||
sliderCallback.onItemClicked(position, model, binding.getRoot());
|
||||
}
|
||||
return false;
|
||||
return super.onSingleTapConfirmed(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
binding.getRoot().setTapListener(tapListener);
|
||||
final AnimatedZoomableController zoomableController = AnimatedZoomableController.newInstance();
|
||||
zoomableController.setMaxScaleFactor(3f);
|
||||
binding.getRoot().setZoomableController(zoomableController);
|
||||
if (onVerticalDragListener != null) {
|
||||
binding.getRoot().setOnVerticalDragListener(onVerticalDragListener);
|
||||
}
|
||||
binding.getRoot().setZoomingEnabled(true);
|
||||
}
|
||||
|
||||
// private void setDimensions(final FeedModel feedModel, final int spanCount, final boolean animate) {
|
||||
// final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams();
|
||||
// final int deviceWidth = Utils.displayMetrics.widthPixels;
|
||||
// final int spanWidth = deviceWidth / spanCount;
|
||||
// final int spanHeight = NumberUtils.getResultingHeight(spanWidth, feedModel.getImageHeight(), feedModel.getImageWidth());
|
||||
// final int width = spanWidth == 0 ? deviceWidth : spanWidth;
|
||||
// final int height = spanHeight == 0 ? deviceWidth + 1 : spanHeight;
|
||||
// if (animate) {
|
||||
// Animation animation = AnimationUtils.expand(
|
||||
// binding.imageViewer,
|
||||
// layoutParams.width,
|
||||
// layoutParams.height,
|
||||
// width,
|
||||
// height,
|
||||
// new Animation.AnimationListener() {
|
||||
// @Override
|
||||
// public void onAnimationStart(final Animation animation) {
|
||||
// showOrHideDetails(spanCount);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onAnimationEnd(final Animation animation) {
|
||||
// // showOrHideDetails(spanCount);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onAnimationRepeat(final Animation animation) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
// binding.imageViewer.startAnimation(animation);
|
||||
// } else {
|
||||
// layoutParams.width = width;
|
||||
// layoutParams.height = height;
|
||||
// binding.imageViewer.requestLayout();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void showOrHideDetails(final int spanCount) {
|
||||
// if (spanCount == 1) {
|
||||
// binding.itemFeedTop.getRoot().setVisibility(View.VISIBLE);
|
||||
// binding.itemFeedBottom.getRoot().setVisibility(View.VISIBLE);
|
||||
// } else {
|
||||
// binding.itemFeedTop.getRoot().setVisibility(View.GONE);
|
||||
// binding.itemFeedBottom.getRoot().setVisibility(View.GONE);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.adapters.SliderItemsAdapter;
|
||||
import awais.instagrabber.customviews.VerticalDragHelper;
|
||||
import awais.instagrabber.customviews.VideoPlayerCallbackAdapter;
|
||||
import awais.instagrabber.customviews.VideoPlayerViewHelper;
|
||||
import awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding;
|
||||
@ -27,40 +28,23 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
private static final String TAG = "SliderVideoViewHolder";
|
||||
|
||||
private final LayoutVideoPlayerWithThumbnailBinding binding;
|
||||
// private final LayoutExoCustomControlsBinding controlsBinding;
|
||||
private final boolean loadVideoOnItemClick;
|
||||
private final GestureDetector.OnGestureListener videoPlayerViewGestureListener = new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
binding.playerView.performClick();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private VideoPlayerViewHelper videoPlayerViewHelper;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public SliderVideoViewHolder(@NonNull final LayoutVideoPlayerWithThumbnailBinding binding,
|
||||
final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener,
|
||||
// final LayoutExoCustomControlsBinding controlsBinding,
|
||||
final boolean loadVideoOnItemClick) {
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
// this.controlsBinding = controlsBinding;
|
||||
this.loadVideoOnItemClick = loadVideoOnItemClick;
|
||||
// if (onVerticalDragListener != null) {
|
||||
// final VerticalDragHelper thumbnailVerticalDragHelper = new VerticalDragHelper(binding.thumbnailParent);
|
||||
// final VerticalDragHelper playerVerticalDragHelper = new VerticalDragHelper(binding.playerView);
|
||||
// thumbnailVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
|
||||
// playerVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
|
||||
// binding.thumbnailParent.setOnTouchListener((v, event) -> {
|
||||
// final boolean onDragTouch = thumbnailVerticalDragHelper.onDragTouch(event);
|
||||
// if (onDragTouch) {
|
||||
// return true;
|
||||
// }
|
||||
// return thumbnailVerticalDragHelper.onGestureTouchEvent(event);
|
||||
// });
|
||||
// }
|
||||
final GestureDetector.OnGestureListener videoPlayerViewGestureListener = new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
binding.playerView.performClick();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final GestureDetector gestureDetector = new GestureDetector(itemView.getContext(), videoPlayerViewGestureListener);
|
||||
binding.playerView.setOnTouchListener((v, event) -> {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
@ -77,7 +61,7 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
@Override
|
||||
public void onThumbnailClick() {
|
||||
if (sliderCallback != null) {
|
||||
sliderCallback.onItemClicked(position);
|
||||
sliderCallback.onItemClicked(position, media, binding.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,6 +104,21 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
sliderCallback.onPlayerRelease(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFullScreenModeChanged(final boolean isFullScreen, final StyledPlayerView playerView) {
|
||||
if (sliderCallback != null) {
|
||||
sliderCallback.onFullScreenModeChanged(isFullScreen, playerView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInFullScreen() {
|
||||
if (sliderCallback != null) {
|
||||
return sliderCallback.isInFullScreen();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
final float aspectRatio = (float) media.getOriginalWidth() / media.getOriginalHeight();
|
||||
String videoUrl = null;
|
||||
@ -138,16 +137,10 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
aspectRatio,
|
||||
ResponseBodyUtils.getThumbUrl(media),
|
||||
loadVideoOnItemClick,
|
||||
// controlsBinding,
|
||||
videoPlayerCallback);
|
||||
// binding.itemFeedBottom.btnMute.setOnClickListener(v -> {
|
||||
// final float newVol = videoPlayerViewHelper.toggleMute();
|
||||
// setMuteIcon(newVol);
|
||||
// Utils.sessionVolumeFull = newVol == 1f;
|
||||
// });
|
||||
binding.playerView.setOnClickListener(v -> {
|
||||
if (sliderCallback != null) {
|
||||
sliderCallback.onItemClicked(position);
|
||||
sliderCallback.onItemClicked(position, media, binding.getRoot());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -161,62 +154,4 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
if (videoPlayerViewHelper == null) return;
|
||||
videoPlayerViewHelper.releasePlayer();
|
||||
}
|
||||
|
||||
// public void resetPlayerTimeline() {
|
||||
// if (videoPlayerViewHelper == null) return;
|
||||
// videoPlayerViewHelper.resetTimeline();
|
||||
// }
|
||||
//
|
||||
// public void removeCallbacks() {
|
||||
// if (videoPlayerViewHelper == null) return;
|
||||
// videoPlayerViewHelper.removeCallbacks();
|
||||
// }
|
||||
|
||||
// private void setDimensions(final FeedModel feedModel, final int spanCount, final boolean animate) {
|
||||
// final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams();
|
||||
// final int deviceWidth = Utils.displayMetrics.widthPixels;
|
||||
// final int spanWidth = deviceWidth / spanCount;
|
||||
// final int spanHeight = NumberUtils.getResultingHeight(spanWidth, feedModel.getImageHeight(), feedModel.getImageWidth());
|
||||
// final int width = spanWidth == 0 ? deviceWidth : spanWidth;
|
||||
// final int height = spanHeight == 0 ? deviceWidth + 1 : spanHeight;
|
||||
// if (animate) {
|
||||
// Animation animation = AnimationUtils.expand(
|
||||
// binding.imageViewer,
|
||||
// layoutParams.width,
|
||||
// layoutParams.height,
|
||||
// width,
|
||||
// height,
|
||||
// new Animation.AnimationListener() {
|
||||
// @Override
|
||||
// public void onAnimationStart(final Animation animation) {
|
||||
// showOrHideDetails(spanCount);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onAnimationEnd(final Animation animation) {
|
||||
// // showOrHideDetails(spanCount);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onAnimationRepeat(final Animation animation) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
// binding.imageViewer.startAnimation(animation);
|
||||
// } else {
|
||||
// layoutParams.width = width;
|
||||
// layoutParams.height = height;
|
||||
// binding.imageViewer.requestLayout();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void showOrHideDetails(final int spanCount) {
|
||||
// if (spanCount == 1) {
|
||||
// binding.itemFeedTop.getRoot().setVisibility(View.VISIBLE);
|
||||
// binding.itemFeedBottom.getRoot().setVisibility(View.VISIBLE);
|
||||
// } else {
|
||||
// binding.itemFeedTop.getRoot().setVisibility(View.GONE);
|
||||
// binding.itemFeedBottom.getRoot().setVisibility(View.GONE);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ public class FeedSliderViewHolder extends FeedItemViewHolder {
|
||||
final String text = "1/" + sliderItemLen;
|
||||
binding.mediaCounter.setText(text);
|
||||
binding.mediaList.setOffscreenPageLimit(1);
|
||||
final SliderItemsAdapter adapter = new SliderItemsAdapter(null, false, new SliderCallbackAdapter() {
|
||||
final SliderItemsAdapter adapter = new SliderItemsAdapter(false, new SliderCallbackAdapter() {
|
||||
@Override
|
||||
public void onItemClicked(final int position) {
|
||||
public void onItemClicked(final int position, final Media media, final View view) {
|
||||
feedItemCallback.onSliderClick(feedModel, position);
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
package awais.instagrabber.customviews;
|
||||
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
|
||||
public class VideoPlayerCallbackAdapter implements VideoPlayerViewHelper.VideoPlayerCallback {
|
||||
@Override
|
||||
public void onThumbnailLoaded() {}
|
||||
@ -18,4 +20,12 @@ public class VideoPlayerCallbackAdapter implements VideoPlayerViewHelper.VideoPl
|
||||
|
||||
@Override
|
||||
public void onRelease() {}
|
||||
|
||||
@Override
|
||||
public void onFullScreenModeChanged(final boolean isFullScreen, final StyledPlayerView playerView) {}
|
||||
|
||||
@Override
|
||||
public boolean isInFullScreen() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
package awais.instagrabber.customviews;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder;
|
||||
@ -23,18 +27,23 @@ import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.audio.AudioListener;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerControlView;
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
private static final String TAG = "VideoPlayerViewHelper";
|
||||
// private static final long INITIAL_DELAY = 0;
|
||||
// private static final long RECURRING_DELAY = 60;
|
||||
private static final String TAG = VideoPlayerViewHelper.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private final LayoutVideoPlayerWithThumbnailBinding binding;
|
||||
@ -42,74 +51,20 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
private final float thumbnailAspectRatio;
|
||||
private final String thumbnailUrl;
|
||||
private final boolean loadPlayerOnClick;
|
||||
// private final LayoutExoCustomControlsBinding controlsBinding;
|
||||
private final VideoPlayerCallback videoPlayerCallback;
|
||||
private final String videoUrl;
|
||||
private final DefaultDataSourceFactory dataSourceFactory;
|
||||
private SimpleExoPlayer player;
|
||||
private PopupMenu speedPopup;
|
||||
// private PositionCheckRunnable positionChecker;
|
||||
// private Handler positionUpdateHandler;
|
||||
private AppCompatImageButton mute;
|
||||
|
||||
// private final Player.EventListener listener = new Player.EventListener() {
|
||||
// @Override
|
||||
// public void onPlaybackStateChanged(final int state) {
|
||||
// // switch (state) {
|
||||
// // case Player.STATE_BUFFERING:
|
||||
// // case STATE_IDLE:
|
||||
// // case STATE_ENDED:
|
||||
// // positionUpdateHandler.removeCallbacks(positionChecker);
|
||||
// // return;
|
||||
// // case STATE_READY:
|
||||
// // setupTimeline();
|
||||
// // positionUpdateHandler.postDelayed(positionChecker, INITIAL_DELAY);
|
||||
// // break;
|
||||
// // }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) {
|
||||
// // updatePlayPauseDrawable(playWhenReady);
|
||||
// // if (positionUpdateHandler == null || positionChecker == null) return;
|
||||
// // if (playWhenReady) {
|
||||
// // positionUpdateHandler.removeCallbacks(positionChecker);
|
||||
// // positionUpdateHandler.postDelayed(positionChecker, INITIAL_DELAY);
|
||||
// // }
|
||||
// }
|
||||
// };
|
||||
private final AudioListener audioListener = new AudioListener() {
|
||||
@Override
|
||||
public void onVolumeChanged(final float volume) {
|
||||
updateMuteIcon(volume);
|
||||
}
|
||||
};
|
||||
// private final Slider.OnChangeListener onChangeListener = (slider, value, fromUser) -> {
|
||||
// if (!fromUser) return;
|
||||
// long actualValue = (long) value;
|
||||
// if (actualValue < 0) {
|
||||
// actualValue = 0;
|
||||
// } else if (actualValue > player.getDuration()) {
|
||||
// actualValue = player.getDuration();
|
||||
// }
|
||||
// player.seekTo(actualValue);
|
||||
// };
|
||||
// private final View.OnClickListener onClickListener = v -> player.setPlayWhenReady(!player.getPlayWhenReady());
|
||||
// // private final LabelFormatter labelFormatter = value -> TextUtils.millisToTimeString((long) value);
|
||||
private final View.OnClickListener muteOnClickListener = v -> toggleMute();
|
||||
private MaterialButton mute;
|
||||
// private final View.OnClickListener rewOnClickListener = v -> {
|
||||
// final long positionMs = player.getCurrentPosition() - 5000;
|
||||
// player.seekTo(positionMs < 0 ? 0 : positionMs);
|
||||
// };
|
||||
// private final View.OnClickListener ffOnClickListener = v -> {
|
||||
// long positionMs = player.getCurrentPosition() + 5000;
|
||||
// long duration = player.getDuration();
|
||||
// if (duration == TIME_UNSET) {
|
||||
// duration = 0;
|
||||
// }
|
||||
// player.seekTo(Math.min(positionMs, duration));
|
||||
// };
|
||||
// private final View.OnClickListener showMenu = this::showMenu;
|
||||
private Object layoutManager;
|
||||
|
||||
public VideoPlayerViewHelper(@NonNull final Context context,
|
||||
@NonNull final LayoutVideoPlayerWithThumbnailBinding binding,
|
||||
@ -118,7 +73,6 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
final float thumbnailAspectRatio,
|
||||
final String thumbnailUrl,
|
||||
final boolean loadPlayerOnClick,
|
||||
// final LayoutExoCustomControlsBinding controlsBinding,
|
||||
final VideoPlayerCallback videoPlayerCallback) {
|
||||
this.context = context;
|
||||
this.binding = binding;
|
||||
@ -126,7 +80,6 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
this.thumbnailAspectRatio = thumbnailAspectRatio;
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
this.loadPlayerOnClick = loadPlayerOnClick;
|
||||
// this.controlsBinding = controlsBinding;
|
||||
this.videoPlayerCallback = videoPlayerCallback;
|
||||
this.videoUrl = videoUrl;
|
||||
this.dataSourceFactory = new DefaultDataSourceFactory(binding.getRoot().getContext(), "instagram");
|
||||
@ -143,7 +96,6 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
}
|
||||
});
|
||||
setThumbnail();
|
||||
// setupControls();
|
||||
}
|
||||
|
||||
private void setThumbnail() {
|
||||
@ -196,11 +148,6 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
player = new SimpleExoPlayer.Builder(context)
|
||||
.setLooper(Looper.getMainLooper())
|
||||
.build();
|
||||
// positionUpdateHandler = new Handler();
|
||||
// positionChecker = new PositionCheckRunnable(positionUpdateHandler,
|
||||
// player,
|
||||
// controlsBinding.timeline,
|
||||
// controlsBinding.fromTime);
|
||||
player.addListener(this);
|
||||
player.addAudioListener(audioListener);
|
||||
player.setVolume(initialVolume);
|
||||
@ -210,138 +157,118 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
final MediaItem mediaItem = MediaItem.fromUri(videoUrl);
|
||||
final ProgressiveMediaSource mediaSource = sourceFactory.createMediaSource(mediaItem);
|
||||
player.setMediaSource(mediaSource);
|
||||
// setupControls();
|
||||
player.prepare();
|
||||
binding.playerView.setPlayer(player);
|
||||
// binding.playerView.setShowFastForwardButton(false);
|
||||
// binding.playerView.setShowRewindButton(false);
|
||||
binding.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT);
|
||||
binding.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
||||
binding.playerView.setShowNextButton(false);
|
||||
binding.playerView.setShowPreviousButton(false);
|
||||
// binding.controls.setPlayer(player);
|
||||
mute = binding.playerView.findViewById(R.id.mute);
|
||||
// mute = binding.controls.findViewById(R.id.mute);
|
||||
if (mute != null) {
|
||||
mute.setOnClickListener(muteOnClickListener);
|
||||
}
|
||||
updateMuteIcon(player.getVolume());
|
||||
binding.playerView.setControllerOnFullScreenModeChangedListener(isFullScreen -> {
|
||||
if (videoPlayerCallback == null) return;
|
||||
videoPlayerCallback.onFullScreenModeChanged(isFullScreen, binding.playerView);
|
||||
});
|
||||
setupControllerView();
|
||||
}
|
||||
|
||||
// private void setupControls() {
|
||||
// if (controlsBinding == null) return;
|
||||
// // binding.playerView.setUseController(false);
|
||||
// if (player == null) {
|
||||
// // enableControls(false);
|
||||
// // controlsBinding.playPause.setEnabled(true);
|
||||
// // controlsBinding.playPause.setOnClickListener(new NoPlayerPlayPauseClickListener(binding.thumbnailParent));
|
||||
// return;
|
||||
// }
|
||||
// // enableControls(true);
|
||||
// // updatePlayPauseDrawable(player.getPlayWhenReady());
|
||||
// // updateMuteIcon(player.getVolume());
|
||||
// player.addListener(listener);
|
||||
// // player.addAudioListener(audioListener);
|
||||
// // controlsBinding.timeline.addOnChangeListener(onChangeListener);
|
||||
// // controlsBinding.timeline.setLabelFormatter(labelFormatter);
|
||||
// // controlsBinding.playPause.setOnClickListener(onClickListener);
|
||||
// // controlsBinding.mute.setOnClickListener(muteOnClickListener);
|
||||
// // controlsBinding.rewWithAmount.setOnClickListener(rewOnClickListener);
|
||||
// // controlsBinding.ffWithAmount.setOnClickListener(ffOnClickListener);
|
||||
// // controlsBinding.speed.setOnClickListener(showMenu);
|
||||
// }
|
||||
private void setupControllerView() {
|
||||
try {
|
||||
final StyledPlayerControlView controllerView = getStyledPlayerControlView();
|
||||
if (controllerView == null) return;
|
||||
layoutManager = setControlViewLayoutManager(controllerView);
|
||||
if (videoPlayerCallback != null && videoPlayerCallback.isInFullScreen()) {
|
||||
setControllerViewToFullScreenMode(controllerView);
|
||||
}
|
||||
final ViewGroup exoBasicControls = controllerView.findViewById(R.id.exo_basic_controls);
|
||||
if (exoBasicControls == null) return;
|
||||
mute = new AppCompatImageButton(context);
|
||||
final Resources resources = context.getResources();
|
||||
if (resources == null) return;
|
||||
final int width = resources.getDimensionPixelSize(R.dimen.exo_small_icon_width);
|
||||
final int height = resources.getDimensionPixelSize(R.dimen.exo_small_icon_height);
|
||||
final int margin = resources.getDimensionPixelSize(R.dimen.exo_small_icon_horizontal_margin);
|
||||
final int paddingHorizontal = resources.getDimensionPixelSize(R.dimen.exo_small_icon_padding_horizontal);
|
||||
final int paddingVertical = resources.getDimensionPixelSize(R.dimen.exo_small_icon_padding_vertical);
|
||||
final ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(width, height);
|
||||
layoutParams.setMargins(margin, 0, margin, 0);
|
||||
mute.setLayoutParams(layoutParams);
|
||||
mute.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
|
||||
mute.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
mute.setBackgroundResource(Utils.getAttrResId(context, android.R.attr.selectableItemBackground));
|
||||
mute.setImageTintList(ColorStateList.valueOf(resources.getColor(R.color.white)));
|
||||
updateMuteIcon(player.getVolume());
|
||||
exoBasicControls.addView(mute, 0);
|
||||
mute.setOnClickListener(muteOnClickListener);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "loadPlayer: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
// private void setupTimeline() {
|
||||
// final long duration = player.getDuration();
|
||||
// controlsBinding.timeline.setEnabled(true);
|
||||
// controlsBinding.timeline.setValueFrom(0);
|
||||
// controlsBinding.timeline.setValueTo(duration);
|
||||
// controlsBinding.fromTime.setText(TextUtils.millisToTimeString(0));
|
||||
// controlsBinding.toTime.setText(TextUtils.millisToTimeString(duration));
|
||||
// }
|
||||
@Nullable
|
||||
private Object setControlViewLayoutManager(@NonNull final StyledPlayerControlView controllerView)
|
||||
throws NoSuchFieldException, IllegalAccessException {
|
||||
final Field controlViewLayoutManagerField = controllerView.getClass().getDeclaredField("controlViewLayoutManager");
|
||||
controlViewLayoutManagerField.setAccessible(true);
|
||||
return controlViewLayoutManagerField.get(controllerView);
|
||||
}
|
||||
|
||||
// private void enableControls(final boolean enable) {
|
||||
// controlsBinding.speed.setEnabled(enable);
|
||||
// controlsBinding.speed.setClickable(enable);
|
||||
// controlsBinding.mute.setEnabled(enable);
|
||||
// controlsBinding.mute.setClickable(enable);
|
||||
// controlsBinding.ffWithAmount.setEnabled(enable);
|
||||
// controlsBinding.ffWithAmount.setClickable(enable);
|
||||
// controlsBinding.rewWithAmount.setEnabled(enable);
|
||||
// controlsBinding.rewWithAmount.setClickable(enable);
|
||||
// // controlsBinding.fromTime.setEnabled(enable);
|
||||
// // controlsBinding.toTime.setEnabled(enable);
|
||||
// controlsBinding.playPause.setEnabled(enable);
|
||||
// controlsBinding.playPause.setClickable(enable);
|
||||
// // controlsBinding.timeline.setEnabled(enable);
|
||||
// }
|
||||
private void setControllerViewToFullScreenMode(@NonNull final StyledPlayerControlView controllerView)
|
||||
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||
// Exoplayer doesn't expose the fullscreen state, so using reflection
|
||||
final Field fullScreenButtonField = controllerView.getClass().getDeclaredField("fullScreenButton");
|
||||
fullScreenButtonField.setAccessible(true);
|
||||
final ImageView fullScreenButton = (ImageView) fullScreenButtonField.get(controllerView);
|
||||
final Field isFullScreen = controllerView.getClass().getDeclaredField("isFullScreen");
|
||||
isFullScreen.setAccessible(true);
|
||||
isFullScreen.set(controllerView, true);
|
||||
final Method updateFullScreenButtonForState = controllerView
|
||||
.getClass()
|
||||
.getDeclaredMethod("updateFullScreenButtonForState", ImageView.class, boolean.class);
|
||||
updateFullScreenButtonForState.setAccessible(true);
|
||||
updateFullScreenButtonForState.invoke(controllerView, fullScreenButton, true);
|
||||
|
||||
// public void showMenu(View anchor) {
|
||||
// PopupMenu popup = getPopupMenu(anchor);
|
||||
// popup.show();
|
||||
// }
|
||||
}
|
||||
|
||||
// @NonNull
|
||||
// private PopupMenu getPopupMenu(final View anchor) {
|
||||
// if (speedPopup != null) {
|
||||
// return speedPopup;
|
||||
// }
|
||||
// final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.popupMenuStyle);
|
||||
// // final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.Widget_MaterialComponents_PopupMenu_Exoplayer);
|
||||
// speedPopup = new PopupMenu(themeWrapper, anchor);
|
||||
// speedPopup.getMenuInflater().inflate(R.menu.speed_menu, speedPopup.getMenu());
|
||||
// speedPopup.setOnMenuItemClickListener(item -> {
|
||||
// float nextSpeed;
|
||||
// int textResId;
|
||||
// int itemId = item.getItemId();
|
||||
// if (itemId == R.id.pt_two_five_x) {
|
||||
// nextSpeed = 0.25f;
|
||||
// textResId = R.string.pt_two_five_x;
|
||||
// } else if (itemId == R.id.pt_five_x) {
|
||||
// nextSpeed = 0.5f;
|
||||
// textResId = R.string.pt_five_x;
|
||||
// } else if (itemId == R.id.pt_seven_five_x) {
|
||||
// nextSpeed = 0.75f;
|
||||
// textResId = R.string.pt_seven_five_x;
|
||||
// } else if (itemId == R.id.one_x) {
|
||||
// nextSpeed = 1f;
|
||||
// textResId = R.string.one_x;
|
||||
// } else if (itemId == R.id.one_pt_two_five_x) {
|
||||
// nextSpeed = 1.25f;
|
||||
// textResId = R.string.one_pt_two_five_x;
|
||||
// } else if (itemId == R.id.one_pt_five_x) {
|
||||
// nextSpeed = 1.5f;
|
||||
// textResId = R.string.one_pt_five_x;
|
||||
// } else if (itemId == R.id.two_x) {
|
||||
// nextSpeed = 2f;
|
||||
// textResId = R.string.two_x;
|
||||
// } else {
|
||||
// nextSpeed = 1;
|
||||
// textResId = R.string.one_x;
|
||||
// }
|
||||
// player.setPlaybackParameters(new PlaybackParameters(nextSpeed));
|
||||
// controlsBinding.speed.setText(textResId);
|
||||
// return true;
|
||||
// });
|
||||
// return speedPopup;
|
||||
// }
|
||||
@Nullable
|
||||
private StyledPlayerControlView getStyledPlayerControlView() throws NoSuchFieldException, IllegalAccessException {
|
||||
final Field controller = binding.playerView.getClass().getDeclaredField("controller");
|
||||
controller.setAccessible(true);
|
||||
return (StyledPlayerControlView) controller.get(binding.playerView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(@NonNull TrackGroupArray trackGroups, @NonNull TrackSelectionArray trackSelections) {
|
||||
if (trackGroups.isEmpty()) {
|
||||
setHasAudio(false);
|
||||
return;
|
||||
}
|
||||
boolean hasAudio = false;
|
||||
for (int i = 0; i < trackGroups.length; i++) {
|
||||
for (int g = 0; g < trackGroups.get(i).length; g++) {
|
||||
final String sampleMimeType = trackGroups.get(i).getFormat(g).sampleMimeType;
|
||||
if (sampleMimeType != null && sampleMimeType.contains("audio")) {
|
||||
hasAudio = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setHasAudio(hasAudio);
|
||||
}
|
||||
|
||||
private void setHasAudio(final boolean hasAudio) {
|
||||
if (mute == null) return;
|
||||
mute.setEnabled(hasAudio);
|
||||
mute.setAlpha(hasAudio ? 1f : 0.5f);
|
||||
updateMuteIcon(hasAudio ? 1f : 0f);
|
||||
}
|
||||
|
||||
private void updateMuteIcon(final float volume) {
|
||||
if (mute == null) return;
|
||||
if (volume == 0) {
|
||||
mute.setIconResource(R.drawable.ic_volume_off_24_states);
|
||||
mute.setImageResource(R.drawable.ic_volume_off_24);
|
||||
return;
|
||||
}
|
||||
mute.setIconResource(R.drawable.ic_volume_up_24_states);
|
||||
mute.setImageResource(R.drawable.ic_volume_up_24);
|
||||
}
|
||||
|
||||
// private void updatePlayPauseDrawable(final boolean playWhenReady) {
|
||||
// if (playWhenReady) {
|
||||
// controlsBinding.playPause.setIconResource(R.drawable.ic_pause_24);
|
||||
// return;
|
||||
// }
|
||||
// controlsBinding.playPause.setIconResource(R.drawable.ic_play_states);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) {
|
||||
if (videoPlayerCallback == null) return;
|
||||
@ -359,18 +286,18 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
|
||||
private void toggleMute() {
|
||||
if (player == null) return;
|
||||
if (layoutManager != null) {
|
||||
try {
|
||||
final Method resetHideCallbacks = layoutManager.getClass().getDeclaredMethod("resetHideCallbacks");
|
||||
resetHideCallbacks.invoke(layoutManager);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "toggleMute: ", e);
|
||||
}
|
||||
}
|
||||
final float vol = player.getVolume() == 0f ? 1f : 0f;
|
||||
player.setVolume(vol);
|
||||
}
|
||||
|
||||
// public void togglePlayback() {
|
||||
// if (player == null) return;
|
||||
// final int playbackState = player.getPlaybackState();
|
||||
// if (playbackState == STATE_IDLE || playbackState == STATE_ENDED) return;
|
||||
// final boolean playWhenReady = player.getPlayWhenReady();
|
||||
// player.setPlayWhenReady(!playWhenReady);
|
||||
// }
|
||||
|
||||
public void releasePlayer() {
|
||||
if (videoPlayerCallback != null) {
|
||||
videoPlayerCallback.onRelease();
|
||||
@ -379,86 +306,14 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
// if (positionUpdateHandler != null) {
|
||||
// if (positionChecker != null) {
|
||||
// positionUpdateHandler.removeCallbacks(positionChecker);
|
||||
// positionChecker = null;
|
||||
// }
|
||||
// positionUpdateHandler = null;
|
||||
// }
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (player != null) {
|
||||
player.pause();
|
||||
}
|
||||
// if (positionUpdateHandler != null) {
|
||||
// if (positionChecker != null) {
|
||||
// positionUpdateHandler.removeCallbacks(positionChecker);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// public void resetTimeline() {
|
||||
// if (player == null) {
|
||||
// enableControls(false);
|
||||
// return;
|
||||
// }
|
||||
// setupTimeline();
|
||||
// final long currentPosition = player.getCurrentPosition();
|
||||
// controlsBinding.timeline.setValue(Math.min(currentPosition, player.getDuration()));
|
||||
// setupControls();
|
||||
// }
|
||||
|
||||
// public void removeCallbacks() {
|
||||
// if (player != null) {
|
||||
// player.removeListener(listener);
|
||||
// player.removeAudioListener(audioListener);
|
||||
// }
|
||||
// controlsBinding.timeline.removeOnChangeListener(onChangeListener);
|
||||
// controlsBinding.timeline.setLabelFormatter(null);
|
||||
// controlsBinding.playPause.setOnClickListener(null);
|
||||
// controlsBinding.mute.setOnClickListener(null);
|
||||
// controlsBinding.rewWithAmount.setOnClickListener(null);
|
||||
// controlsBinding.ffWithAmount.setOnClickListener(null);
|
||||
// controlsBinding.speed.setOnClickListener(null);
|
||||
// }
|
||||
|
||||
// private static class PositionCheckRunnable implements Runnable {
|
||||
// private final Handler positionUpdateHandler;
|
||||
// private final SimpleExoPlayer player;
|
||||
// private final Slider timeline;
|
||||
// private final AppCompatTextView fromTime;
|
||||
//
|
||||
// public PositionCheckRunnable(final Handler positionUpdateHandler,
|
||||
// final SimpleExoPlayer simpleExoPlayer,
|
||||
// final Slider slider,
|
||||
// final AppCompatTextView fromTime) {
|
||||
// this.positionUpdateHandler = positionUpdateHandler;
|
||||
// this.player = simpleExoPlayer;
|
||||
// this.timeline = slider;
|
||||
// this.fromTime = fromTime;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// if (positionUpdateHandler == null) return;
|
||||
// positionUpdateHandler.removeCallbacks(this);
|
||||
// if (player == null) return;
|
||||
// final long currentPosition = player.getCurrentPosition();
|
||||
// final long duration = player.getDuration();
|
||||
// if (duration == TIME_UNSET) {
|
||||
// timeline.setValueFrom(0);
|
||||
// timeline.setValueTo(0);
|
||||
// timeline.setEnabled(false);
|
||||
// return;
|
||||
// }
|
||||
// timeline.setValue(Math.min(currentPosition, duration));
|
||||
// fromTime.setText(TextUtils.millisToTimeString(currentPosition));
|
||||
// positionUpdateHandler.postDelayed(this, RECURRING_DELAY);
|
||||
// }
|
||||
// }
|
||||
|
||||
public interface VideoPlayerCallback {
|
||||
void onThumbnailLoaded();
|
||||
|
||||
@ -471,5 +326,9 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
void onPause();
|
||||
|
||||
void onRelease();
|
||||
|
||||
void onFullScreenModeChanged(boolean isFullScreen, final StyledPlayerView playerView);
|
||||
|
||||
boolean isInFullScreen();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@ -14,15 +15,18 @@ import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.PermissionChecker;
|
||||
import androidx.fragment.app.Fragment;
|
||||
@ -44,6 +48,8 @@ import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||
import com.facebook.drawee.interfaces.DraweeController;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.skydoves.balloon.ArrowOrientation;
|
||||
@ -59,6 +65,7 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.MainActivity;
|
||||
import awais.instagrabber.adapters.SliderCallbackAdapter;
|
||||
import awais.instagrabber.adapters.SliderItemsAdapter;
|
||||
import awais.instagrabber.adapters.viewholder.SliderVideoViewHolder;
|
||||
@ -67,6 +74,7 @@ import awais.instagrabber.customviews.VideoPlayerCallbackAdapter;
|
||||
import awais.instagrabber.customviews.VideoPlayerViewHelper;
|
||||
import awais.instagrabber.customviews.drawee.AnimatedZoomableController;
|
||||
import awais.instagrabber.customviews.drawee.DoubleTapGestureListener;
|
||||
import awais.instagrabber.customviews.drawee.ZoomableController;
|
||||
import awais.instagrabber.customviews.drawee.ZoomableDraweeView;
|
||||
import awais.instagrabber.databinding.DialogPostViewBinding;
|
||||
import awais.instagrabber.databinding.LayoutPostViewBottomBinding;
|
||||
@ -117,6 +125,12 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
@Nullable
|
||||
private ViewPager2 sliderParent;
|
||||
private LayoutPostViewBottomBinding bottom;
|
||||
private View postView;
|
||||
private int originalHeight;
|
||||
private int originalSystemUi;
|
||||
private boolean isInFullScreenMode;
|
||||
private StyledPlayerView playerView;
|
||||
private int playerViewOriginalHeight;
|
||||
|
||||
private final Observer<Object> backStackSavedStateObserver = result -> {
|
||||
if (result == null) return;
|
||||
@ -127,6 +141,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
// clear result
|
||||
backStackSavedStateResultLiveData.postValue(null);
|
||||
};
|
||||
private Drawable originalRootBackground;
|
||||
|
||||
public void setOnDeleteListener(final OnDeleteListener onDeleteListener) {
|
||||
if (onDeleteListener == null) return;
|
||||
@ -197,6 +212,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
showSystemUI();
|
||||
final Media media = viewModel.getMedia();
|
||||
if (media == null) return;
|
||||
switch (media.getMediaType()) {
|
||||
@ -753,7 +769,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
}
|
||||
|
||||
private void setupPostImage() {
|
||||
binding.mediaCounter.setVisibility(View.GONE);
|
||||
// binding.mediaCounter.setVisibility(View.GONE);
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
final Resources resources = context.getResources();
|
||||
@ -762,12 +778,14 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
final String imageUrl = ResponseBodyUtils.getImageUrl(media);
|
||||
if (TextUtils.isEmpty(imageUrl)) return;
|
||||
final ZoomableDraweeView postImage = new ZoomableDraweeView(context);
|
||||
postView = postImage;
|
||||
final NullSafePair<Integer, Integer> widthHeight = NumberUtils.calculateWidthHeight(media.getOriginalHeight(),
|
||||
media.getOriginalWidth(),
|
||||
(int) (Utils.displayMetrics.heightPixels * 0.8),
|
||||
Utils.displayMetrics.widthPixels);
|
||||
final int height = widthHeight.second;
|
||||
final ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, height);
|
||||
originalHeight = widthHeight.second;
|
||||
final ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
originalHeight);
|
||||
layoutParams.topToBottom = binding.topBarrier.getId();
|
||||
layoutParams.bottomToTop = bottom.buttonsTopBarrier.getId();
|
||||
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
|
||||
@ -788,10 +806,22 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
zoomableController.setGestureZoomEnabled(true);
|
||||
zoomableController.setEnabled(true);
|
||||
postImage.setZoomingEnabled(true);
|
||||
postImage.setTapListener(new DoubleTapGestureListener(postImage));
|
||||
final DoubleTapGestureListener tapListener = new DoubleTapGestureListener(postImage) {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
if (!isInFullScreenMode) {
|
||||
zoomableController.reset();
|
||||
hideSystemUI();
|
||||
} else {
|
||||
showSystemUI();
|
||||
binding.getRoot().postDelayed(zoomableController::reset, 500);
|
||||
}
|
||||
return super.onSingleTapConfirmed(e);
|
||||
}
|
||||
};
|
||||
postImage.setTapListener(tapListener);
|
||||
// postImage.setAllowTouchInterceptionWhileZoomed(true);
|
||||
binding.contentRoot.addView(postImage, 0);
|
||||
// binding.postImage.setAllowTouchInterceptionWhileZoomed(true);
|
||||
// binding.postImage.setOnVerticalDragListener(onVerticalDragListener);
|
||||
}
|
||||
|
||||
private void setupSlider() {
|
||||
@ -818,13 +848,15 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
maxHW.second,
|
||||
(int) (Utils.displayMetrics.heightPixels * 0.8),
|
||||
Utils.displayMetrics.widthPixels);
|
||||
originalHeight = widthHeight.second;
|
||||
final ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
widthHeight.second);
|
||||
originalHeight);
|
||||
layoutParams.topToBottom = binding.topBarrier.getId();
|
||||
layoutParams.bottomToTop = bottom.buttonsTopBarrier.getId();
|
||||
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
|
||||
layoutParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
|
||||
sliderParent.setLayoutParams(layoutParams);
|
||||
postView = sliderParent;
|
||||
binding.contentRoot.addView(sliderParent, 0);
|
||||
|
||||
final boolean hasVideo = media.getCarouselMedia()
|
||||
@ -841,16 +873,23 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
});
|
||||
}
|
||||
}
|
||||
sliderItemsAdapter = new SliderItemsAdapter(null, true, new SliderCallbackAdapter() {
|
||||
sliderItemsAdapter = new SliderItemsAdapter(true, new SliderCallbackAdapter() {
|
||||
@Override
|
||||
public void onThumbnailLoaded(final int position) {
|
||||
if (position != 0) return;
|
||||
startPostponedEnterTransition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClicked(final int position) {
|
||||
// toggleDetails();
|
||||
public void onItemClicked(final int position, final Media media, final View view) {
|
||||
if (media == null
|
||||
|| media.getMediaType() != MediaItemType.MEDIA_TYPE_IMAGE
|
||||
|| !(view instanceof ZoomableDraweeView)) {
|
||||
return;
|
||||
}
|
||||
final ZoomableController zoomableController = ((ZoomableDraweeView) view).getZoomableController();
|
||||
if (!(zoomableController instanceof AnimatedZoomableController)) return;
|
||||
if (!isInFullScreenMode) {
|
||||
((AnimatedZoomableController) zoomableController).reset();
|
||||
hideSystemUI();
|
||||
return;
|
||||
}
|
||||
showSystemUI();
|
||||
binding.getRoot().postDelayed(((AnimatedZoomableController) zoomableController)::reset, 500);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -877,6 +916,21 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (activity == null) return;
|
||||
Utils.disableKeepScreenOn(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFullScreenModeChanged(final boolean isFullScreen, final StyledPlayerView playerView) {
|
||||
PostViewV2Fragment.this.playerView = playerView;
|
||||
if (isFullScreen) {
|
||||
hideSystemUI();
|
||||
return;
|
||||
}
|
||||
showSystemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInFullScreen() {
|
||||
return isInFullScreenMode;
|
||||
}
|
||||
});
|
||||
sliderParent.setAdapter(sliderItemsAdapter);
|
||||
if (sliderPosition >= 0 && sliderPosition < media.getCarouselMedia().size()) {
|
||||
@ -981,12 +1035,14 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
(int) (Utils.displayMetrics.heightPixels * 0.8),
|
||||
Utils.displayMetrics.widthPixels);
|
||||
layoutParams.width = ConstraintLayout.LayoutParams.MATCH_PARENT;
|
||||
layoutParams.height = widthHeight.second;
|
||||
originalHeight = widthHeight.second;
|
||||
layoutParams.height = originalHeight;
|
||||
layoutParams.topToBottom = binding.topBarrier.getId();
|
||||
layoutParams.bottomToTop = bottom.buttonsTopBarrier.getId();
|
||||
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
|
||||
layoutParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
|
||||
binding.contentRoot.addView(videoPost.getRoot(), 0);
|
||||
postView = videoPost.getRoot();
|
||||
binding.contentRoot.addView(postView, 0);
|
||||
|
||||
// final GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
|
||||
// @Override
|
||||
@ -1041,6 +1097,16 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (activity == null) return;
|
||||
Utils.disableKeepScreenOn(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFullScreenModeChanged(final boolean isFullScreen, final StyledPlayerView playerView) {
|
||||
PostViewV2Fragment.this.playerView = playerView;
|
||||
if (isFullScreen) {
|
||||
hideSystemUI();
|
||||
return;
|
||||
}
|
||||
showSystemUI();
|
||||
}
|
||||
};
|
||||
final float aspectRatio = (float) media.getOriginalWidth() / media.getOriginalHeight();
|
||||
String videoUrl = null;
|
||||
@ -1064,92 +1130,6 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
}
|
||||
}
|
||||
|
||||
// private void enablePlayerControls(final boolean enable) {
|
||||
// video = enable;
|
||||
// if (enable) {
|
||||
// binding.playerControlsToggle.setVisibility(View.VISIBLE);
|
||||
// binding.playerControlsToggle.setOnClickListener(v -> {
|
||||
// final int visibility = binding.playerControls.getRoot().getVisibility();
|
||||
// if (visibility == View.GONE) {
|
||||
// showPlayerControls();
|
||||
// return;
|
||||
// }
|
||||
// hidePlayerControls();
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// binding.playerControlsToggle.setVisibility(View.GONE);
|
||||
// hidePlayerControls();
|
||||
// }
|
||||
|
||||
// private void hideCaption() {
|
||||
// if (bottomSheetBehavior == null) return;
|
||||
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
// }
|
||||
|
||||
// private void showPlayerControls() {
|
||||
// hideCaption();
|
||||
// // previously invisible view
|
||||
// View view = binding.playerControls.getRoot();
|
||||
// if (view.getVisibility() == View.VISIBLE) {
|
||||
// return;
|
||||
// }
|
||||
// if (!ViewCompat.isAttachedToWindow(view)) {
|
||||
// view.setVisibility(View.VISIBLE);
|
||||
// return;
|
||||
// }
|
||||
// // get the center for the clipping circle
|
||||
// int cx = view.getWidth() / 2;
|
||||
// // int cy = view.getHeight() / 2;
|
||||
// int cy = view.getHeight();
|
||||
//
|
||||
// // get the final radius for the clipping circle
|
||||
// float finalRadius = (float) Math.hypot(cx, cy);
|
||||
//
|
||||
// // create the animator for this view (the start radius is zero)
|
||||
// Animator anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, 0f, finalRadius);
|
||||
//
|
||||
// // make the view visible and start the animation
|
||||
// view.setVisibility(View.VISIBLE);
|
||||
// anim.start();
|
||||
//
|
||||
// }
|
||||
|
||||
// private void hidePlayerControls() {
|
||||
// // previously visible view
|
||||
// final View view = binding.playerControls.getRoot();
|
||||
// if (view.getVisibility() == View.GONE) {
|
||||
// return;
|
||||
// }
|
||||
// if (!ViewCompat.isAttachedToWindow(view)) {
|
||||
// view.setVisibility(View.GONE);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // get the center for the clipping circle
|
||||
// int cx = view.getWidth() / 2;
|
||||
// // int cy = view.getHeight() / 2;
|
||||
// int cy = view.getHeight();
|
||||
//
|
||||
// // get the initial radius for the clipping circle
|
||||
// float initialRadius = (float) Math.hypot(cx, cy);
|
||||
//
|
||||
// // create the animation (the final radius is zero)
|
||||
// Animator anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0f);
|
||||
//
|
||||
// // make the view invisible when the animation is done
|
||||
// anim.addListener(new AnimatorListenerAdapter() {
|
||||
// @Override
|
||||
// public void onAnimationEnd(Animator animation) {
|
||||
// super.onAnimationEnd(animation);
|
||||
// view.setVisibility(View.GONE);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // start the animation
|
||||
// anim.start();
|
||||
// }
|
||||
|
||||
private void setupOptions(final Boolean show) {
|
||||
if (!show) {
|
||||
binding.options.setVisibility(View.GONE);
|
||||
@ -1282,29 +1262,49 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
}
|
||||
|
||||
private void toggleDetails() {
|
||||
// hasBeenToggled = true;
|
||||
final boolean hasBeenToggled = true;
|
||||
final Media media = viewModel.getMedia();
|
||||
binding.getRoot().post(() -> {
|
||||
TransitionManager.beginDelayedTransition(binding.getRoot());
|
||||
if (detailsVisible) {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
originalRootBackground = binding.getRoot().getBackground();
|
||||
final Resources resources = context.getResources();
|
||||
if (resources == null) return;
|
||||
final ColorDrawable colorDrawable = new ColorDrawable(resources.getColor(R.color.black));
|
||||
binding.getRoot().setBackground(colorDrawable);
|
||||
if (postView != null) {
|
||||
// Make post match parent
|
||||
final ViewGroup.LayoutParams layoutParams = postView.getLayoutParams();
|
||||
final int fullHeight = Utils.displayMetrics.heightPixels + Utils.getNavigationBarSize(context).y;
|
||||
layoutParams.height = fullHeight;
|
||||
binding.contentRoot.getLayoutParams().height = fullHeight;
|
||||
if (playerView != null) {
|
||||
playerViewOriginalHeight = playerView.getLayoutParams().height;
|
||||
playerView.getLayoutParams().height = fullHeight;
|
||||
}
|
||||
}
|
||||
detailsVisible = false;
|
||||
if (media.getUser() != null) {
|
||||
binding.profilePic.setVisibility(View.GONE);
|
||||
binding.title.setVisibility(View.GONE);
|
||||
binding.subtitle.setVisibility(View.GONE);
|
||||
// binding.topBg.setVisibility(View.GONE);
|
||||
}
|
||||
if (media.getLocation() != null) {
|
||||
binding.location.setVisibility(View.GONE);
|
||||
}
|
||||
// bottom.bottomBg.setVisibility(View.GONE);
|
||||
// bottom.likesCount.setVisibility(View.GONE);
|
||||
// bottom.commentsCount.setVisibility(View.GONE);
|
||||
if (media.getCaption() != null && !TextUtils.isEmpty(media.getCaption().getText())) {
|
||||
bottom.caption.setVisibility(View.GONE);
|
||||
bottom.translate.setVisibility(View.GONE);
|
||||
}
|
||||
bottom.likesCount.setVisibility(View.GONE);
|
||||
bottom.commentsCount.setVisibility(View.GONE);
|
||||
bottom.date.setVisibility(View.GONE);
|
||||
bottom.comment.setVisibility(View.GONE);
|
||||
bottom.like.setVisibility(View.GONE);
|
||||
bottom.save.setVisibility(View.GONE);
|
||||
// bottom.share.setVisibility(View.GONE);
|
||||
bottom.share.setVisibility(View.GONE);
|
||||
bottom.download.setVisibility(View.GONE);
|
||||
binding.mediaCounter.setVisibility(View.GONE);
|
||||
bottom.viewsCount.setVisibility(View.GONE);
|
||||
@ -1312,12 +1312,21 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (options != null && !options.isEmpty()) {
|
||||
binding.options.setVisibility(View.GONE);
|
||||
}
|
||||
// wasControlsVisible = binding.playerControls.getRoot().getVisibility() == View.VISIBLE;
|
||||
// if (wasControlsVisible) {
|
||||
// hidePlayerControls();
|
||||
// }
|
||||
return;
|
||||
}
|
||||
if (originalRootBackground != null) {
|
||||
binding.getRoot().setBackground(originalRootBackground);
|
||||
}
|
||||
if (postView != null) {
|
||||
// Make post height back to original
|
||||
final ViewGroup.LayoutParams layoutParams = postView.getLayoutParams();
|
||||
layoutParams.height = originalHeight;
|
||||
binding.contentRoot.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
if (playerView != null) {
|
||||
playerView.getLayoutParams().height = playerViewOriginalHeight;
|
||||
playerView = null;
|
||||
}
|
||||
}
|
||||
if (media.getUser() != null) {
|
||||
binding.profilePic.setVisibility(View.VISIBLE);
|
||||
binding.title.setVisibility(View.VISIBLE);
|
||||
@ -1327,17 +1336,20 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
if (media.getLocation() != null) {
|
||||
binding.location.setVisibility(View.VISIBLE);
|
||||
}
|
||||
// bottom.bottomBg.setVisibility(View.VISIBLE);
|
||||
if (media.getCaption() != null && !TextUtils.isEmpty(media.getCaption().getText())) {
|
||||
bottom.caption.setVisibility(View.VISIBLE);
|
||||
bottom.translate.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (viewModel.hasPk()) {
|
||||
// bottom.likesCount.setVisibility(View.VISIBLE);
|
||||
bottom.likesCount.setVisibility(View.VISIBLE);
|
||||
bottom.date.setVisibility(View.VISIBLE);
|
||||
// binding.captionParent.setVisibility(View.VISIBLE);
|
||||
// binding.captionToggle.setVisibility(View.VISIBLE);
|
||||
// bottom.share.setVisibility(View.VISIBLE);
|
||||
bottom.share.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (viewModel.hasPk() && !viewModel.getMedia().isCommentsDisabled()) {
|
||||
bottom.comment.setVisibility(View.VISIBLE);
|
||||
// bottom.commentsCount.setVisibility(View.VISIBLE);
|
||||
bottom.commentsCount.setVisibility(View.VISIBLE);
|
||||
}
|
||||
bottom.download.setVisibility(View.VISIBLE);
|
||||
final List<Integer> options = viewModel.getOptions().getValue();
|
||||
@ -1362,6 +1374,64 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
|
||||
});
|
||||
}
|
||||
|
||||
private void hideSystemUI() {
|
||||
if (detailsVisible) {
|
||||
toggleDetails();
|
||||
}
|
||||
final MainActivity activity = (MainActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
final ActionBar actionBar = activity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.hide();
|
||||
}
|
||||
final CollapsingToolbarLayout appbarLayout = activity.getCollapsingToolbarView();
|
||||
if (appbarLayout != null) {
|
||||
appbarLayout.setVisibility(View.GONE);
|
||||
}
|
||||
final Toolbar toolbar = activity.getToolbar();
|
||||
if (toolbar != null) {
|
||||
toolbar.setVisibility(View.GONE);
|
||||
}
|
||||
final View decorView = activity.getWindow().getDecorView();
|
||||
originalSystemUi = decorView.getSystemUiVisibility();
|
||||
decorView.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||
// Set the content to appear under the system bars so that the
|
||||
// content doesn't resize when the system bars hide and show.
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
// Hide the nav bar and status bar
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
isInFullScreenMode = true;
|
||||
}
|
||||
|
||||
// Shows the system bars by removing all the flags
|
||||
// except for the ones that make the content appear under the system bars.
|
||||
private void showSystemUI() {
|
||||
if (!detailsVisible) {
|
||||
toggleDetails();
|
||||
}
|
||||
final MainActivity activity = (MainActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
final ActionBar actionBar = activity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.show();
|
||||
}
|
||||
final CollapsingToolbarLayout appbarLayout = activity.getCollapsingToolbarView();
|
||||
if (appbarLayout != null) {
|
||||
appbarLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
final Toolbar toolbar = activity.getToolbar();
|
||||
if (toolbar != null) {
|
||||
toolbar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
final View decorView = activity.getWindow().getDecorView();
|
||||
decorView.setSystemUiVisibility(originalSystemUi);
|
||||
isInFullScreenMode = false;
|
||||
}
|
||||
|
||||
private void navigateToProfile(final String username) {
|
||||
final NavController navController = getNavController();
|
||||
if (navController == null) return;
|
||||
|
@ -10,6 +10,7 @@ import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaScannerConnection;
|
||||
@ -22,6 +23,7 @@ import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
@ -294,6 +296,12 @@ public final class Utils {
|
||||
return outValue.data;
|
||||
}
|
||||
|
||||
public static int getAttrResId(@NonNull final Context context, final int attr) {
|
||||
final TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(attr, outValue, true);
|
||||
return outValue.resourceId;
|
||||
}
|
||||
|
||||
public static void transparentStatusBar(final Activity activity,
|
||||
final boolean enable,
|
||||
final boolean fullscreen) {
|
||||
@ -517,4 +525,41 @@ public final class Utils {
|
||||
if (navRootString == null || tabOrderString == null) return false;
|
||||
return tabOrderString.contains(navRootString);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Point getNavigationBarSize(@NonNull Context context) {
|
||||
Point appUsableSize = getAppUsableScreenSize(context);
|
||||
Point realScreenSize = getRealScreenSize(context);
|
||||
|
||||
// navigation bar on the right
|
||||
if (appUsableSize.x < realScreenSize.x) {
|
||||
return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
|
||||
}
|
||||
|
||||
// navigation bar at the bottom
|
||||
if (appUsableSize.y < realScreenSize.y) {
|
||||
return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
|
||||
}
|
||||
|
||||
// navigation bar is not present
|
||||
return new Point();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Point getAppUsableScreenSize(@NonNull Context context) {
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = windowManager.getDefaultDisplay();
|
||||
Point size = new Point();
|
||||
display.getSize(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Point getRealScreenSize(@NonNull Context context) {
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = windowManager.getDefaultDisplay();
|
||||
Point size = new Point();
|
||||
display.getRealSize(size);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?colorSurface"
|
||||
tools:context=".fragments.PostViewV2Fragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
@ -16,6 +16,7 @@
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_grey_ripple"
|
||||
android:visibility="visible"
|
||||
app:icon="@drawable/ic_not_liked"
|
||||
app:iconGravity="textStart"
|
||||
@ -51,6 +52,7 @@
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/background_grey_ripple"
|
||||
app:icon="@drawable/ic_outline_comments_24"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="22dp"
|
||||
@ -90,6 +92,7 @@
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_grey_ripple"
|
||||
app:icon="?attr/actionModeShareDrawable"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
@ -104,6 +107,7 @@
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_grey_ripple"
|
||||
android:visibility="visible"
|
||||
app:icon="@drawable/ic_round_bookmark_border_24"
|
||||
app:iconGravity="textStart"
|
||||
@ -120,6 +124,7 @@
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_grey_ripple"
|
||||
android:visibility="visible"
|
||||
app:icon="@drawable/ic_download"
|
||||
app:iconGravity="textStart"
|
||||
|
Loading…
Reference in New Issue
Block a user