java - 使用 android fragment 动画共享元素转换似乎是一场噩梦

标签 java android android-fragments android-animation android-recyclerview

动画化两个 fragment 之间的共享元素过渡似乎很痛苦。我使用完全相同的代码让它在我的应用程序的其他地方工作。

这是我在 recyclerview 适配器中的点击代码:

private void click(int position, ItemViewHolder holder){

final ItemDescription itemDescription = itemListFiltered.get(position);
FragmentManager fm = mContext.getSupportFragmentManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && itemDescription != null) {

    //animate transition
    TransitionSet transitionSet = new TransitionSet();
    transitionSet.addTransition(new ChangeTransform());
    transitionSet.addTransition(new ChangeBounds());
    transitionSet.addTransition(new ChangeImageTransform());
    transitionSet.setDuration(300);

    //set up fragment
    ScanDetailsFragment frag = ScanDetailsFragment.newInstance(itemDescription, holder.productImage.getTransitionName());
    frag.setEnterTransition(transitionSet);
    frag.setExitTransition(transitionSet);

    fm.beginTransaction().replace(R.id.fragment_container, frag)
            .addSharedElement(holder.productImage, "product_image")
            .addToBackStack("item details")
            .commit();
}else {
    ScanDetailsFragment itemDetails = ScanDetailsFragment.newInstance(itemDescription);
    fm.beginTransaction().replace(R.id.fragment_container, itemDetails).addToBackStack("item details").commit();
}

我似乎无法让这个动画正常工作。

最佳答案

我是这样做的

带有 RecyclerView 的 fragment

public class DogFragment extends Fragment implements DogAdapter.OnItemCLickListener {

    public static final String TAG = "DogFragment";

    @InjectView(R.id.recyclerview_dog)
    RecyclerView mRecyclerView;

    DogAdapter adapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        final View v = inflater.inflate(R.layout.fragment_dog, container, false);
        ButterKnife.inject(this, v);
        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        final List<Integer> images = new ArrayList<>();
        images.add(R.drawable.dog1);
        images.add(R.drawable.dog2);
        images.add(R.drawable.dog3);

        final RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 1);
        mRecyclerView.setLayoutManager(layoutManager);
        adapter = new DogAdapter(images);
        adapter.setOnItemClickListener(this);
        mRecyclerView.setAdapter(adapter);
    }

    public String getTAG() {
        return TAG;
    }

    @Override
    public void onItemClick(int position, int imageRefId, ImageView imageView) {
        SingleDogFragment fragment = SingleDogFragment.getInstance(getActivity(), adapter.getImageTransitionName(getActivity(), position), imageRefId);
        getFragmentManager().beginTransaction()
                .addSharedElement(imageView, adapter.getImageTransitionName(getActivity(), position))
                .replace(R.id.container, fragment, fragment.getTag())
                .addToBackStack(null)
                .commit();
    }
}

适配器

public class DogAdapter extends RecyclerView.Adapter<DogAdapter.ViewHolder> {

    private OnItemCLickListener mItemClickListener;
    private List<Integer> mImages;

    public DogAdapter(List<Integer> images) {
        mImages = images;
    }

    public int getItem(int position) {
        return mImages.get(position);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.gridview_element_dog, viewGroup, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.mImageView.setImageResource(getItem(i));
        viewHolder.mImageView.setTransitionName(
                getImageTransitionName(viewHolder.mImageView.getContext(), i)
        );
    }

    public String getImageTransitionName(Context context, int position) {
        return context.getString(R.string.dog_transition_name) + position;
    }

    @Override
    public int getItemCount() {
        return mImages.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        @InjectView(R.id.dog_imageview)
        ImageView mImageView;

        public ViewHolder(final View view) {
            super(view);
            ButterKnife.inject(this, view);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mItemClickListener != null) {
                mItemClickListener.onItemClick(getPosition(), getItem(getPosition()), mImageView);
            }
        }
    }

    public interface OnItemCLickListener {
        public void onItemClick(int position, int refId, ImageView imageView);
    }

    public void setOnItemClickListener(final OnItemCLickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }

}

目标 fragment

public class SingleDogFragment extends Fragment {

    private static final String ARG_TRANSITION_NAME = "ARG_TRANSITION_NAME";
    private static final String ARG_IMAGE_REF_ID = "ARG_IMAGE_REF_ID";

    @InjectView(R.id.single_dog_imageview)
    ImageView mDogImage;

    public static SingleDogFragment getInstance(Context context, String transitionName, int imageRefId) {
        SingleDogFragment fragment = new SingleDogFragment();
        Bundle bundle = new Bundle();
        bundle.putString(ARG_TRANSITION_NAME, transitionName);
        bundle.putInt(ARG_IMAGE_REF_ID, imageRefId);
        fragment.setSharedElementEnterTransition(TransitionInflater.from(context).inflateTransition(R.transition.change_transform));
        fragment.setEnterTransition(TransitionInflater.from(context).inflateTransition(R.transition.slide_left));
        fragment.setExitTransition(TransitionInflater.from(context).inflateTransition(R.transition.slide_left));
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View v = inflater.inflate(R.layout.fragment_single_dog, container, false);
        ButterKnife.inject(this, v);
        mDogImage.setTransitionName(getArguments().getString(ARG_TRANSITION_NAME));
        mDogImage.setImageResource(getArguments().getInt(ARG_IMAGE_REF_ID));
        return v;
    }
}

change_transform.xml

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <targets>
        <target android:excludeId="@android:id/statusBarBackground"/>
        <target android:excludeId="@android:id/navigationBarBackground"/> <!-- exclude the status bar and the navigation bar of the animation -->
    </targets>
    <changeBounds/>
    <changeTransform/>
</transitionSet>

这是它的样子

enter image description here

希望我能帮上忙!

关于java - 使用 android fragment 动画共享元素转换似乎是一场噩梦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31799619/

相关文章:

java - 将文件对象转换为位图

android - 如何处理来自 SD 卡的音乐文件列表

java - 尝试创建新的 EditText 后 setcontentview 使应用程序崩溃

android - 如何在 TabHost/ViewPager 父 fragment 中恢复子 fragment

android - 如何在 Android 中使用链接从 Google Drive 下载文件?

java - Android:如何知道何时从fragment返回

java - 如何在java中显示50位或更多(例如乘法)?

java - 如何以正确的方式使用 Enum?

java - 未加载 Spring 上下文

java - 如何在 Android Spinner 的下拉菜单中启用快速滚动(拇指)?