2018年9月7日金曜日

Android Activity Transitions の対象をグループ化する

ActivityTransition に Slide を指定すると、デフォルトでは View ごとに別々にアニメーションします。

例えばボタンを縦に並べた Activity に Slide で enter すると、スライド中はボタンの間隔が広がって、徐々に詰まっていきます。

左 → 右 : スライド中


ボタン同士の配置そのままに Slide させるには、ボタンの親の ViewGroup の setTransitionGroup() で true をセットします。
  1. class MainActivity : AppCompatActivity() {  
  2.   
  3.     override fun onCreate(savedInstanceState: Bundle?) {  
  4.         super.onCreate(savedInstanceState)  
  5.         setContentView(R.layout.activity_main)  
  6.   
  7.         button.setOnClickListener {  
  8.             startActivity(  
  9.                 Intent(this, MainActivity2::class.java),  
  10.                 ActivityOptions.makeSceneTransitionAnimation(this).toBundle()  
  11.             )  
  12.         }  
  13.     }  
  14. }  
  1. class MainActivity2 : AppCompatActivity() {  
  2.   
  3.     override fun onCreate(savedInstanceState: Bundle?) {  
  4.         super.onCreate(savedInstanceState)  
  5.   
  6.         window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)  
  7.         window.enterTransition = Slide()  
  8.         window.exitTransition = Slide()  
  9.   
  10.         setContentView(R.layout.activity_main2)  
  11.   
  12.         // これを追加  
  13.         constraintLayout.isTransitionGroup = true  
  14.     }  
  15. }  


左 → 右 : スライド中



解説

ViewGroup の captureTransitioningViews() で isTransitionGroup() が false の場合、各子 View の captureTransitioningViews() を呼びます。 View の captureTransitioningViews() では VISIBLE な場合自身を transition するリストに追加します。

つまり、ViewGroup の setTransitionGroup() で true をセットすると、その ViewGroup が transition するリストに追加され、子 View はされなくなります。
  1. public abstract class ViewGroup ... {  
  2.   
  3.     ...  
  4.   
  5.     /** @hide */  
  6.     @Override  
  7.     public void captureTransitioningViews(List<View> transitioningViews) {  
  8.         if (getVisibility() != View.VISIBLE) {  
  9.             return;  
  10.         }  
  11.         if (isTransitionGroup()) {  
  12.             transitioningViews.add(this);  
  13.         } else {  
  14.             int count = getChildCount();  
  15.             for (int i = 0; i < count; i++) {  
  16.                 View child = getChildAt(i);  
  17.                 child.captureTransitioningViews(transitioningViews);  
  18.             }  
  19.         }  
  20.     }  
  21.   
  22.     ...  
  23. }  
  24.   
  25. public class View ...{  
  26.   
  27.    ...  
  28.   
  29.     public void captureTransitioningViews(List<View> transitioningViews) {  
  30.         if (getVisibility() == View.VISIBLE) {  
  31.             transitioningViews.add(this);  
  32.         }  
  33.     }  
  34.   
  35.     ...  
  36. }  



0 件のコメント:

コメントを投稿