private void exitFullscreenAnimated(boolean animated) { if (!isVideoFullScreen()) return; swipeRefreshLayout.setVisibility(View.VISIBLE); // reset the values correctly viewer.setRotation(0.f); viewer.setScaleX(1.f); viewer.setScaleY(1.f); viewer.setTranslationX(0.f); // simulate scrolling to fix the clipping and translationY simulateScroll(); // go back to normal! FragmentActivity activity = getActivity(); activity.supportInvalidateOptionsMenu(); if (activity instanceof ToolbarActivity) { // show the toolbar again ((ToolbarActivity) activity).getScrollHideToolbarListener().reset(); } Screen.unlockOrientation(activity); }
private void realignFullScreen() { FullscreenParams params = new FullscreenParams(); viewer.setTranslationY(params.trY); viewer.setScaleX(params.scale); viewer.setScaleY(params.scale); }
@Override public void onCreate(Bundle savedState) { super.onCreate(savedState); setHasOptionsMenu(true); // get the item that is to be displayed. feedItem = getArguments().getParcelable(ARG_FEED_ITEM); if (savedState != null) { tags = Parceler.get(TagListParceler.class, savedState, "PostFragment.tags"); comments = Parceler.get(CommentListParceler.class, savedState, "PostFragment.comments"); } autoScrollTo = Optional.absent(); activeState() .compose(bindToLifecycleForeground()) .subscribe( active -> { if (viewer != null) { if (active) { viewer.playMedia(); } else { viewer.stopMedia(); } } if (!active) { exitFullscreenAnimated(false); } }); }
/** Positions the media view using the given offset (on the y axis) */ private void offsetMediaView(boolean viewerVisible, float offset) { if (viewerVisible) { // finally position the viewer viewer.setTranslationY(-offset); viewer.setVisibility(View.VISIBLE); // position the repost badge, if it is visible if (repostHint.getVisibility() == View.VISIBLE) { repostHint.setTranslationY(viewer.getPaddingTop() - repostHint.getPivotY() - offset); } } else { viewer.setVisibility(View.INVISIBLE); } }
/** * If the current post is a loop, we'll check if it is a loop. If it is, we will hide the little * video progress bar. */ private void hideProgressIfLoop(List<Tag> tags) { MediaView actualView = viewer != null ? viewer.getActualMediaView() : null; if (actualView instanceof AbstractProgressMediaView) { if (Iterables.any(tags, tag -> isLoopTag(tag.getTag()))) { ((AbstractProgressMediaView) actualView).setProgressEnabled(false); } } }
/** * Called with the downloaded post information. * * @param post The post information that was downloaded. */ private void onPostReceived(Post post) { swipeRefreshLayout.setRefreshing(false); // update from post displayTags(post.getTags()); displayComments(post.getComments()); if (rewindOnLoad) { rewindOnLoad = false; viewer.rewind(); } }
@OnOptionsItemSelected(R.id.action_zoom) public void enterFullscreen() { FragmentActivity activity = getActivity(); if (activity == null) return; if (isStaticImage(feedItem)) { boolean hq = settings.loadHqInZoomView(); Intent intent = ZoomViewActivity.newIntent(activity, feedItem, hq); startActivity(intent); } else { FullscreenParams params = new FullscreenParams(); ObjectAnimator.ofPropertyValuesHolder( viewer, ofFloat(View.ROTATION, params.rotation), ofFloat(View.TRANSLATION_Y, params.trY), ofFloat(View.SCALE_X, params.scale), ofFloat(View.SCALE_Y, params.scale)) .setDuration(500) .start(); repostHint.setVisibility(View.GONE); // hide content below swipeRefreshLayout.setVisibility(View.GONE); if (activity instanceof ToolbarActivity) { // hide the toolbar if required necessary ((ToolbarActivity) activity).getScrollHideToolbarListener().hide(); } viewer.setClipBoundsCompat(null); activity.supportInvalidateOptionsMenu(); registerExitFullscreenListener(); // forbid orientation changes while in fullscreen Screen.lockOrientation(activity); } }
/** * Registers a tap listener on the given viewer instance. The listener is used to handle * double-tap-to-vote events from the view. * * @param viewer The viewer to register the tap listener to. */ private void registerTapListener(MediaView viewer) { viewer.setTapListener( new MediaView.TapListener() { final boolean isImage = isStaticImage(feedItem); @Override public boolean onSingleTap() { if (isImage && settings.singleTapForFullscreen()) { enterFullscreen(); } return true; } @Override public boolean onDoubleTap() { if (settings.doubleTapToUpvote()) { infoLineView.getVoteView().triggerUpVoteClicked(); } return true; } }); }
private void onTransitionEnds() { if (viewer != null && content != null) { viewer.onTransitionEnds(); } }
private void initializeMediaView() { int padding = AndroidUtility.getActionBarContentOffset(getActivity()); // initialize a new viewer fragment MediaUri uri = MediaUri.of(feedItem.getId(), UriHelper.of(getContext()).media(feedItem)); if (!uri.isLocal() && AndroidUtility.isOnMobile(getActivity())) { Settings.ConfirmOnMobile confirmOnMobile = settings.confirmPlayOnMobile(getContext()); if (confirmOnMobile == Settings.ConfirmOnMobile.ALL) { uri = uri.withDelay(true); } else if (confirmOnMobile == Settings.ConfirmOnMobile.VIDEO && uri.getMediaType() != MediaUri.MediaType.IMAGE) { uri = uri.withDelay(true); } } viewer = MediaViews.newInstance( getActivity(), uri, () -> { // mark this item seen. We do that in a background thread seenService.markAsSeen(feedItem); }); // inform viewer over fragment lifecycle events! MediaViews.adaptFragmentLifecycle(lifecycle(), viewer); registerTapListener(viewer); PreviewInfo previewInfo = this.previewInfo != null ? this.previewInfo : getPreviewInfoFromCache(); if (previewInfo != null) { viewer.setPreviewImage(previewInfo, "TransitionTarget-" + feedItem.getId()); if (Sdk.isAtLeastLollipop()) { viewer.postDelayed(this::onTransitionEnds, 350); } else { viewer.post(this::onTransitionEnds); } } else { viewer.post(this::onTransitionEnds); } // add views in the correct order int idx = playerContainer.indexOfChild(voteAnimationIndicator); playerContainer.addView(viewer, idx); if (tabletLayout) { viewer.setLayoutParams( new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER)); } else { viewer.setPadding(0, padding, 0, 0); // we add a placeholder to the first element of the recycler view. // this placeholder will mirror the size of the viewer. PlaceholderView placeholder = new PlaceholderView(); adapter.addAdapter(SingleViewAdapter.ofView(placeholder)); RxView.layoutChanges(viewer) .subscribe( event -> { int newHeight = viewer.getMeasuredHeight(); if (newHeight != placeholder.fixedHeight) { placeholder.fixedHeight = newHeight; if (Sdk.isAtLeastKitKat()) { placeholder.requestLayout(); } else { // it looks like a requestLayout is not honored on pre kitkat devices // if already in a layout pass. placeholder.post(placeholder::requestLayout); } if (isVideoFullScreen()) { realignFullScreen(); } } }); RxView.layoutChanges(placeholder) .subscribe( event -> { // simulate scroll after layouting the placeholder to // reflect changes to the viewers clipping. simulateScroll(); }); } }
public void mediaHorizontalOffset(int offset) { viewer.setTranslationX(offset); }