Fresco: 共有要素の移行

作成日 2015年03月28日  ·  57コメント  ·  ソース: facebook/fresco

共有要素の移行が機能していないようです。

android5.0を搭載したモトローラデバイスでテスト済み

最も参考になるコメント

正常に機能する、私が使用する回避策は次のとおりです。
https://github.com/bumptech/glide

全てのコメント57件

詳細を教えてください。 あなたは正確に何をしようとしましたか、そして代わりに何が起こりましたか?

新しいAndroidバージョンのlollipopでは、アクティビティ間の共有要素遷移としてImageViewを使用できます。 その場合、画像は1つのアクティビティから次のアクティビティにスモス遷移します。 SimpleDraweeViewを使用すると、表示されなくなります。

それをテストするコードは次のようになります。

アプリのテーマ:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
    </style>

Activity1 Layout.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/image"
        android:layout_width="@dimen/size_1"
        android:layout_height="@dimen/size_1"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"/>

</RelativeLayout>

Activity2 Layout.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/image"
        android:layout_width="@dimen/size_2"
        android:layout_height="@dimen/size_2"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:transitionName="image_transition"/>

</RelativeLayout>

2番目のアクティビティを開始するためのコード:

    Intent intent = new Intent(activity1, Activity2.class);
    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(activity1, simpleDraweeView1, "image_transition");
    activity1.startActivity(intent, options.toBundle());

このコードは、画像が移動し、アクティビティ1の左上隅からアクティビティ2の右下隅にサイズ変更されるアクティビティ間で移行する必要があります。ネットワークから画像を読み込む同様のコードをテストしましたが、表示されません。アニメーション。

これも実現していると思いますhttps://github.com/facebook/fresco/issues/99

これは、移行中にビューが取得するアタッチ/デタッチイベントに関係していると思われます。 それを調査する必要があります。

これも確認できます。 共有要素の遷移はFrescoで壊れているようです。 これは今後非常に重要な機能であるため、これを修正できれば素晴らしいと思います。

私にも起こりました。 transtitionName xml attrをSimpleDraweeViewに設定すると、setImageUri()メソッドが機能しなくなりました

これに関する更新はありますか?

FadeDrawableが実際の画像のアニメーションを終了した後、ログがあります。
com.facebook.samples.comparison D / ViewRootImpl:changeCanvasOpacity:opaque = false

changeCanvasOpacityにより、画像が描画されない可能性があります。

バグは修正されていますか? それは私のプロジェクトにとっても非常に重要です。 :)

パッケージorg.goodev.droidddle.drawee;

インポートcom.facebook.drawee.generic.GenericDraweeHierarchy;
インポートcom.facebook.drawee.view.SimpleDraweeView;

android.content.Contextをインポートします。
android.graphics.Matrixをインポートします。
android.util.AttributeSetをインポートします。

パブリッククラスTranslateDraweeViewはSimpleDraweeViewを拡張します{
public TranslateDraweeView(Context context){
super(context);
}

public TranslateDraweeView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public TranslateDraweeView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public TranslateDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
    super(context, hierarchy);
}

// looks like overwrite this method can fix this issue
// but still don't figure out why
public void animateTransform(Matrix matrix) {
    invalidate();
}

}

@goodev上書きするそのような方法はありません。

@ shumin0809このメソッドを追加するだけです。これは、遷移のパブリックメソッドを非表示にします。

SharedElementTransitionsの動作は異なりますが、バグがあります。 これが同じ問題なのか、関連する問題なのか、別の問題なのかわからない。

_複製_
SharedElementTransitionのかなり標準的な設定:

  • GridLayoutManagerが多数の画像をSimpleDraweeViewsとして表示し、ビューホルダーバインドメソッドでそれらにtransitionNameを動的に設定するフラグメント内のRecyclerView(URIも設定しています)
  • OnClickは、単一のSimpleDraweeビューで別のフラグメントへのトランジションを起動し、同じtransitionNameも動的に設定されます

_期待される_
通常のImageView(scaleTypeが一致する場合)の場合、フラグメント間の共有リソースのシームレスなアニメーション

_観察された_
SharedElementTransitionが発生しますが、ターゲット画像が表示される前にちらつきがあります(ターゲット画像が十分に早く設定されていないようです)

_メモ_
Webとディスクから画像をロードしようとしましたが、トランジションを起動する前に画像がロードされてキャッシュに保存されます。 ターゲットフラグメントのコードは、まったく同じuriをプルしています。 私はパイプラインを直接使用しようとしていじくり回しました(そして多くを学びました)が、結果に影響を与えることができませんでした。

_セットアップ_
デバイス:Nexus5とNexus7(2013)、どちらもAndroid 5.1.1(API 22)を実行
最新のライブラリとツール:fresco(0.5.0)、Android Studio(1.3 Preview 3 EAP.0)、compileSdk(22)、ビルドツール(22.0.1)

_実現_
この投稿を書いている間、私は関連するかもしれない2つのことに気づきました:

  • 2つのDraweeはサイズが異なります(これは標準のImageViewを移行する場合の問題ではなく、ターゲットの寸法を設定するプリフェッチについては何も覚えていません)
  • メモリから、コードのどこかにコンテキストとしてフラグメントをフレスコ画で渡していると思います。おそらく、2つのフラグメントがそれぞれ独自のキャッシュを持っていることを意味しますか?

@ jorgemf-投稿されたコードには、アクティビティ1レイアウトで設定された一致するtransitionName属性は必要ありませんか? https://developer.android.com/training/material/animations.html

_共有要素でアクティビティを開始します_
..。
4- android:transitionName属性を使用して、両方のレイアウトの共有要素に共通の名前を割り当てます。

私の問題では、移行を延期する必要があるかもしれません。 今日はこれを見ていきます:
http://www.androiddesignpatterns.com/2015/03/activity-postponed-shared-element-transitions-part3b.html

私も同じ問題を抱えています。 fresco 0.5.3とSimpleDraweeViewを使用していますが、attr " android:transitionName "で画像が読み込まれません。 フレスコを使った解決策を知っている人はいますか?

@jorgemf Activity1 Layout.xmlで「android-background」を設定すると、完全には機能しませんが、機能します。
私は自分のテストでそれを設定しました: android:background = "@ android:color / transparent "

@LuizGadao背景を設定すると、ライブラリのすべての利点が失われます。 インターネットからダウンロードした画像に欲しいので無意味だと思います。 背景としての静的リソース用ではありません。
いくつかのライブラリをテストした後、ピカソは私のためにうまく機能しています。 全く問題ありません。

@jorgemf私はあなたに同意します。 それが機能するためのハックにすぎません。

これに関するニュースはありますか?

@LuizGadao回避策XMLの例を投稿できますか?

この問題を報告していただきありがとうございます。しばらくお待ちください。 この問題に関する最新情報について、コアチームに通知しました。 30日以内に回答をお待ちしております。そうでない場合は、問題が解決される可能性があります。

これに関するニュースはありますか?

PS:
@goodevが提供する機能しません。 ReenterTransitionが間違った位置から始まります。

boxcounterが言ったように、TraslateDraweeViewはHTCOneM8でも機能しません。

ChangeImageTransform Transitionを使用している場合、ChangeImageTransformがImageViewのマトリックスをアニメーション化しているため、共有要素の遷移は失敗すると思います。これは、デフォルトではDraweeViewをサポートしていないと思います。

私が遭遇した問題は、元々は「centerCrop」であったのに、共有要素が「fitCenter」で始まることです。
プロジェクトは問題を再現できます
https://github.com/JackFan-Z/ActivitySharedElementTransition.git

回避策を追加しましたが
フレスコ画を使用した別のプライベートプロジェクトでは機能しません。
誰かが本当の問題がどこにあるかを知ることができますか?

遷移の開始状態が間違っています
2015-10-01 11 26 34

移行前
2015-10-01 11 26 50

@ JackFan-Z
遷移中の共有要素は、最終ビューを初期値に設定し、それを最終値にアニメーション化します。

通常のImageViewをChangeImageTransformと組み合わせると、画像マトリックスの開始値と終了値がキャプチャされ、画像マトリックスの変更がアニメーション化されます。

ただし、 DraweeViewは画像マトリックスに関連する特定の関数をオーバーライドするため、 ChangeImageTransformは画像に影響を与えません。

つまり、最終的にはChangeBoundsのみが有効になります。

現在、DraweeViewの画像マトリックスを操作する方法が見つかりませんでした。 setActualImageMatrixさえ非推奨とマークされています。 非推奨ではなく、デフォルトのImageViewのデフォルトのsetImageMatrixとまったく同じように機能するとします。 それでも、 DraweeViewHierarchyを設定した後はマトリックスを変更する方法がないため、変更をアニメーション化することは実際にはあまり便利ではありません。 したがって、 onAnimationUpdate呼び出しごとに、新しいDraweeViewHierarchyを作成する必要があります。

DraweeViewがこのように実装されている理由がわかりません。 そして、現在可能な解決策は、基礎となるビットマップを取り戻し、 ChangeImageTransform遷移を実行するために別のImageViewを作成することだと思います。

@soapsign
コメントありがとうございます。

実際、私のプライベートプロジェクトでは、共有要素と同じビットマップを使用するダミーのImageViewを作成しようとしました。 問題はまだ存在します。
私が直面している問題がフレスコ画に関連しているかどうかはわかりません。
しかし、SimpleDraweeViewで同じ問題を簡単に再現できることは確かです。

ChangeImageTransformは、内在次元を使用して変換行列を決定します。 DraweeView実装では、 widthheightに対して-1に等しい内在次元を持つDraweeHierarchyを使用します。 これは、 Draweeすでに正しいスケールタイプのスケーリングを適用しているため、ビューで適用する必要がないためです。 さらに、 ImageViewは1つのスケールタイプのみを適用できますが、描画可能な階層では、画像ブランチ(プレースホルダー、障害画像、実際の画像など)ごとに個別のスケールタイプを使用できます。 実際の内在次元をビューに戻すと、サイズ設定のバグが発生するリスクがあります。
移行を機能させたい場合は、 ChangeBoundsを使用する必要があります。

fresco:ImageMatrixSrc = actual 」のような新しいオプションを追加するのはどうですか?

@boxcounter現時点では、現在の状況は問題ないと考えています。 ただし、プロポーザルのプルリクエストを作成することはできます:)

@massimocarli ChangeBoundsは、共有画像のサイズが両方のアクティビティ/ビューで同じである場合にのみ適切に機能します。 ただし、移行中に画像のサイズを変更する必要がある場合、画像がトリミングされて見栄えが悪くなります。
あなたはそのような方法で何をすることを提案しますか? ChangeImageTransformはこれを解決しますが、DraweeViewでは機能しません。

こっちも一緒...

@massimocarliChangeBoundsは十分ではありません。

これは私が達成しようとしていることです(これはImageViewを使用しています): https

SimpleDraweeViewを使用すると次のようになります: https
元の画像がアニメーション画像の背後で誤ってサイズ変更される方法に注意してください。

これは、トランジションとしてChangeBoundsだけを使用した場合の外観です: https ://gfycat.com/SorrowfulExemplaryAntlion

ねえフォークス、私は同じ問題を抱えています。 ChangeBoundsがスムーズに機能していません。 回避策または修正がある場合は、お知らせください。 共有要素の移行は、マテリアルデザインが導入した最高のもののひとつであり、フレスコ画は私がこれまで使用した中で最高のライブラリの1つです。 開発者に両方をシームレスに使用させてください。

Frescoがこれを修正しないので、誰かが回避策を見つけることができましたか?

正常に機能する、私が使用する回避策は次のとおりです。
https://github.com/bumptech/glide

みなさん、こんにちは。

ChangeBoundsメソッド自体は十分ではなく、共有要素の遷移の現在の状態は問題ないというFacebookからの回答に驚いています。

私はついに、サンプルプロジェクトでうまくいくように見える十分に単純な解決策を見つけました。
ChangeBoundsトランジションは、onMeasure()を介してレイアウト自体を更新するのではなく、現在どのドローイービューによってオーバーライドされていないonSizeChanged()を介して更新するため、トランジション中にドローアブルのスケールが更新されることはありません。

移行中にTopLevelDrawableを更新するCustomDraweeViewは次のとおりです。

public class CustomDraweeView extends SimpleDraweeView {

    public CustomDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
        super(context, hierarchy);
    }

    public CustomDraweeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    <strong i="10">@Override</strong>
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Drawable drawable = getTopLevelDrawable();
        if (drawable != null) {
            drawable.setBounds(0, 0, w, h);
        }
    }
}

膨らませる必要があるトランジションセットのxmlは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<transitionSet
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:duration="<strong i="14">@android</strong>:integer/config_mediumAnimTime"
    android:transitionOrdering="together"
    tools:targetApi="LOLLIPOP" >
    <changeBounds
        android:interpolator="<strong i="15">@android</strong>:interpolator/accelerate_decelerate"/>
    <changeTransform
        android:interpolator="<strong i="16">@android</strong>:interpolator/accelerate_decelerate"/>
</transitionSet>

この方法の唯一の欠点は、ドローアブルのスケールタイプがフラグメントまたはアクティビティ間で一致しない場合です。これは、共有要素の遷移を使用する場合は、とにかく避ける必要があります。

@massimocarli @tyronen
Facebookの誰かが、DraweeViewが現在このメソッドをオーバーライドしない理由と、この変更で発生する可能性のある問題についての洞察を提供できますか? 何も見つからない場合は、そのためのプルリクエストを作成させていただきます。

こんにちは、みんな! 新しいFrescoリリース0.10では、異なるScaleType間のカスタムScaleType変換は簡単です。 これが私の実装です
https://gist.github.com/burzumrus/a589aa7e36ca003ddaf2334218c50ad0

使い方は簡単です

TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new ChangeBounds());
transitionSet.addTransition(new DraweeTransform(ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.FIT_CENTER));
getWindow().setSharedElementEnterTransition(transitionSet);

@burzumrusそれはすごい! 実装していただきありがとうございます。 それはまさに私がInterpolatingScaleTypeで考えていたものです。 まだ行っていない場合は、Frescoのプルリクエストを行うことを検討してください。

@plamenko私はフレスコ画0.12を使用しています

getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
                    ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));
getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
                    ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));

アニメーションは完全に機能しています。 しかし、最初のアクティビティに戻ると、画像は消えています

誰かがフラグメントからフラグメントへのアニメーションでこれらを試しましたか? v0.12では動作しないようです。
編集:RecyclerViewが問題を引き起こす可能性はありますか?
編集2 :問題は、親の変更がtrueに設定されている場合、 ChangeBounds自体がXおよびYの_window_座標のみを使用することであるようです。 ChangeBoundssetReparenting(true)を介して設定することは非推奨であり、代わりにChangeTransformをお勧めします。 したがって、 RecyclerView場合、 transitionSet.addTransition(new ChangeTransform());も必要です。 (返されるアニメーションはまだ悪いようですが、少なくとも入力するアニメーションは問題ありませんcreateAnimator(...) startValues.viewendValues.viewに変更しても効果がありません)。これ。)

@Gericop@ ladia12 0.12は、私のプロジェクトのフラグメント間アニメーションでうまく機能します。
RecyclerViewでも使用しています。
重要なのは、「replace」フラグメントトランザクションしか使用できないということです。 'add'トランザクションは使用できません。
それがあなたを助けることができるなら、これは私がうまくいった何かを始めるのを助けたフラグメントからフラグメントへの移行の例(フレスコ画なし)です(あなたはgithubでプロジェクトコードをダウンロードすることができます)
http://www.androidauthority.com/using-shared-element-transitions-activities-fragments-631996/

@sperochon私はreplaceを使用していて、それはRecyclerViewにありますが、機能しません(そして、正直なところ、それがあなたのために機能するのは驚くべきことです、多分あなたはRecyclerViewの異なるバージョンを使用しますか?私はv24.1.1を使用します)。 アニメーションを機能させるには、いくつかの変更を加える必要がありました。

  • 追加ChangeTransformを介して遷移セットにtransitionSet.addTransition(new ChangeTransform());

    • これは、 ChangeBoundsRecyclerViewの開始ビューの誤った位置を報告するという事実によるものです(常に最初の要素のX、Y座標を返します)

  • createAnimator(...) if (mFromScale == mToScale)if(mFromScale == mToScale && startBounds.equals(endBounds))置き換えます

    • 2人の名宛人が同じスケールタイプを共有している場合、サイズが同じでなくても、変換は行われません。

  • createAnimator(...) final GenericDraweeView draweeView = (GenericDraweeView) startValues.view;final GenericDraweeView draweeView = (GenericDraweeView) endValues.view; createAnimator(...)置き換えます( startValues -> endValues変更に

    • 最初の名宛人の代わりに最後の名宛人を使用する

  • scaleType.setValue(fraction)呼び出しの後のAnimatorUpdateListenerに、次の行を挿入します。
Drawable drawable = draweeView.getTopLevelDrawable();

if (drawable != null) {
    drawable.setBounds(0, 0, draweeView.getWidth(), draweeView.getHeight());
}

この最後のコードは、 @ Aohayouのソリューションに基づいています( CustomDraweeView機能させることができなかったため)。
これをAndroid5.0.2でテストし、libバージョンv24.1.1をサポートしました。

同じサイズの画像間をアニメーション化する場合、このソリューションは機能しないことに注意してください。

@Gericopこれ
https://github.com/sperochon/DemoFrescoFragment2Fragment

この助けを願っています!

@sperochon複数の画像で試してみてください。
ちなみに、私はあなたのデモを変更されていないソースでテストしました。 結果は次のとおりです。

device-2016-08-14-220810_1

これは完全に間違っています。 端面図は別の位置から始まり、スケールタイプは何の効果もありません。 明らかにそうではないので、これについて「うまくいく」とどのように言うことができますか。

@Gericopコードを更新しました。 終了フラグメントに別のレイアウトを指定するのを忘れました。 もう一度やり直してください。

@sperochon API 23エミュレーターでは、
つまり、現在の実装はAPI 21では機能しませんが(API 22ではテストしていません)、API23では機能します。

編集:デモでは、デフォルトのChangeBoundsおよびChangeTransformトランジションのみをテストし、Facebookが提供するDraweeTransition実装はテストしません。

残念ながら、あなたは正しいです...私は私のデバイスでそれをテストしました:
Android 5.0 + Fresco v0.11 / v0.12-> KO
Android 6.0 + Fresco v0.11 / v0.12-> OK
以前は気づかなかった...

@ Gericop @ sperochon私はこれについてメディアにブログ投稿を書きました。 それが役立つかどうかを確認してください。

@ ladia12その投稿は、私が直面していた(私たちが直面していた)問題とは何の関係もありません...あなたのブログエントリは_inter-アクティビティ_移行に関するものですが、私の問題は_inter-フラグメント_に関連しています。 さらに、本当のバグは、API 21がChangeBoundsおよび/またはChangeTransform遷移を処理する方法にあり、FacebookがDraweeTransitionしても役に立ちません。 一方、私のソリューションは、ソース画像とターゲット画像の寸法(幅や高さ)が異なる場合、これを克服します。

情報のためだけに:
Android 5.0 + Fresco v0.11 / v0.12 / 0.13-> KO
Android> = 5.1 + Fresco v0.11 / 0.12 / 0.13-> OK

@ ladia12最初のアクティビティに戻ると、元の画像が消える問題をどのように解決しましたか?

@dbrant私は同じ問題を抱えています、あなたは解決するためのいくつかの方法を見つけましたか?

#1446を参照

@ ladia12最初のアクティビティに戻ると、元の画像が消える問題をどのように解決しましたか?

@ ladia12最初のアクティビティに戻ると、元の画像が消える問題をどのように解決しましたか? 私の元の画像はrecyclerviewのビューホルダーにあります

共有要素の移行にPicassoを使用することになりました。 修正されませんでした
フレスコで。 だからピカソは軽量で、それを使用しても問題はありません
フレスコと一緒に。

午前5時11分PMに水、2019年6月19日にbembem1011 [email protected]書きました:

@ ladia12https ://github.com/ladia12の問題をどのように解決しましたか
最初のアクティビティに戻ると元の画像が消えますか? 私の
元の画像はrecyclerviewのビューホルダーにあります


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/facebook/fresco/issues/22?email_source=notifications&email_token=AAXQ5WYUP5KBJYNBOZX7CCDP3ILM5A5CNFSM4A6ZMH32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAXQ5W5EXO5SV4R2PXVTG7LP3ILM5ANCNFSM4A6ZMH3Q

このページは役に立ちましたか?
0 / 5 - 0 評価