AndroidStudio 2.3 Beta 1
我试图让转换与片段一起工作,我正在使用的图像如何转换。它只是正常弹出。
我创建了一个简单的应用程序来尝试让它工作。我有2个片段ListMovieFragment
和DetailMovieFragment
。 1 MainActivity
。
用户将点击ListMovieFragment
中的图片转换为DetailMovieFragment
。
这是我的Transition xml change_image_transform:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeImageTransform/>
</transitionSet>
ListMovieFragment:
public class ListMovieFragment extends Fragment {
public interface MovieSelectedListener {
void onMovieSelected(int movieId);
}
private MovieSelectedListener mMovieSelectedListener;
public ListMovieFragment() {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mMovieSelectedListener = (MovieSelectedListener)context;
}
@Override
public void onDetach() {
super.onDetach();
mMovieSelectedListener = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_list, container, false);
final ImageView ivMoviePoster = (ImageView)view.findViewById(R.id.ivMoviePoster);
ivMoviePoster.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mMovieSelectedListener != null) {
mMovieSelectedListener.onMovieSelected(12345);
}
}
});
Glide.with(getActivity())
.load("https://image.tmdb.org/t/p/w185/qjiskwlV1qQzRCjpV0cL9pEMF9a.jpg")
.placeholder(R.drawable.placeholder_poster)
.centerCrop()
.crossFade()
.into(ivMoviePoster);
return view;
}
}
DetailMovieFragment
public class DetailMovieFragment extends Fragment {
public DetailMovieFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_detail, container, false);
final ImageView ivMovieDetailPoster = (ImageView)view.findViewById(R.id.ivMovieDetailPoster);
Glide.with(getActivity())
.load("https://image.tmdb.org/t/p/w185/qjiskwlV1qQzRCjpV0cL9pEMF9a.jpg")
.placeholder(R.drawable.placeholder_poster)
.centerCrop()
.crossFade()
.into(ivMovieDetailPoster);
return view;
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements ListMovieFragment.MovieSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.activity_main, new ListMovieFragment(), "listmoviefragment");
fragmentTransaction.commit();
}
}
@Override
public void onMovieSelected(int movieId) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
/* Get the fragments that will be using the transition */
ListMovieFragment listMovieFragment = new ListMovieFragment();
DetailMovieFragment detailMovieFragment = new DetailMovieFragment();
/* Inflate the transition */
Transition changeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(R.transition.change_image_transform);
Transition explodeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(android.R.transition.explode);
/* Set the exit and return on the source fragment (ListMovieFragment) */
listMovieFragment.setSharedElementReturnTransition(changeTransition);
listMovieFragment.setExitTransition(explodeTransition);
/* Set the enter on the destination fragment (MovieDetailFragment) */
detailMovieFragment.setSharedElementEnterTransition(changeTransition);
detailMovieFragment.setEnterTransition(explodeTransition);
/* Get the shared imageview from the source fragment (MovieListFragment) */
final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image));
fragmentTransaction.commit();
}
else {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.commit();
}
}
@Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
else {
super.onBackPressed();
}
}
}
ListMovieFragment的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="6dp">
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ivMoviePoster"
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/placeholder_poster"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:transitionName="@string/transition_poster_image">
</ImageView>
</LinearLayout>
DetailMovieFragment的布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="me.androidbox.fragmenttransitions.detail.DetailMovieFragment">
<ImageView
android:id="@+id/ivMovieDetailPoster"
android:layout_width="140dp"
android:layout_height="160dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="112dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:layout_gravity="end"
android:transitionName="@string/transition_poster_image"/>
</FrameLayout>
转换名称的字符串名称:
<string name="transition_poster_image">imagePoster</string>
实施看似简单,所以我认为我的错误是我忽视的。
非常感谢任何建议,
答案 0 :(得分:11)
您的代码中存在两个问题:onMovieSelected
方法:
ListMovieFragment
的新实例,然后对其应用转换逻辑。
但是你忘了你已经有了这个片段的实例(你是用onCreate
方法创建的)。
因此,您需要从ListMovieFragment
检索现有的FragmentManager
对象,然后将转换应用于该对象。DetailMovieFragment
的一个实例,但随后突然将ListMoveFragment
替换为新的onMovieSelected
。 因此,您的固定@Override
public void onMovieSelected(int movieId) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
/* Get the fragments that will be using the transition */
ListMovieFragment listMovieFragment = (ListMovieFragment) getSupportFragmentManager().findFragmentByTag("listmoviefragment");
DetailMovieFragment detailMovieFragment = new DetailMovieFragment();
/* Inflate the transition */
Transition changeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(R.transition.change_image_transform);
Transition explodeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(android.R.transition.explode);
/* Set the exit and return on the source fragment (ListMovieFragment) */
listMovieFragment.setSharedElementReturnTransition(changeTransition);
listMovieFragment.setExitTransition(explodeTransition);
/* Set the enter on the destination fragment (MovieDetailFragment) */
detailMovieFragment.setSharedElementEnterTransition(changeTransition);
detailMovieFragment.setEnterTransition(explodeTransition);
/* Get the shared imageview from the source fragment (MovieListFragment) */
final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image));
fragmentTransaction.commit();
} else {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.commit();
}
}
方法将是:
{{1}}
现在这应该有效。
PS 我已经使用过您的代码并运行它,并注意到您有一些奇怪的过渡,所以如果您遇到一些问题,请查看great article,如何顺利进行用户友好的过渡与片段:)
答案 1 :(得分:3)
在添加到片段事务时,不要创建新的对象片段,重用应用了进入和退出转换的现有片段。
public class MainActivity extends AppCompatActivity implements ListMovieFragment.MovieSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ListMovieFragment listMovieFragment = new ListMovieFragment();
Transition changeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(R.transition.change_image_transform);
Transition explodeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(android.R.transition.explode);
listMovieFragment.setSharedElementReturnTransition(changeTransition);
listMovieFragment.setExitTransition(explodeTransition);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//don't create new ListMovieFragment use existing listMovieFragment instance
fragmentTransaction.add(R.id.activity_main, listMovieFragment, "listmoviefragment");
fragmentTransaction.commit();
}else {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.activity_main, new ListMovieFragment(), "listmoviefragment");
fragmentTransaction.commit();
}
}
}
@Override
public void onMovieSelected(int movieId) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
/* Get the fragments that will be using the transition */
ListMovieFragment listMovieFragment = new ListMovieFragment();
DetailMovieFragment detailMovieFragment = new DetailMovieFragment();
/* Inflate the transition */
Transition changeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(R.transition.change_image_transform);
Transition explodeTransition = TransitionInflater
.from(MainActivity.this)
.inflateTransition(android.R.transition.explode);
/* Set the exit and return on the source fragment (ListMovieFragment) */
listMovieFragment.setSharedElementReturnTransition(changeTransition);
listMovieFragment.setExitTransition(explodeTransition);
/* Set the enter on the destination fragment (MovieDetailFragment) */
detailMovieFragment.setSharedElementEnterTransition(changeTransition);
detailMovieFragment.setEnterTransition(explodeTransition);
/* Get the shared imageview from the source fragment (MovieListFragment) */
final ImageView ivSharedImage = (ImageView)findViewById(R.id.ivMoviePoster);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//don't create new DetailMovieFragment use existing detailMovieFragment instance
fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image));
fragmentTransaction.commit();
}
else {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main, new DetailMovieFragment(), "detailmoviefragment");
fragmentTransaction.addToBackStack("detailmoviefragment");
fragmentTransaction.commit();
}
}
@Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
else {
super.onBackPressed();
}
}
}