使用Android片段动画共享元素转换似乎是一场噩梦。

6

在两个片段之间实现共享元素的转换动画似乎很麻烦。我已经在我的应用程序中的其他地方使用完全相同的代码使其工作。

这是我在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();
}

我似乎无法让这个动画正常运行。
1个回答

17

这是我的做法

使用RecyclerView的片段

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;
    }

}

目标片段

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>

以下是它的外观

输入图像描述

希望我能帮到你!


1
你能发布 slide_left 过渡效果吗? - Alex Fragotsis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接