Recolor transition 对 VIewGroup 不起作用吗?

Does Recolor transition not work for VIewGroup?

我有一个场景转换,我想使用重新着色动画将 ViewGroup 的背景从透明更改为另一种颜色。这是我的 login_to_register.xml:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
   <fade android:fadingMode="fade_out"/>
   <fade android:fadingMode="fade_in">
      <targets>
         <target android:targetId="@id/passwordEditor" />
         <target android:targetId="@id/loginNameEditor" />
      </targets>
   </fade>
   <!--<changeTransform />-->
   <changeBounds />
   <recolor>
      <targets>
         <target android:targetId="@id/loginOptions" />
      </targets>
   </recolor>
</transitionSet>

这是片段布局的 XML,它位于 ViewPager 内。

<FrameLayout
      android:layout_width="match_parent" android:layout_height="match_parent">

      <ImageView
         android:layout_width="match_parent" android:layout_height="match_parent"
         android:scaleType="centerCrop"
         android:src="@drawable/onboarding_bg"
         />

      <LinearLayout
         android:id="@+id/loginOptions"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginLeft="@dimen/activity_horizontal_margin"
         android:layout_marginRight="@dimen/activity_horizontal_margin"
         android:background="@android:color/transparent"
         android:layout_gravity="bottom"
         android:gravity="center_horizontal"
         >
         <android.support.design.widget.TextInputLayout
            android:id="@+id/loginNameEditor"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/email"
            app:errorEnabled="true"
            app:hintTextAppearance="@style/BlackFloatingTextTextAppearance"
            android:visibility="gone"
            tools:visibility="visible"
            >
            <android.support.design.widget.TextInputEditText
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@={regModel.emailAddress, default=`twinkle`}"
               android:inputType="textEmailAddress"
               android:maxLength="254"
               android:onFocusChange="@{(v, focus) -> context.loginFocusChanged(true, focus)}"
               android:afterTextChanged="@{() -> context.loginTextChanged()}"
               />
         </android.support.design.widget.TextInputLayout>

         <android.support.design.widget.TextInputLayout
            android:id="@+id/passwordEditor"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/password"
            app:passwordToggleEnabled="true"
            app:errorEnabled="true"
            app:hintTextAppearance="@style/BlackFloatingTextTextAppearance"
            app:counterEnabled="true"
            app:counterMaxLength="50"
            android:visibility="gone"
            tools:visibility="visible"
            >
            <android.support.design.widget.TextInputEditText
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@={regModel.password}"
               android:inputType="textPassword"
               android:fontFamily="monospace"
               android:onFocusChange="@{(v, focus) -> context.loginFocusChanged(false, focus)}"
               android:afterTextChanged="@{() -> context.loginTextChanged()}"
               />
         </android.support.design.widget.TextInputLayout>

         <TextView
            android:id="@+id/error"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingStart="4dp"
            android:paddingEnd="4dp"
            android:textAppearance="@style/TextAppearance.Design.Error"
            android:gravity="start"
            android:visibility="gone"
            tools:visibility="visible"
            />

         <!--<Button-->
         <!--android:id="emailAuthButton"-->
         <!--android:layout_width="wrap_content"-->
         <!--android:layout_height="wrap_content"-->
         <!--android:layout_marginTop="@dimen/loginButtonSpacing"-->
         <!--android:text="@string/login"-->
         <!--style="@style/PrimaryColorButtonBorderlessStyle"-->
         <!--android:onClick="loginEmail"-->
         <!--/>-->

         <com.google.android.gms.common.SignInButton
            android:id="@+id/googButton"
            android:layout_width="230dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/loginButtonSpacing"
            android:layout_marginTop="@dimen/loginButtonSpacing"
            android:onClick="loginGoogle"
            app:buttonSize="wide"
            />

         <com.facebook.login.widget.LoginButton
            android:id="@+id/fbButton"
            android:layout_width="220dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/loginButtonSpacing"
            app:com_facebook_login_text="@string/com_facebook_loginview_log_in_button"
            android:layout_marginBottom="@dimen/loginButtonSpacing"
            android:paddingTop="12dp"
            android:paddingBottom="12dp"
            android:onClick="loginFB"
            />

         <TextView
            android:id="@+id/emailInfo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:layout_marginTop="@dimen/register_row_spacing"
            android:layout_marginStart="10dp"
            android:text="@string/unauth_email_prompt"
            android:textColor="?android:attr/textColorPrimaryInverse"
            />

         <Button
            android:id="@+id/unfederatedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/loginButtonSpacing"
            android:layout_marginBottom="@dimen/loginButtonSpacing"
            android:text="@string/create_account"
            style="@style/ScalableBorderlessButton"
            android:textColor="@color/colorAccent"
            android:minHeight="53dp"
            android:onClick="showUnfederatedUI"
            />
         <TextView
            android:id="@+id/forgotPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:layout_marginTop="15dp"
            android:paddingTop="@dimen/smallLinkTopPadding"
            android:paddingBottom="@dimen/smallLinkBottomPadding"
            android:paddingLeft="@dimen/smallLinkHPadding"
            android:paddingRight="@dimen/smallLinkHPadding"
            app:hypertext="@{R.string.forgot_pass}"
            android:background="?android:attr/selectableItemBackground"
            tools:text="@string/forgot_pass"
            android:textSize="@dimen/smallLinkTextSize"
            android:onClick="recoverPassword"
            android:visibility="gone"
         />
      </LinearLayout>
   </FrameLayout>

现在我要使用 Recolor 的视图是 id loginOptions。您可以看到我在转换中给出了它的特定 targetId。如果从 null 开始有任何问题,它默认为 transparent。所以这里是开始场景转换的代码

    val trans = TransitionInflater.from(this).inflateTransition(R.transition.login_to_register)
    TransitionManager.beginDelayedTransition(this.dataBinding.root, trans)
    this.loginBinding!!.loginNameEditor.visibility = View.VISIBLE
    this.loginBinding!!.passwordEditor.visibility = View.VISIBLE
    this.loginBinding!!.error.visibility = View.VISIBLE
    this.loginBinding!!.googButton.visibility = View.GONE
    this.loginBinding!!.fbButton.visibility = View.GONE
    this.loginBinding!!.emailInfo.visibility = View.GONE
    this.loginBinding!!.forgotPassword.visibility = View.VISIBLE

    val color = this.resources.getColor(R.color.almostWhite)
    this.loginBinding!!.loginOptions.background = ColorDrawable(color)

我不包括 ViewPager 的 activity 布局,它很简单,可能没有任何问题,因为所有其他转换都有效!是的,所有 VISIBILITY 更改都正常工作,边界也发生了变化。 Recolor 有什么问题?编辑:让我补充一点,如果我删除 <recolor>@id/loginOptions 的背景 会更改为 almostWhite

这报告给 Google issue tracker,有一个适合我的解决方案,这就是我接受这个的原因。

要在转场中使用自定义转场 xml 执行:

<transition 
        class="com.example.BackgroundRecolor" 
        android:duration="200"/> 

在您的自定义转换中添加来自 Transition 的构造函数以支持 xml 属性:

public BackgroundRecolor() {} 

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

我正在查看我发现 here 的重新着色源,它似乎只捕获 TextViews 的值。不知道这个是不是最新版,现在没法测试。

或者,尝试找到 here 的(优秀的)TransitionsEverywhere 库,我已经对两者进行了并排测试(Android Transitions vs. Library),它们的性能相同。值得一试,因为您所要做的就是更改命名空间 :)(或者您甚至可以通过查看现有的源代码来创建自己的“重新着色”版本,以满足您的需求。

UPDATE:通过查看更新的源代码(甚至是 Recolor 的 TransitionsEverywhere 版本),它似乎确实捕获了视图的背景。 (Source)

它与 Android 本机版本相同:

transitionValues.values.put(PROPNAME_BACKGROUND,
                            transitionValues.view.getBackground());

也许你可以尝试使用 TransitionDrawable? 请参阅 this Whosebug question/answer 组合。