GridView 奇怪行为中的共享元素转换

Shared Element Transition in GridView Weird behavior

我在 gridView 适配器中的 imageView 和细节中的 imageView 之间使用共享元素转换 activity,但是当我单击 GridView 中的项目时,imageView 不会开始动画正确的位置它总是从原来的位置开始,当我回击时图像正确地动画到正确的位置所以只有在进入新的 activity.

时才会发生故障

https://youtu.be/cprBHWPVNbk(我放慢了动画速度,以便清除故障)。

在 BrowseFragment 的 OnCreate 中:

gridView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        ImageView gridPoster = (ImageView) view.findViewById(R.id.movie_poster);
        gridPoster.setTransitionName("poster" + position);
        listener.onItemSelected(movie,gridPoster);

然后 BrowseActivity 的侦听器启动 detailsActivtiy :

ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation
                    (this, posterView,posterView.getTransitionName());
Intent detailsIntent = new Intent(this, MovieDetalisActivity.class);
detailsIntent.putExtra(getString(R.string.movie_details_extra_key), movie);
detailsIntent.putExtra("transition",posterView.getTransitionName());
            ActivityCompat.startActivity(this, detailsIntent, optionsCompat.toBundle());

然后在DetailsFragment的OnCreate中:

ImageView poster = (ImageView) rootView.findViewById(R.id.poster);
poster.setTransitionName(getActivity().getIntent().getStringExtra("transition"));

GridViewItem 布局:

<LinearLayout 

xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/gird_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="2dp"
    android:background="#4e585c"
    android:clipChildren="false">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="240dp"
        android:id="@+id/movie_poster" />

    <RelativeLayout
        android:id="@+id/thumb_bottom_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="48dp"
        android:gravity="center_vertical">

        <TextView
            android:id="@+id/movie_name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:fontFamily="sans-serif"
            android:textColor="#aaa"
            android:textSize="16sp"

            />    
    </RelativeLayout>
</LinearLayout>

DetailsView 布局的一部分:

 <android.support.v4.widget.NestedScrollView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/scrollView"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:clipChildren="false">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:context="com.example.rashwan.popularmovies.MovieDetailsActivityFragment"
            android:orientation="vertical"
            android:focusableInTouchMode="true">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="310dp"
                android:orientation="horizontal"
                android:padding="10dp"
                android:baselineAligned="false"
                android:clipChildren="false">
                <FrameLayout
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:clipChildren="false">
                    <ImageView
                        android:layout_width="wrap_content"
                        android:minWidth="220dp"
                        android:layout_height="fill_parent"
                        android:layout_gravity="center_horizontal"
                        android:id="@+id/poster" />
                </FrameLayout>

                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical"
                    android:padding="5dp"
                    android:gravity="center_vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="ReleaseDate"
                        android:id="@+id/release_date"
                        android:layout_gravity="center_horizontal"
                        android:textAppearance="?android:attr/textAppearanceLarge"
                        android:padding="5dp"
                        />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="UserRating"
                        android:id="@+id/user_rating"
                        android:layout_gravity="center_horizontal"
                        android:textAppearance="?android:textAppearanceLarge"/>

                </LinearLayout>
            </LinearLayout>

在我的主题中我声明<item name="android:windowContentTransitions">true</item>我没有使用任何自定义动画,虽然我尝试了一些并且我也尝试推迟过渡但没有解决问题。

尝试将您的 类 放入 manifest.AS

我发现问题是我正在使用 picasso 库加载细节片段中的图像,所以我需要在细节 activity 中使用 postponeEnterTransition();然后在详细信息片段中,我使用 getActivity().startPostponedEnterTransition(); 开始过渡,但仅在使用 picasso.

加载图像之后

详情片段中的代码如下:

Picasso.with(getActivity()).load(posterUri).fit().into(poster, new Callback() {
  @Override
  public void onSuccess() {
      poster.getViewTreeObserver().addOnPreDrawListener(
      new ViewTreeObserver.OnPreDrawListener() {
          @Override
          public boolean onPreDraw() {
              if (isLollipop) {
                  poster.getViewTreeObserver().removeOnPreDrawListener(this);
                  getActivity().startPostponedEnterTransition();
              }
              return true;
          }
      });
  }