android - How to restore element in Activity Transition Animation to different position? -
i have linearlayout in vertical scrollview multiple imageviews, when click on 1 image view transition animation (activity 1) full screen gallery (activity 2), gallery has view pager user can swipe right / left .. when user swipes different image in gallery , presses current visible image in (activity 2) restored (again using transition animation) starting position in activity 1, problem image restored until reaches old position , disappears , reveals different image (since complicated discuss) attached image.
activity1 layout:
<linearlayout> <imageview /> <imageview /> <imageview /> <imageview /> <imageview /> <imageview /> </linearlayout>
acivity2 (gallery) layout:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <android.support.v7.widget.appcompatimageview android:id="@+id/animation_image" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/transparent" android:scaletype="fitcenter" android:src="@drawable/placeholder" android:transitionname="@string/transition_article_image_gallery" android:layout_centerinparent="true" /> <viewpager android:id="@+id/gallery_pager" android:layout_width="match_parent" android:layout_height="match_parent"/> </relativelayout>
on click on image activity 1:
public void opengallery(int position, arraylist<string> images, view view) { intent intent = new intent(getactivity(), galleryactivity.class); intent.putstringarraylistextra(galleryactivity.extra_gallery_images, images); intent.putextra(galleryactivity.extra_position, position); if (build.version.sdk_int >= build.version_codes.lollipop) { activityoptionscompat options = activityoptionscompat.makescenetransitionanimation( getactivity(), new pair<>(view, target_element_transition_name_attrib_value) ); activitycompat.startactivity(getactivity(), intent, options.tobundle()); } else { getactivity().startactivity(intent); } }
update code george mount, worked there's 1 trick, it's callback called 2 times when transition starts , on way back, it's important reset position , check on way follows:
if (build.version.sdk_int >= build.version_codes.lollipop) { getdetailsactivity().setexitsharedelementcallback(new sharedelementcallback() { @targetapi(build.version_codes.lollipop) @override public void onmapsharedelements(list<string> names, map<string, view> sharedelements) { if (position != -1) { sharedelements.put(getstring(r.string.transition_article_image_gallery), articleimagesholder.getchildat(position)); } } }); }
and
public void opengallery(int pos, arraylist<string> images, view view) { // reset return position position = -1; }
and following in fragment:
public void onactivityreenter(int resultcode, intent data) { if (resultcode == activity.result_ok) { int pos = data.getintextra(extra_image_position, -1); if (pos != -1) { position = pos; } } }
and following in (activity1):
@override public void onactivityreenter(int resultcode, intent data) { articledetailsfragment fragment = (articledetailsfragment) getsupportfragmentmanager().findfragmentbytag(articledetailsfragment.class.getsimplename()); if (fragment != null) { fragment.onactivityreenter(resultcode, data); } }
update 2 seems george wrote articles transitions, they're not popular nor showing in google search results, thought it'd useful share them here:
https://halfthought.wordpress.com/2014/12/
first, you're using transition names wrong in call. name in activityoptions.makescenetransitionanimation
name of view in activity 2. can use name want in activity 1 , framework map names. way can many-to-one mapping. example, if have list view of images , click on 1 of them, should able transition single image in activity 2. in case:
<linearlayout> <imageview android:transitionname="image1" /> <imageview android:transitionname="image2" /> <imageview android:transitionname="image3" /> <imageview android:transitionname="image4" /> <imageview android:transitionname="image5" /> <imageview android:transitionname="image6" /> </linearlayout>
and when make call:
activityoptionscompat options = activityoptionscompat.makescenetransitionanimation( getactivity(), view, activity2.image_view_name);
and in activity 2, should have imageview transitionname of activity2.image_view_name.
but that's not asking about.
because you're sharing different element on way back, you're going have override shared element mappings. can in couple of ways in circumstances. best way requires change mapping of shared elements in activity 1.
in activity1, set sharedelementcallback:
setexitsharedelementcallback(new sharedelementcallback() { @override public void onmapsharedelements(list<string> names, map<string, view> sharedelements) { sharedelements.put(activity2.image_view_name, newsharedelement); } }
so, how know view should return to? should use startactivityforresult , called activity can return correct view you. here, assume use same extra_position field when call setresult intent. can override onactivityreenter
need:
@override public void onactivityreenter(int resultcode, intent data) { int position = data.getintextra(galleryactivity.extra_position, -1); if (position != -1) { // i'm assuming child index same position here. newsharedelement = mlinearlayout.getchildat(position); } }
the other thing can @ point scroll view position such view visible. if you're using recycling container listview or recyclerview, you'll need use postponeentertransition
, startpostponedentertransition
ensure views laid out prior starting transition.
Comments
Post a Comment