2017-06-12 45 views
1

在我的Android應用程序中,我需要實現一個涉及其中一個元素的高程(z-index)更改的場景轉換。正如您在左側開始場景中的下圖所示,藍色弧線顯示在狗的圖像下方。在右側顯示的最終轉場中,狗的圖像顯示在藍色弧線的下方。我的願望是先讓圖像的changeBounds轉換先開始,然後再稍微做一次arcButtonBounds轉換。在過渡的大約一半處,圖像的底部應該位於弧的上方。在這個中途點,我想要改變圖像的高程/ z-index,以便狗圖像顯示在藍色弧線下面。 before and after images如何將高程變化動畫化爲場景更改動畫/轉換的一部分?

我目前的主題是我的應用程序配置爲使用以下transitionSet進行此場景更改。

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" 
    android:transitionOrdering="together" 
    android:duration="2000"> 

    <changeBounds 
     android:startDelay="0" 
     android:duration="1000" 
     android:resizeClip="false" 
     > 
     <targets> 
      <target android:targetId="@id/charlie"/> 
     </targets> 
    </changeBounds> 

    <transition class="com.motb.transitiontest.ElevationTransition"> 
     android:startDelay="0" 
     android:duration="1000" 
     <targets> 
      <target android:targetId="@id/charlie"/> 
      <target android:targetId="@id/arc1"/> 
     </targets> 
    </transition> 


    <changeBounds 
     android:startDelay="300" 
     android:duration="1000" 
     > 
     <targets> 
      <target android:targetId="@id/arc1"/> 
      <target android:targetId="@id/helloText" /> 
     </targets> 
    </changeBounds> 

</transitionSet> 

我試圖在使用這種定製「ElevationTransition」的高程變化如下圖所示:

public class ElevationTransition extends Transition { 

public static final String TAG = "ElevationTransition" ; 

public ElevationTransition(Context context, AttributeSet attributes) { 
    super(context, attributes); 
} 

private static final String PROPNAME_TRANS_Z = "com.motb:transition:transz"; 
@Override 
public void captureStartValues(TransitionValues transitionValues) { 
    float translationZ = transitionValues.view.getTranslationZ() ; 
    transitionValues.values.put(PROPNAME_TRANS_Z + "_start" , translationZ); 
} 

@Override 
public void captureEndValues(TransitionValues transitionValues) { 
    float translationZ = transitionValues.view.getTranslationZ() ; 
    transitionValues.values.put(PROPNAME_TRANS_Z + "_end", translationZ); 
} 
@Override 
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 
           TransitionValues endValues) { 
    if (startValues == null || endValues == null) { 
     return null; 
    } 
    final View view = endValues.view; 
    float startElevation = (Float) startValues.values.get(PROPNAME_TRANS_Z + "_start"); 
    float endElevation = (Float) endValues.values.get(PROPNAME_TRANS_Z + "_end"); 
    if (startElevation != endElevation) { 
     view.setTranslationZ(startElevation); 
     return ObjectAnimator.ofFloat(view, View.TRANSLATION_Z, 
       startElevation, endElevation); 
    } 
    return null; 
} 

}

主要活動只是用下面的佈局顯示空白分配圖:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.motb.transitiontest.MainActivity" 
android:id="@+id/main" 
android:onClick="onClick" 
android:background="@drawable/treasuremap" 
> 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="250dp" 
    android:id="@+id/fragmentContainer" 
    android:layout_alignParentBottom="true" 
    /> 


</RelativeLayout> 

點擊地圖用一個片段dis替換上面的FrameLayout播放時使用以下佈局底部的「名片」:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="250dp" 
tools:context="com.motb.transitiontest.MainActivity" 
android:id="@+id/main" 
android:background="@android:color/transparent" 
> 


<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="160dp" 
    android:background="@drawable/arc_bg" 
    android:backgroundTint="#ff0000ff" 
    android:layout_alignParentBottom="true" 
    android:transitionName="rv1" 
    android:id="@+id/arc1" 
    android:translationZ="20dp" 

    > 

    <TextView 
     android:id="@+id/helloText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Hello World Transition Test" 
     android:layout_marginStart="165dp" 
     android:layout_marginTop="27dp" 
     android:textSize="40dp" 
     android:gravity="left" 
     android:transitionName="tv1" 
     android:textColor="#ffffffff" 
     /> 


</RelativeLayout> 

<ImageView 
    android:layout_width="300px" 
    android:layout_height="300px" 
    android:layout_alignParentTop="true" 
    android:layout_marginTop="80dp" 
    android:layout_marginStart="20dp" 
    android:transitionName="iv1" 
    android:src="@drawable/charlie" 
    android:id="@+id/charlie" 
    android:translationZ="30dp" 
    android:stateListAnimator="@null" 
    /> 


</RelativeLayout> 

在片段的點擊,開始與狗的大圖使用下面的XML的第二個活動:

` 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.motb.transitiontest.Activity2" 
android:theme="@android:style/Theme.Translucent.NoTitleBar" 
> 


    <RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.motb.transitiontest.Activity2" 
    android:layout_marginTop="200dp" 
    android:background="@drawable/arc_bg" 
    android:layout_alignParentBottom="true" 
    android:transitionName="rv1" 
    android:id="@+id/arc1" 
    android:backgroundTint="#ff0000ff" 
    android:translationZ="40dp" 
    > 


    <TextView 
     android:id="@+id/helloText" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="30dp" 
     android:layout_marginLeft="50dp" 
     android:layout_marginRight="50dp" 
     android:text="Hello World Transition Test" 
     android:textSize="40dp" 
     android:textAlignment="center" 
     android:transitionName="tv1" 
     android:textColor="#ffffffff" 
     /> 


</RelativeLayout> 


<ImageView 
    android:id="@+id/charlie" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:src="@drawable/charlie" 
    android:transitionName="iv1" 
    android:scaleType="centerCrop" 
    android:translationZ="0dp" 
    android:stateListAnimator="@null" 
    /> 



</RelativeLayout>` 

目前,我看到的是,在轉換開始時立面會立即改變,導致狗圖像被弧遮擋。

+0

更優雅和高效的解決方案將是寫一個你自定義的類來繪製漸進Z指數的圖像,你可以使用valueAnimator給平滑到動畫 – sumit

+0

@sumit請提供關於爲什麼你認爲一個更詳細信息在這種情況下,valueAnimator比ObjectAnimator更好。是什麼讓它更優雅和高效? – John

+0

你也可以發佈視圖層次嗎? – azizbekian

回答

2

我檢查了github。這是一個錯誤。

我可以使用Transtions和TransitionManager.go()來明確地運行場景之間的轉換。但是,當你運行片段和活動之間的轉換時,總是會立即更改淡入淡出動畫。在支持26.0.0 beta版中修復了一些淡入淡出的錯誤-1

  • 當淡入淡出轉換中斷並顛倒時,視圖從頭開始播放動畫。 (從Android框架修復移植。)
  • Transition.Fade忽略查看的初始阿爾法(AOSP問題221820)

可是,捫心自問,你所有的擺弄你曾經看到它做一個實際的褪色過渡? - 不喜歡所有的移動和其他什麼,你能讓它淡化嗎?因爲這就是我所需要的所有建議,而且我無法按照您運行的方式來運行它。但是,顯然所有移動的元素確實是的工作,所以這是一個該死的錯誤。


你也可以完全假裝它。如果你已經淡入淡出,你可以調用它並讓它起作用。

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 

    setContentView(R.layout.activity2); 
    findViewById(R.id.arc1).setVisibility(View.VISIBLE); 
    findViewById(R.id.arc2).setAlpha(0); 
    findViewById(R.id.arc2).animate().alpha(1).setDuration(2000).start(); 
} 

我只是ARC1的可見性設置爲正確的,因爲你有一個錯誤:如果您在活性2改變的onCreate()是你得到正確的動畫。這是始終可見的。

我認爲然後添加一個動畫與另一個相同的時間段,以階段和繁榮。有用。這是一個愚蠢的錯誤。你無法在活動之間淡化,因爲沒有任何理由。


我自己發現了alpha。第一個可能是發生了什麼事。或者它可能完全是一個不同類的錯誤。但是,我可以向你保證。我查了一下,做的都對。它仍然失敗。很明顯,解決方法就是在他們工作的地方使用場景轉換。也許根本不使用新的活動。

有一堆你可以明顯想出來的解決方法。只要啓動它應該具有的佈局的活動,然後設置一個場景以轉換到適當的佈局。在第一個活動中自己添加另一個到佈局的轉換。或者是什麼。但是,它不起作用。你做了從片段到活動的轉換,並且東西會移動,但是漸變總是會拋出一個conniption並拒絕。它即刻呈現其他視圖的可見性,並且無需alpha即可工作,也無法輕鬆糾正這種情況。

我認爲有一些工作原代碼使用場景:當我想這是他對暫時無法實現我的怎麼顯然很高招故障舊的答案

boolean to = true; 
public void onClick(View view) { 
    Scene scene; 
    ViewGroup mSceneRoot = (ViewGroup) findViewById(R.id.container); 
    if (to) { 
     Transition mFadeTransition = 
       TransitionInflater.from(this). 
         inflateTransition(R.transition.transitionset); 
     scene = Scene.getSceneForLayout(mSceneRoot, R.layout.fragment_replacement, this); 

     TransitionManager.go(scene, mFadeTransition); 
    } 
    else { 
     Transition mFadeTransition = 
       TransitionInflater.from(this). 
         inflateTransition(R.transition.backwardstransitionset); 
     scene = Scene.getSceneForLayout(mSceneRoot, R.layout.fragment_rep, this); 
     TransitionManager.go(scene, mFadeTransition); 
    } 
    to = !to; 
} 

留位做過渡。這個錯誤是他沒有可靠的淡入淡出效果,而這一直是問題所在。


你不能用Z命令來動畫。你改變順序,他們彼此重疊,而不是相反。做你想要建議你需要做的事情是同時有這兩個訂單同時和動畫他們的過渡與透明度。

您繪製弧,狗,另一個弧。然後,Z順序的變化實際上是頂部繪製的弧的透明度。如果它是完全不透明的,則弧在狗的頂部。如果它完全透明,那麼狗就在弧上。但是,如果最頂端的弧是部分透明的,則它看起來像狗正在融化通過弧線,或弧線正在融化通過狗,這取決於我們如何調整透明度。你可以在其他地方使用相同的技巧。把這個東西放在兩個地方。如果它是不透明的,它會被覆蓋,但是如果它是透明的,它將只顯示最下面的弧線,以及弧線與對象之間的混合(如果部分透明的話)。在動畫結束時,將它們按正確的順序排列。

所以在動畫過程中,您總是將2個弧移動到相同的位置。你應該看到它們是同一弧線。在頂部改變弧的不透明度,並且對你的狗做任何你正在做的事情。


視頻:

https://youtu.be/zVs3qzPU2FM


創建佈局。三明治你想改變兩個副本之間的高度另一個對象的位。在其中一種佈局中,將可見性設置爲invisible。因此,所有項目都以相同的順序排列在兩個佈局中。但是,其中一個元素的第二個副本是不可見的。確保兩個副本在兩個位置都處於相同位置。當你改變一個副本的邊界時,確保你也改變了另一個副本的邊界。將它們作爲一個單元移動。當您轉換視圖時,將項目移出或移動時淡入其中。由於還有第二個副本,它看起來不像淡出,它看起來像是一個融化。


+0

我想我明白你的建議,但仍然無法弄清楚實施。您的建議是否適用於ActivityOptions.makeSceneTransitionAnimation?我現在在起始片段的佈局和最終活動的佈局中有兩個弧。我在我的transition.xml中添加了一個。但是我看到的是第二個弧線立即可見,而不是消失。 – John

+0

兩條弧線必須相互重合。你只能看到它們爲1弧。如果弧線消失,則它應該從0 alpha開始,然後轉換到1.而始終與其他弧線一致。 – Tatarize

+0

我總是捲起一個自定義動畫師,所以我不確定你是如何移動它們的。而且我發現你的模型很混亂(狗的照片取代了地圖圖片並且變大了或者是什麼)? – Tatarize