3

我試圖使共享元素過渡工作與回收器視圖內的元素。當用戶點擊我的回收商查看項目中的文本視圖時,詳細信息活動即會打開。在細節活動內部,我展示了一些信息,並且我也有一個選項卡布局,可以使用picasso從url加載一些圖像。過渡到細節活動正在工作,但如果用戶在加載所有圖像之前返回到主活動,主活動中的回收站視圖將在逆向動畫之後消失!當我禁用共享元素轉換時,問題消失了。與RecyclerView項目共享元素過渡 - Android

這兩項活動都適用於碎片。所以,我試圖在兩個片段之間創建一個轉換,這些片段處於不同的活動中。

在RecyclerViewAdapter,我設定的轉換名:

public void onBindViewHolder(final ViewHolder viewHolder, int position) { 
    ... 
viewHolder.profileImage.setTransitionName("profile"+position); 

onClickListener我的TextView的(在主要活動的片段內):

Intent i = new Intent(getCurrentActivity(), DetailActivity.class); 
     ActivityOptionsCompat options = ActivityOptionsCompat. 
       makeSceneTransitionAnimation(getCurrentActivity(), (View) profileImage, "profile"+position); 
     getCurrentActivity().startActivity(i, options.toBundle()); 

詳細活動的片段具有共享內元素(在onCreateView中):

profileImage.setTransitionName("profile"+position); 

我已經檢查了trans當意圖發生時兩個活動中的ition名稱相同。

我被困在這個問題兩天,看不見發生了什麼事情。如果您需要更多信息或代碼,只需詢問。

謝謝!

+0

我不知道,如果該事項,但兩個活動(主要和詳細信息)的片段,這樣的意圖,詳細活動從主要活動的片段和setTransitionName稱爲( )的第二個活動在其片段的onCreateView()內調用。 –

+0

當然你會有這個問題。畢加索是在BackGround上的一個異步調用,如果它沒有完成任務,那麼你移動到另一個Activity,這是你的MainActivity。來自畢加索的異步電話將被暫停。 @G_comp。我不認爲他正在使用碎片,因爲你設置了碎片交易的過渡。 – Aizen

+0

@Aizen,但問題發生在共享元素轉換啓用時,所以我不認爲這是畢加索的錯誤。當我禁用共享元素轉換時,我可以在加載圖像之前返回主活動 –

回答

5

問題是,共享元素轉換在Activity生命週期的早期就由框架啓動。轉換必須同時捕獲其目標視圖的開始和結束狀態,以便構建正常運行的動畫。因此,如果框架在其共享元素在被調用的Activity中被賦予其最終大小,位置和大小之前開始共享元素轉換,那麼轉換將捕獲其共享元素的不正確的結束值,並且所產生的動畫將完全失敗。

如果共享元素依賴於異步加載數據通過AsyncTask,AsyncQueryHandler,Loader或類似的東西,然後可以確定它們在被調用活動中的最終外觀,那麼框架可能會在數據交付之前開始轉換回到主線程。
所以,soluation如下:

  1. 通話postponeEnterTransition()你叫活動的onCreate()方法。
  2. 如果您確定所有共享元素都已正確定位並調整大小,請致電startPostponedEnterTransition()以恢復轉換。你會發現一個常見的模式是在OnPreDrawListener中啓動推遲的轉換,這將在測量和佈局共享元素之後調用。

您使用畢加索,因爲我知道畢加索有一個加載圖像時,將名爲RequestCreator回調。
例如:

private final Callback callBack = new Callback() { 
    @Override 
    public void onSuccess() { 
     imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      @Override 
      public boolean onPreDraw() { 
       imageView.getViewTreeObserver().removeOnPreDrawListener(this); 
       MainActivity.this.startPostponedEnterTransition(); 
       return true; 
      } 
     }); 
    } 

    @Override 
    public void onError() { 

    } 
}; 

RequestCreator requestCreator = Picasso.with(this).load(imageUrl); 
requestCreator.into(imageView, callback);