標籤雲

搜尋此網誌

2015/09/11

Animation - Activity Scene Transition

前面看過了 Scene Transition
其實 Android 官方範例裡還有另一個關於 Activity 轉場 Transition

那就順便重點學習一下嚕

// MainActivity 裡面只有一個 GridView
// 而它的 AdapterView.OnItemClickListener 是這樣的
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
    Item item = (Item) adapterView.getItemAtPosition(position);

    // 建立 intent 並把 item id 塞進 extra 中
    Intent intent = new Intent(this, DetailActivity.class);
    intent.putExtra(DetailActivity.EXTRA_PARAM_ID, item.getId());

    // 這裡利用 ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity, Pair...<View, String> sharedElements)
    // 建立轉場動畫,注意到它需要傳入Pair<View, String> 一一把 view 跟識別名稱傳入
    ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
        this,
        new Pair<View, String>( view.findViewById(R.id.imageview_item), DetailActivity.VIEW_NAME_HEADER_IMAGE ),
        new Pair<View, String>( view.findViewById(R.id.textview_name), DetailActivity.VIEW_NAME_HEADER_TITLE )
    );
    // 然後用 ActivityCompat.startActivity 把 intent 跟 ActivityOptionsCompat(作為 Bundle) 傳入
    ActivityCompat.startActivity(this, intent, activityOptions.toBundle());
}

而在 DetailActivity 中
//bundle 用的 key
public static final String EXTRA_PARAM_ID = "detail:_id";

// 用作 activity scene transition 識別名稱
public static final String VIEW_NAME_HEADER_IMAGE = "detail:header:image";
public static final String VIEW_NAME_HEADER_TITLE = "detail:header:title";

private ImageView mHeaderImageView;
private TextView mHeaderTitle;

private Item mItem;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // 省略...

    // 用 id 取出 item
    mItem = Item.getItem(getIntent().getIntExtra(EXTRA_PARAM_ID, 0));

    mHeaderImageView = (ImageView) findViewById(R.id.imageview_header);
    mHeaderTitle = (TextView) findViewById(R.id.textview_title);

    // 用 ViewCompat.setTransitionName 把 view 跟對應的共同識別名稱關連起來
    ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE);
    ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE);

    loadItem();
}

private void loadItem() {
    mHeaderTitle.setText(getString(R.string.image_header, mItem.getName(), mItem.getAuthor()));

    //API 5.0 以上才有支援 Activity Scene Transition,取得 Transition 並加上 TransitionListener
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && addTransitionListener()) {
        //用縮圖做 transition,待轉場動畫結束後再 load 大圖進來
        loadThumbnail();
    } else {
        //否則直接載入大圖
        loadFullSizeImage();
    }
}
private boolean addTransitionListener() {
    final Transition transition = getWindow().getSharedElementEnterTransition(); //取得預設的元件轉場 Transition

    if (transition != null) {
        transition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionEnd(Transition transition) {
                // 轉場結束所以可以 load 大圖跟移除 listener 了
                loadFullSizeImage();
                transition.removeListener(this);
            }
            @Override
            public void onTransitionStart(Transition transition) { }
            @Override
            public void onTransitionCancel(Transition transition) {
                // 如果轉場被 Cancel 也移除 listener
                transition.removeListener(this);
            }
            @Override
            public void onTransitionPause(Transition transition) { }
            @Override
            public void onTransitionResume(Transition transition) { }
        });
        return true;
    }

    // 如果 transition 是 null 則回傳 false
    return false;
}
// 省略...

這範例還挺簡單的
而且在 DetailActivity 按 back 回 MainActivity 時它也自動加了轉場呢

相關資料:
Android sample code - Activity Scene Transition Basic

沒有留言: