2016-04-21 8 views
2

1つのイメージビューをクリックすると、複数のImageViewがある垂直スクロールビューにLinearLayoutがあります(アクティビティ1)からフルスクリーンギャラリー(アクティビティ2)へのトランジションアニメーションを実行すると、ギャラリーにはビューページャーがあり、/left ..ギャラリー内の別の画像にスワイプして、現在の表示可能な画像(アクティビティ2)を押し戻すと、アクティビティ1の開始位置に戻って(再び移行アニメーションを使用して)復元されます。問題は画像それが元の位置に到達するまで復元されてから消え、別のイメージが表示されます(これはすでに議論するにはあまりにも複雑です)。イメージを添付しました。アクティビティトランジションアニメーションの要素を別の位置に復元する方法はありますか?

enter image description here

Activity1レイアウト:

<LinearLayout> 
    <ImageView /> 
    <ImageView /> 
    <ImageView /> 
    <ImageView /> 
    <ImageView /> 
    <ImageView /> 
</LinearLayout> 

Acivity2(ギャラリー)レイアウト:アクティビティ1から任意の画像をクリックで

<?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> 

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 George Mountのコードはうまくいきましたが、1つのトリックがあります。主に、このコールバックはトランジションが開始されたときと途中で2回呼び出されるため、位置をリセットして帰り道として、次のとおりです。

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)); 
       } 
      } 
     }); 
    } 

public void openGallery(int pos, ArrayList<String> images, View view) 
    { 
     // reset the return position 
     position = -1; 
    } 

と私のフラグメントに次のように:

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; 
     } 
    } 
} 

と私(Activity1)に次の

@Override 
public void onActivityReenter(int resultCode, Intent data) 
{ 
    ArticleDetailsFragment fragment = (ArticleDetailsFragment) getSupportFragmentManager().findFragmentByTag(ArticleDetailsFragment.class.getSimpleName()); 
    if (fragment != null) { 
     fragment.onActivityReenter(resultCode, data); 
    } 
} 

アップデート2 ジョージがすでに移行に関するいくつかの記事を書いたようだが、彼らが人気でもGoogleの検索結果に表示されないなら、そうIここでそれらを共有することが有用であるだろうと考えた:

https://halfthought.wordpress.com/2014/12/

https://halfthought.wordpress.com/2014/11/

https://halfthought.wordpress.com/2015/06/

答えて

4

まず、通話に間違ったトランジション名が使用されています。 ActivityOptions.makeSceneTransitionAnimationの名前は、アクティビティ2のビューの名前です。アクティビティ1で任意の名前を使用でき、フレームワークは名前をマップします。この方法で、多対1マッピングを実行できます。あなたがイメージのリストビューを持っているし、あなたがそれらのいずれかをクリックした場合、あなたのケースでのアクティビティ2に単一のイメージに移行することができるはずです。

<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> 

を、あなたが電話をかけるとき:

ActivityOptionsCompat options = 
    ActivityOptionsCompat.makeSceneTransitionAnimation(
      getActivity(), view, Activity2.IMAGE_VIEW_NAME); 

あなたのアクティビティ2には、ActivityNameのtransitionNameを持つImageViewが必要です。IMAGE_VIEW_NAME。

しかし、それはあなたが求めていたものではありません。

途中で別の要素を共有しているので、共有要素のマッピングをオーバーライドする必要があります。あなたの状況に応じて、いくつかの方法でこれを行うことができます。最良の方法は、Activity1の活動1.

の内の共有要素のマッピングを変更する必要があり、SharedElementCallbackを設定:だから

setExitSharedElementCallback(new SharedElementCallback() { 
    @Override 
    public void onMapSharedElements(List<String> names, 
     Map<String, View> sharedElements) { 
     sharedElements.put(Activity2.IMAGE_VIEW_NAME, newSharedElement); 
    } 
} 

、どのようにあなたはそれがに戻るべきかを表示知っているのですか? startActivityForResultを使用して、呼び出されたアクティビティが正しいビューを返すようにする必要があります。ここでは、setResultをインテントで呼び出すときに、同じEXTRA_POSITIONフィールドを使用すると仮定します。あなたは、あなたが必要なものを行うにはonActivityReenterを上書きすることができます:あなたはこの時点で行うことができます

@Override 
public void onActivityReenter(int resultCode, Intent data) { 
    int position = data.getIntExtra(GalleryActivity.EXTRA_POSITION, -1); 
    if (position != -1) { 
     // I'm assuming child index is the same as position here. 
     newSharedElement = mLinearLayout.getChildAt(position); 
    } 
} 

他の事は、ビューが表示されているような位置にビューをスクロールしています。 ListViewやRecyclerViewなどのリサイクルコンテナを使用している場合は、postponeEnterTransitionstartPostponedEnterTransitionを使用して、トランジションの開始前にビューが配置されていることを確認する必要があります。

+0

質問を投稿したあと、setExitSharedElementCallback(new SharedElementCallback(){...これが試行され、うまくいけば質問を正しいとマークします。) – Shehabix

+0

ありがとう@George Mount、あなたは火格子の助けを借りていました.Googleに既に参加していて、この特定の部分で作業していたので、ドキュメンテーションの担当者に、トランジションとシーンに関連する部分を改善するよう依頼してください。ほぼ2年前にリリースされましたが、 – Shehabix

関連する問題