共享元素
如果要在两个拥有共享元素的操作行为之间安排屏幕转换动画:
1.请在您的主题中启用窗口内容转换。
1.请在您的主题中启用窗口内容转换。
<item name="android:windowContentTransitions">true</item>
2.在您的风格中指定一个共享元素转换。给要共享的元素设置transitionname
3.将您的转换定义为 XML 资源。共享元素动画可以使用xml定义
4.利用 android:transitionName 属性对两个布局中的共享元素指定一个通用名称。
5.使用 ActivityOptions.makeSceneTransitionAnimation() 方法。
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 对象:
如果要在两个拥有多个共享元素的操作行为之间安排场景转换动画,请以 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退出和进入的时候都会调用一次。