private void setupTransitions() { // grab the position that the search icon transitions in *from* // & use it to configure the return transition setEnterSharedElementCallback(new SharedElementCallback() { @Override public void onSharedElementStart( List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { if (sharedElements != null && !sharedElements.isEmpty()) { View searchIcon = sharedElements.get(0); if (searchIcon.getId() != R.id.searchback) return; int centerX = (searchIcon.getLeft() + searchIcon.getRight()) / 2; CircularReveal hideResults = (CircularReveal) TransitionUtils.findTransition( (TransitionSet) getWindow().getReturnTransition(), CircularReveal.class, R.id.results_container); if (hideResults != null) { hideResults.setCenter(new Point(centerX, 0)); } } } }); }
@TargetApi(21) private void setCallback(final int chosenPosition) { DataManager.getInstance().setPosition(chosenPosition); ((AppCompatActivity) context).setExitSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { int pos = DataManager.getInstance().getPosition(); if (chosenPosition != pos && names.size() > 0) { sharedElements.put(names.get(0), contentViewCache.get(pos)); } ((AppCompatActivity) context).setExitSharedElementCallback((SharedElementCallback) null); } }); }
@TargetApi(21) private void setSharedElementCallback(final View view) { SharedElementCallback callback = new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { names.clear(); sharedElements.clear(); names.add(view.getTransitionName()); sharedElements.put(view.getTransitionName(), view); } }; setEnterSharedElementCallback(callback); }
@Override void handleElementOnClick(final View view) { final int itemPosition = getRecyclerView().getChildAdapterPosition(view); VideoOnDemand item = getElements().get(itemPosition); if (activity instanceof VODActivity) { ((VODActivity) activity).startNewVOD(item); } else { Intent intent = VODActivity.createVODIntent(item, getContext()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { intent.putExtra(getContext().getString(R.string.stream_preview_url), item.getMediumPreview()); intent.putExtra(getContext().getString(R.string.stream_preview_alpha), hasVodBeenWatched(item.getVideoId()) ? VOD_WATCHED_IMAGE_ALPHA : 1.0f); final View sharedView = view.findViewById(R.id.image_stream_preview); sharedView.setTransitionName(getContext().getString(R.string.stream_preview_transition)); final ActivityOptionsCompat options = ActivityOptionsCompat. makeSceneTransitionAnimation(activity, sharedView, getContext().getString(R.string.stream_preview_transition)); activity.setExitSharedElementCallback(new SharedElementCallback() { @SuppressLint("NewApi") @Override public void onSharedElementEnd(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { super.onSharedElementEnd(sharedElementNames, sharedElements, sharedElementSnapshots); sharedView.animate().alpha(VOD_WATCHED_IMAGE_ALPHA).setDuration(300).start(); activity.setExitSharedElementCallback(null); } }); activity.startActivity(intent, options.toBundle()); } else { getContext().startActivity(intent); activity.overridePendingTransition(R.anim.slide_in_bottom_anim, R.anim.fade_out_semi_anim); } } }
private void setup() { String name = getIntent().getStringExtra(KEY_ID); if (name != null) { setEnterSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { sharedElements.put(ELEMENT_NAME, mImageView); } }); } }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_rv, null); mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view); int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing_card); mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels)); mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 1)); mRecyclerView.setHasFixedSize(true); setUpList(); getActivity().setExitSharedElementCallback(new SharedElementCallback() { @Override public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, RectF screenBounds) { int bitmapWidth = Math.round(screenBounds.width()); int bitmapHeight = Math.round(screenBounds.height()); Bitmap bitmap = null; if (bitmapWidth > 0 && bitmapHeight > 0) { Matrix matrix = new Matrix(); matrix.set(viewToGlobalMatrix); matrix.postTranslate(-screenBounds.left, -screenBounds.top); bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.concat(matrix); sharedElement.draw(canvas); } return bitmap; } }); return v; }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_rv, null); mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view); int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing_card); mRecyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels)); mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2)); mRecyclerView.setHasFixedSize(true); setUpList(); getActivity().setExitSharedElementCallback(new SharedElementCallback() { @Override public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, RectF screenBounds) { int bitmapWidth = Math.round(screenBounds.width()); int bitmapHeight = Math.round(screenBounds.height()); Bitmap bitmap = null; if (bitmapWidth > 0 && bitmapHeight > 0) { Matrix matrix = new Matrix(); matrix.set(viewToGlobalMatrix); matrix.postTranslate(-screenBounds.left, -screenBounds.top); bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.concat(matrix); sharedElement.draw(canvas); } return bitmap; } }); return v; }
private static SharedElementCallback createCallback(SharedElementCallback21 callback) { SharedElementCallback newListener = null; if (callback != null) { newListener = new SharedElementCallbackImpl(callback); } return newListener; }
private void setupTransitions() { // grab the position that the search icon transitions in *from* // & use it to configure the return transition if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { setEnterSharedElementCallback(new SharedElementCallback() { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onSharedElementStart( List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { if (sharedElements != null && !sharedElements.isEmpty()) { View searchIcon = sharedElements.get(0); if (searchIcon.getId() != R.id.searchback) return; int centerX = (searchIcon.getLeft() + searchIcon.getRight()) / 2; CircularReveal hideResults = (CircularReveal) TransitionUtils.findTransition( (TransitionSet) getWindow().getReturnTransition(), CircularReveal.class, R.id.results_container); if (hideResults != null) { hideResults.setCenter(new Point(centerX, 0)); } } } }); // focus the search view once the transition finishes getWindow().getEnterTransition().addListener( new TransitionUtils.TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { searchView.requestFocus(); ImeUtils.showIme(searchView); } }); } else { searchView.requestFocus(); ImeUtils.showIme(searchView); } }
public static SharedElementCallback createSharedElementReenterCallback( @NonNull Context context) { final String shotTransitionName = context.getString(R.string.transition_shot); final String shotBackgroundTransitionName = context.getString(R.string.transition_shot_background); return new SharedElementCallback() { /** * We're performing a slightly unusual shared element transition i.e. from one view * (image in the grid) to two views (the image & also the background of the details * view, to produce the expand effect). After changing orientation, the transition * system seems unable to map both shared elements (only seems to map the shot, not * the background) so in this situation we manually map the background to the * same view. */ @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { if (sharedElements.size() != names.size()) { // couldn't map all shared elements final View sharedShot = sharedElements.get(shotTransitionName); if (sharedShot != null) { // has shot so add shot background, mapped to same view sharedElements.put(shotBackgroundTransitionName, sharedShot); } } } }; }
static void clearSharedElementsOnReturn(@NonNull final BaseActivity activity) { activity.setEnterSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(final List<String> names, final Map<String, View> sharedElements) { super.onMapSharedElements(names, sharedElements); if (activity.isFinishingAfterTransition()) { names.clear(); sharedElements.clear(); } } }); }
private void initTransitions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { postponeEnterTransition(); setEnterSharedElementCallback(new SharedElementCallback() { @SuppressLint("NewApi") @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { super.onMapSharedElements(names, sharedElements); if (mAdapter.getRegisteredFragment(mPosition) != null) { names.clear(); sharedElements.clear(); View view = ((ImageFragment) mAdapter.getRegisteredFragment(mPosition)).mImage; names.add(view.getTransitionName()); sharedElements.put(view.getTransitionName(), view); } } }); } // mPager.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { // @SuppressLint("NewApi") // public boolean onPreDraw() { // mPager.getViewTreeObserver().removeOnPreDrawListener(this); // startPostponedEnterTransition(); // return true; // } // }); }
private void initTransitions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { setExitSharedElementCallback(new SharedElementCallback() { @SuppressLint("NewApi") @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { super.onMapSharedElements(names, sharedElements); if (!isReenterTransition) { return; } isReenterTransition = false; names.clear(); sharedElements.clear(); final PostFragment postFragment = (PostFragment) mAdapter.getRegisteredFragment(mPager.getCurrentItem()); final RecyclerView recyclerView = postFragment.mRecyclerView; View sharedView = ((PostImagesRecyclerViewAdapter.ViewHolder) recyclerView.findViewHolderForPosition(mImagePosition)).getImage(); names.add(sharedView.getTransitionName()); sharedElements.put(sharedView.getTransitionName(), sharedView); } }); Fade fadeExit = new Fade(); fadeExit.addTarget(R.id.text_post_title); fadeExit.addTarget(R.id.button_show_gallery); fadeExit.addTarget(R.id.recycler_post_images); fadeExit.addTarget(R.id.image_post_author); fadeExit.addTarget(R.id.bottom_shadow_post); fadeExit.addTarget(R.id.toolbar); getWindow().setExitTransition(fadeExit); } }
static SharedElementCallback createSharedElementReenterCallback( @NonNull Context context) { final String shotTransitionName = context.getString(R.string.transition_shot); final String shotBackgroundTransitionName = context.getString(R.string.transition_shot_background); return new SharedElementCallback() { /** * We're performing a slightly unusual shared element transition i.e. from one view * (image in the grid) to two views (the image & also the background of the details * view, to produce the expand effect). After changing orientation, the transition * system seems unable to map both shared elements (only seems to map the shot, not * the background) so in this situation we manually map the background to the * same view. */ @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { if (sharedElements.size() != names.size()) { // couldn't map all shared elements final View sharedShot = sharedElements.get(shotTransitionName); if (sharedShot != null) { // has shot so add shot background, mapped to same view sharedElements.put(shotBackgroundTransitionName, sharedShot); } } } }; }
private void setupHero() { String name = getIntent().getStringExtra(KEY_ID); mHero = null; if (name != null) { mHero = (ImageView) findViewById(getIdForKey(name)); setEnterSharedElementCallback(new SharedElementCallback() { @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { sharedElements.put("hero", mHero); } }); } }
private static SharedElementCallback createCallback(SharedElementCallback21 sharedelementcallback21) { SharedElementCallbackImpl sharedelementcallbackimpl = null; if (sharedelementcallback21 != null) { sharedelementcallbackimpl = new SharedElementCallbackImpl(sharedelementcallback21); } return sharedelementcallbackimpl; }
private static SharedElementCallback createCallback(SharedElementCallback21 callback) { if (callback != null) { return new SharedElementCallbackImpl(callback); } return null; }
@Override void handleElementOnClick(final View view) { int itemPosition = getRecyclerView().getChildAdapterPosition(view); final ChannelInfo item = getElements().get(itemPosition); final StreamerInfoViewHolder vh = (StreamerInfoViewHolder) getRecyclerView().getChildViewHolder(view); final PreviewTarget previewTarget = getTargets().get(vh.getTargetsKey()); // Create intent for opening StreamerInfo activity. Send the StreamerInfo object with // the intent, and flag it to make sure it creates a new task on the history stack final Intent intent = new Intent(getContext(), ChannelActivity.class); intent.putExtra(getContext().getResources().getString(R.string.channel_info_intent_object), item); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { View sharedView = view.findViewById(R.id.profileLogoImageView); sharedView.setTransitionName(getContext().getString(R.string.streamerInfo_transition)); final ActivityOptionsCompat options = ActivityOptionsCompat. makeSceneTransitionAnimation(activity, sharedView, getContext().getString(R.string.streamerInfo_transition)); activity.setExitSharedElementCallback(new SharedElementCallback() { @SuppressLint("NewApi") @Override public void onSharedElementEnd(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { super.onSharedElementEnd(sharedElementNames, sharedElements, sharedElementSnapshots); if (!sharedElements.isEmpty() && sharedElements.get(0) != null && previewTarget != null) { View element = sharedElements.get(0); Animation anim = new RoundImageAnimation(element.getWidth()/2, 0, (ImageView) element, previewTarget.getPreview()); anim.setDuration(200); anim.setInterpolator(new DecelerateInterpolator()); view.startAnimation(anim); } activity.setExitSharedElementCallback(null); } }); activity.startActivity(intent, options.toBundle()); } else { getContext().startActivity(intent); if(activity != null) { activity.overridePendingTransition(R.anim.slide_in_right_anim, R.anim.fade_out_semi_anim); } } }
public static SharedElementCallback getCallback(RoundingImageTransitionValues values) { return new BaseSharedElementCallback(values); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); final boolean useNavDrawer = Config.get().navDrawerModeEnabled(); if (useNavDrawer) { setContentView(R.layout.activity_main_drawer); } else { setContentView(R.layout.activity_main); } ButterKnife.bind(this); setSupportActionBar(mToolbar); setupPages(); setupPager(); if (useNavDrawer) { setupNavDrawer(); } else { setupTabs(); } // Restore last selected page, tab/nav-drawer-item if (Config.get().persistSelectedPage()) { int lastPage = PreferenceManager.getDefaultSharedPreferences(MainActivity.this) .getInt("last_selected_page", 0); if (lastPage > mPager.getAdapter().getCount() - 1) { lastPage = 0; } mPager.setCurrentItem(lastPage); if (mNavView != null) { invalidateNavViewSelection(lastPage); } } dispatchFragmentUpdateTitle(!useNavDrawer); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { setExitSharedElementCallback( new SharedElementCallback() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { if (isReentering) { WallpapersFragment frag = (WallpapersFragment) getFragmentManager().findFragmentByTag("page:" + mPager.getCurrentItem()); final RecyclerView recyclerView = frag.getRecyclerView(); View item = recyclerView.findViewWithTag("view_" + reenterPos); View image = item.findViewById(R.id.image); names.clear(); names.add(image.getTransitionName()); sharedElements.clear(); sharedElements.put(image.getTransitionName(), image); isReentering = false; } } }); } processIntent(getIntent()); }
@NonNull private DesignerNewsStoryHolder createDesignerNewsStoryHolder(ViewGroup parent) { final DesignerNewsStoryHolder holder = new DesignerNewsStoryHolder(layoutInflater.inflate( R.layout.designer_news_story_item, parent, false), pocketIsInstalled); holder.itemView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { final Story story = (Story) getItem(holder.getAdapterPosition()); CustomTabActivityHelper.openCustomTab(host, DesignerNewsStory.getCustomTabIntent(host, story, null).build(), Uri.parse(story.url)); } } ); holder.comments.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View commentsView) { final Intent intent = new Intent(); intent.setClass(host, DesignerNewsStory.class); intent.putExtra(DesignerNewsStory.EXTRA_STORY, (Story) getItem(holder.getAdapterPosition())); ReflowText.addExtras(intent, new ReflowText.ReflowableTextView(holder.title)); setGridItemContentTransitions(holder.itemView); // on return, fade the pocket & comments buttons in host.setExitSharedElementCallback(new SharedElementCallback() { @Override public void onSharedElementStart(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { host.setExitSharedElementCallback(null); notifyItemChanged(holder.getAdapterPosition(), HomeGridItemAnimator.STORY_COMMENTS_RETURN); } }); final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(host, Pair.create((View) holder.title, host.getString(R.string.transition_story_title)), Pair.create(holder.itemView, host.getString(R.string.transition_story_title_background)), Pair.create(holder.itemView, host.getString(R.string.transition_story_background))); host.startActivity(intent, options.toBundle()); } }); if (pocketIsInstalled) { holder.pocket.setImageAlpha(178); // grumble... no xml setter, grumble... holder.pocket.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View view) { PocketUtils.addToPocket(host, ((Story) getItem(holder.getAdapterPosition())).url); // notify changed with a payload asking RV to run the anim notifyItemChanged(holder.getAdapterPosition(), HomeGridItemAnimator.ADD_TO_POCKET); } }); } return holder; }
@NonNull private DesignerNewsStoryHolder createDesignerNewsStoryHolder(ViewGroup parent) { final DesignerNewsStoryHolder holder = new DesignerNewsStoryHolder(layoutInflater.inflate( R.layout.designer_news_story_item, parent, false), pocketIsInstalled); holder.itemView.setOnClickListener( v -> { final Story story = (Story) getItem(holder.getAdapterPosition()); CustomTabActivityHelper.openCustomTab(host, DesignerNewsStory.getCustomTabIntent(host, story, null).build(), Uri.parse(story.url)); } ); holder.comments.setOnClickListener(commentsView -> { final Intent intent = new Intent(); intent.setClass(host, DesignerNewsStory.class); intent.putExtra(DesignerNewsStory.EXTRA_STORY, (Story) getItem(holder.getAdapterPosition())); ReflowText.addExtras(intent, new ReflowText.ReflowableTextView(holder.title)); setGridItemContentTransitions(holder.itemView); // on return, fade the pocket & comments buttons in host.setExitSharedElementCallback(new SharedElementCallback() { @Override public void onSharedElementStart(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) { host.setExitSharedElementCallback(null); notifyItemChanged(holder.getAdapterPosition(), HomeGridItemAnimator.STORY_COMMENTS_RETURN); } }); final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(host, Pair.create((View) holder.title, host.getString(R.string.transition_story_title)), Pair.create(holder.itemView, host.getString(R.string.transition_story_title_background)), Pair.create(holder.itemView, host.getString(R.string.transition_story_background))); host.startActivity(intent, options.toBundle()); }); if (pocketIsInstalled) { holder.pocket.setImageAlpha(178); // grumble... no xml setter, grumble... holder.pocket.setOnClickListener(view -> { PocketUtils.addToPocket(host, ((Story) getItem(holder.getAdapterPosition())).url); // notify changed with a payload asking RV to run the anim notifyItemChanged(holder.getAdapterPosition(), HomeGridItemAnimator.ADD_TO_POCKET); }); } return holder; }
public void setEnterSharedElementCallback(SharedElementCallback callback) { mHostActivity.setEnterSharedElementCallback(callback); }
public void setExitSharedElementCallback(SharedElementCallback callback) { mHostActivity.setExitSharedElementCallback(callback); }