Android开发 之 共享元素

共享元素

如果要在两个拥有共享元素的操作行为之间安排屏幕转换动画:

1.请在您的主题中启用窗口内容转换。
<item name="android:windowContentTransitions">true</item>

2.在您的风格中指定一个共享元素转换。给要共享的元素设置transitionname
3.将您的转换定义为 XML 资源。共享元素动画可以使用xml定义
4.利用 android:transitionName 属性对两个布局中的共享元素指定一个通用名称。
5.使用 ActivityOptions.makeSceneTransitionAnimation() 方法。

// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // start the new activity
        startActivity(intent, options.toBundle());
    }
});

对于在您的代码中生成的共享动态视图,请使用 View.setTransitionName() 方法在两个操作行为中指定一个通用元素名称。
如果要在完成第二项操作行为时反转场景转换动画,请调用 Activity.finishAfterTransition() 方法而非 Activity.finish()。

以多个共享元素启动一个操作行为
如果要在两个拥有多个共享元素的操作行为之间安排场景转换动画,请以 android:transitionName 属性(或在两个操作行为中使用 View.setTransitionName() 方法)定义共享元素,并以下列方式创建一个 ActivityOptions 对象:
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"))

以上是基本技术点,下面看实例,先看效果:


代码:
package th.zxq.com.quxianyundong;

import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.SharedElementCallback;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/7/24.
 */

public class MyAnimationActivity extends AppCompatActivity {
    public static int[] list=new int[]{R.mipmap.tp01,R.mipmap.tp02,R.mipmap.tp03,R.mipmap.tp04,R.mipmap.tp05,R.mipmap.tp06};
    private RecyclerView recycle;
    private SharedElementCallback callback=new SharedElementCallback() {
        @Override
        public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
            super.onMapSharedElements(names, sharedElements);
            Log.e("callback","MyAnimationActivity");
            if(startingPosition!=currentItem)
            {
                View newSharedElement = recycle.findViewWithTag(currentItem+"");
                if (newSharedElement != null) {
                    names.clear();
                    names.add(currentItem+"");
                    sharedElements.clear();
                    sharedElements.put(currentItem+"", newSharedElement);
                }
            }
        }
    };
    private int currentItem=-1,startingPosition=-1;
    private PicAdapter picAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        setContentView(R.layout.activity_myanimation);
        getWindow().setEnterTransition(new Slide(Gravity.LEFT));
        getWindow().setExitTransition(new Slide(Gravity.LEFT));
        setExitSharedElementCallback(callback);
        recycle = (RecyclerView) findViewById(R.id.recycle);
        recycle.setLayoutManager(new GridLayoutManager(this,2));
        picAdapter = new PicAdapter();
        recycle.setAdapter(picAdapter);
    }
    public class PicAdapter extends RecyclerView.Adapter
    {
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(MyAnimationActivity.this).inflate(R.layout.item_recycle, parent, false);
            return new MyViewHolder(view);
        }
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            MyViewHolder mholder= (MyViewHolder) holder;
            mholder.setData(position);
        }
        @Override
        public int getItemCount() {
            return list.length;
        }
    }
    public class MyViewHolder extends RecyclerView.ViewHolder
    {
        private ImageView iv;
        public MyViewHolder(View itemView) {
            super(itemView);
            iv= (ImageView) itemView.findViewById(R.id.iv);

        }
        public void setData(final int position)
        {
            iv.setTransitionName(position+"");
            iv.setTag(position+"");
            iv.setBackgroundResource(list[position]);
            iv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startingPosition=position;
                    currentItem=startingPosition;
                    Intent intent = new Intent(MyAnimationActivity.this, PicDetailActivity.class);
                    intent.putExtra("transitionName",iv.getTransitionName());
                    ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(MyAnimationActivity.this, iv, iv.getTransitionName());
                    startActivity(intent,activityOptions.toBundle());
                }
            });
        }
    }

    @Override
    public void onActivityReenter(int resultCode, Intent data) {
        super.onActivityReenter(resultCode, data);
        currentItem = data.getExtras().getInt("currentItem");
        if (startingPosition != currentItem) {
            recycle.scrollToPosition(currentItem);
        }
        postponeEnterTransition();
        recycle.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                recycle.getViewTreeObserver().removeOnPreDrawListener(this);
                // TODO: figure out why it is necessary to request layout here in order to get a smooth transition.
                recycle.requestLayout();
                startPostponedEnterTransition();
                return true;
            }
        });
    }
}


package th.zxq.com.quxianyundong;

import android.app.SharedElementCallback;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;

import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/7/24.
 */

public class PicDetailActivity extends AppCompatActivity {
    private ImageView iv_push;
    private ViewPager viewpager;
    private int mCurrentPosition=-1;
    private ImageView currentiv;
    private boolean mIsReturning;
    private final SharedElementCallback mCallback = new SharedElementCallback() {
        @Override
        public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
            Log.e("callback","PicDetailActivity");
            if(mIsReturning&&mCurrentPosition!=Integer.parseInt(startpositon))
            {
                names.clear();
                names.add(currentiv.getTransitionName());
                sharedElements.clear();
                sharedElements.put(currentiv.getTransitionName(), currentiv);
            }
        }
    };
    private String startpositon;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_picdetail);
        postponeEnterTransition();
        startpositon = (String) getIntent().getExtras().get("transitionName");
        mCurrentPosition=Integer.parseInt(startpositon);
        setEnterSharedElementCallback(mCallback);
        iv_push= (ImageView) findViewById(R.id.iv_push);
        viewpager = (ViewPager) findViewById(R.id.viewpager);
        viewpager.setAdapter(new Myadapter());
        viewpager.setCurrentItem(Integer.parseInt(startpositon));
//        iv_push.setTransitionName(transitionName);
//        iv_push.setBackgroundResource(MyAnimationActivity.list[Integer.parseInt(transitionName)]);
        viewpager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
            @Override
            public void onPageSelected(int position) {
                mCurrentPosition = position;
            }
        });
    }
    public class Myadapter extends PagerAdapter
    {
        private View view;

        public Myadapter()
        {
        }
        @Override
        public int getCount() {
            return MyAnimationActivity.list.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((ImageView) object);
//            super.destroyItem(container, position, object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {    //实例化Item
            // TODO Auto-generated method stub
            view =  LayoutInflater.from(PicDetailActivity.this).inflate(R.layout.item_detailpagerview, null);
            final ImageView iv_pager= (ImageView) view.findViewById(R.id.iv_pager);
            iv_pager.setTransitionName(position+"");
            iv_pager.setBackgroundResource(MyAnimationActivity.list[Integer.parseInt(iv_pager.getTransitionName())]);
            iv_pager.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    iv_pager.getViewTreeObserver().removeOnPreDrawListener(this);
                    startPostponedEnterTransition();
                    return true;
                }
            });
            ViewGroup vg= (ViewGroup) iv_pager.getParent();
            vg.removeView(iv_pager);
            container.addView(iv_pager);
            return iv_pager;
        }

        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            super.setPrimaryItem(container, position, object);
            currentiv= (ImageView) object;
        }
    }
    @Override
    public void finishAfterTransition() {
        mIsReturning = true;
        Intent data = new Intent();
        data.putExtra("currentItem",mCurrentPosition);
        setResult(RESULT_OK, data);
        super.finishAfterTransition();
    }
}

上面代码中的 SharedElementCallback是在activity退出和进入的时候都会调用一次。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值