背景
我一直在尝试实现父子导航(具体用于recyclerview项->详细片段)。我目前正在使用带有元素容器和详细信息容器的sharedElementTransitions作为sharedElement以及ChangeTransform和ChangeBounds过渡。细节片段的输入过渡大部分有效。但是,recyclerview项的退出转换存在问题。我想做的是在细节视图扩展到全屏时,将recyclerview调暗/变暗。当我尝试使用自定义过渡时,退出过渡永远不会动画。取而代之的是,将立即显示局部视图,并对其进入过渡设置动画。
如您所见,在播放退出动画之前,recyclerview片段是隐藏的。我需要在展开详细视图时以暗淡效果显示recyclerview。
问题
如何在播放详细的自定义退出过渡的同时播放昏暗的自定义退出过渡?
我尝试过的事情
ItemViewModel.java
public void displayArticle(View view) {
MainActivity mainActivity = (MainActivity) view.getContext();
ArticleFragment detailsFragment = ArticleFragment.newInstance(article.getValue(), transitionName.getValue());
ArticleListingFragment itemFragment = (ArticleListingFragment) mainActivity.getSupportFragmentManager().findFragmentByTag(ArticleListingFragment.TAG);
doOpenArticleTransition(detailsFragment, itemFragment);
mainActivity.getSupportFragmentManager()
.beginTransaction()
.addSharedElement(view.findViewById(R.id.article_entry), transitionName.getValue())
.replace(R.id.main_content_container, detailsFragment)
.addToBackStack(null)
.commit();
}
private void doOpenArticleTransition(Fragment newFragment, Fragment oldFragment) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Transition openArticleTransition = TransitionInflater.from(oldFragment.getContext()).inflateTransition(R.transition.transition_article);
newFragment.setSharedElementEnterTransition(openArticleTransition);
newFragment.setEnterTransition(new Fade());
oldFragment.setExitTransition(new Dim(oldFragment.getContext()));
newFragment.setSharedElementReturnTransition(openArticleTransition);
}
}
Dim.java
public class Dim extends BaseTransition {
private static final String PROPNAME_BACKGROUND = "meridian:dim:background";
private final Context context;
public Dim(Context context) {
this.context = context;
}
public Dim(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
public void captureValues(TransitionValues transitionValues) {
Drawable background = transitionValues.view.getBackground();
transitionValues.values.put(PROPNAME_BACKGROUND, background);
}
@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
final View view;
if (startValues == null && endValues != null) {
view = endValues.view;
} else {
view = startValues.view;
}
int whiteBackground = ContextCompat.getColor(context, R.color.white);
int grayBackground = ContextCompat.getColor(context, R.color.gray700);
ValueAnimator animator = ValueAnimator.ofArgb(whiteBackground, grayBackground);
animator.setDuration(400);
animator.setStartDelay(300);
animator.addUpdateListener(animation -> view.setBackgroundColor((Integer)animation.getAnimatedValue()));
return animator;
}
}
transition_article.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet
xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="together">
<changeBounds/>
<changeTransform/>
<transition
class="meridian.custom.anim.Elevate"/>
</transitionSet>
recyclerview_item.xml
<android.support.constraint.ConstraintLayout
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:id="@+id/article_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/article_listing_section"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/two_line_list_entry_margin_lr"
android:layout_marginEnd="@dimen/two_line_list_entry_margin_lr"
android:layout_marginTop="@dimen/two_line_list_entry_margin_tb"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/article_listing_section_title_barrier"
app:layout_constraintTop_toTopOf="parent"
style="@style/EntryOverline"
tools:text="@tools:sample/cities" />
<TextView
android:id="@+id/article_listing_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/two_line_list_entry_margin_tb"
android:layout_marginEnd="@dimen/two_line_list_entry_margin_lr"
android:textAlignment="viewEnd"
app:layout_constraintEnd_toStartOf="@+id/article_listing_date_image_barrier"
app:layout_constraintTop_toTopOf="parent"
style="@style/EntryOverlineGray"
tools:text="17h" />
<TextView
android:id="@+id/article_listing_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/two_line_list_entry_margin_tb"
android:layout_marginEnd="@dimen/two_line_list_entry_margin_lr"
android:layout_marginTop="@dimen/two_line_list_entry_first_line_second_line_spacing"
app:layout_constraintStart_toStartOf="@id/article_listing_section"
app:layout_constraintEnd_toStartOf="@id/article_listing_section_title_barrier"
app:layout_constraintTop_toBottomOf="@id/article_listing_section"
app:layout_constraintBottom_toBottomOf="parent"
android:minLines="3"
android:maxLines="3"
style="@style/EntrySubtitle1"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." />
<ImageView
android:id="@+id/article_listing_image"
android:layout_width="@dimen/two_line_list_entry_image_width"
android:layout_height="@dimen/two_line_list_entry_image_width"
android:layout_marginStart="@dimen/two_line_list_entry_margin_lr"
android:layout_marginEnd="@dimen/two_line_list_entry_margin_lr"
android:contentDescription="@string/content_description_image_article_entry"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/article_listing_date_image_barrier"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/item_article_entry_image_placeholder" />
<android.support.constraint.Barrier
android:id="@+id/article_listing_section_title_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="article_listing_date"/>
<android.support.constraint.Barrier
android:id="@+id/article_listing_date_image_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="article_listing_image"/>
</android.support.constraint.ConstraintLayout>
recyclerview_fragment.xml
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawer_article_sections"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout_articles"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/toolbar" />
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_to_refresh_articles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/articles"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="2"
tools:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/item_article_entry" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view_article_sections"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemTextAppearance="@style/SectionSubtitle1"
app:menu="@menu/navigation_article_topic"
app:headerLayout="@layout/navigation_header_article_sections"/>
details_fragment.xml
<android.support.design.widget.CoordinatorLayout
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"
app:elevation="24dp">
<include
layout="@layout/toolbar" />
<android.support.v4.widget.NestedScrollView
android:id="@+id/article_scroll_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.constraint.ConstraintLayout
android:id="@+id/article"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.article.display.ArticleFragment">
<HorizontalScrollView
android:id="@+id/article_description_scroll_container"
style="@style/HorizontalChipScroller"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scrollbars="none"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.chip.ChipGroup
android:id="@+id/article_description_chip_group"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/chip_group_description_tags"
app:singleLine="true"/>
</HorizontalScrollView>
<ImageView
android:id="@+id/article_image"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
android:contentDescription="@string/content_description_image_article"
android:scaleType="centerCrop"
android:src="@drawable/item_article_entry_image_placeholder"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.45"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_description_scroll_container"
tools:layout_height="208dp"
tools:src="@color/colorImagePlaceholder" />
<TextView
android:id="@+id/article_section"
style="@style/DetailOverline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
app:layout_constraintEnd_toStartOf="@id/article_subsection"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_image"
tools:text="US"
tools:textColor="@color/gray900" />
<TextView
android:id="@+id/article_subsection"
style="@style/DetailOverline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
app:layout_constraintStart_toEndOf="@id/article_section"
app:layout_constraintTop_toBottomOf="@id/article_image"
tools:text="Poverty"
tools:textColor="@color/gray900" />
<TextView
android:id="@+id/article_title"
style="@style/DetailH6Headline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/detail_general_margin_tb"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_section"
tools:text="Pope Accepts Wuerl's Resignation as Washington Archbishop, but Calls Him a Model Bishop"
tools:textColor="@color/gray900"
tools:textSize="20sp"
tools:textStyle="bold" />
<TextView
android:id="@+id/article_abstract"
style="@style/DetailBody2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/detail_general_margin_tb"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_title"
tools:text="Despite demands to oust Cardinal Wuerl over sexual abuse scandals, Pope Francis praised him as a model leader."
tools:textColor="@color/gray600" />
<TextView
android:id="@+id/article_author"
style="@style/DetailBody1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/detail_general_margin_tb"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/detail_general_margin_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_abstract"
tools:text="by Jason Horowitz, Elizabeth Dias and Laurie Goodstein"
tools:textColor="@color/gray900" />
<android.support.design.button.MaterialButton
android:id="@+id/article_full_content_button"
style="@style/OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/detail_general_margin_tb"
android:layout_marginEnd="@dimen/detail_general_margin_lr"
android:layout_marginStart="@dimen/outlined_button_padding_lr"
android:layout_marginTop="@dimen/detail_general_margin_tb"
android:text="@string/button_label_article_read_more"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/article_author" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
DetailsFragment.java
@BindView(R.id.article)
ConstraintLayout container;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupToolbar();
setTransitionName();
loadArticle();
}
private void setTransitionName() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
container.setTransitionName(this.getArguments().getString(ARG_TRANSITION));
}
}