Android 过渡动画原来可以这样写

DeaCPIQ 8年前
   <h2>关键类</h2>    <ul>     <li>android.transition.TransitionManager</li>     <li>android.transition.Transition 抽象类      <ul>       <li>TransitionSet        <ul>         <li>AutoTransition</li>        </ul> </li>       <li>ChangeBounds</li>       <li>Visibility 抽象类        <ul>         <li>Fade</li>         <li>Explode ( design 包中无适配)</li>         <li>Slide ( design 包中无适配)</li>        </ul> </li>       <li>TextScale</li>       <li>ChangeClipBounds ( design 包中无适配)</li>       <li>ChangeImageTransform ( design 包中无适配)</li>       <li>ChangeScroll ( design 包中无适配)</li>       <li>ChangeTransform ( design 包中无适配)</li>      </ul> </li>    </ul>    <h2><strong>介绍</strong></h2>    <p>Visibility 抽象类的子类:Fade, Explode, Slide 动画作用于 View 的 Visibility 属性改变的时候。</p>    <h2>适配</h2>    <p>对应的适配包在design com.android.support:design:x.x.x 包中</p>    <pre>  <code class="language-java">compile 'com.android.support:design:25.0.0'</code></pre>    <p>更好的适配方案:(使用的时候注意导包 com.transitionseverywhere.xxx )</p>    <pre>  <code class="language-java">compile "com.andkulikov:transitionseverywhere:1.6.9"</code></pre>    <p><!--more--></p>    <h2><strong>上代码</strong></h2>    <p>下面的例子 使用适配包 compile "com.andkulikov:transitionseverywhere:1.6.9" 测试系统 Android4.1</p>    <h2><strong>默认效果</strong></h2>    <h3><strong>布局关键代码:</strong></h3>    <pre>  <code class="language-java"><LinearLayout      android:id="@+id/ll_container_one"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:gravity="center"      android:orientation="vertical">        <Button          android:id="@+id/btn_one"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Fad"/>        <TextView          android:id="@+id/tv_one"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_marginTop="16dp"          android:text="Transitions are awesome!"          android:visibility="gone"/>    </LinearLayout></code></pre>    <h3><strong>Activity 中代码:</strong></h3>    <pre>  <code class="language-java">final LinearLayout transitionsContainer = (LinearLayout) findViewById(R.id.ll_container_one);  final TextView text = (TextView) findViewById(R.id.tv_one);  final Button button = (Button) findViewById(R.id.btn_one);    button.setOnClickListener(v -> {      TransitionManager.beginDelayedTransition(transitionsContainer);        if (text.getVisibility() == View.VISIBLE) {          text.setVisibility(View.GONE);      } else {          text.setVisibility(View.VISIBLE);      }  });</code></pre>    <h3><strong>最终效果:</strong></h3>    <p><img src="https://simg.open-open.com/show/e4cb9ffb0716d933a94ce31be842cb0c.gif"></p>    <p>默认效果</p>    <h3><strong>代码解释</strong></h3>    <p>TransitionManager 中的 beginDelayedTransition 方法:</p>    <pre>  <code class="language-java">public static void beginDelayedTransition(final ViewGroup sceneRoot){...}  public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {...}</code></pre>    <ol>     <li>方法一:效果如上面的默认效果</li>     <li>方法二:参数而用于定制动画效果, 参数为 Transition 的子类,常用的有:Fade, ChangeBounds, Slide,</li>    </ol>    <p>对用画具体效果做定制:设置动画时间,设置动画加速度,设置动画延时</p>    <pre>  <code class="language-java">transition.setDuration(300);  transition.setInterpolator(new FastOutSlowInInterpolator());  transition.setStartDelay(200);</code></pre>    <h2><strong>Fade 淡出淡入</strong></h2>    <h3><strong>布局如上 更改 Activity 中代码:</strong></h3>    <pre>  <code class="language-java">final LinearLayout transitionsContainer = (LinearLayout) findViewById(R.id.ll_container_one);  final TextView text = (TextView) findViewById(R.id.tv_one);  final Button button = (Button) findViewById(R.id.btn_one);    button.setOnClickListener(v -> {      Fade fade = new Fade();      TransitionManager.beginDelayedTransition(transitionsContainer, fade);        if (text.getVisibility() == View.VISIBLE) {          text.setVisibility(View.GONE);      } else {          text.setVisibility(View.VISIBLE);      }  });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/04f41b3d7a63e66c05eacc1537e284e6.gif"></p>    <p style="text-align:center">Fade效果</p>    <h2><strong>Slide 移动</strong></h2>    <h3><strong>布局如上 更改 Activity 中代码:</strong></h3>    <pre>  <code class="language-java">final LinearLayout transitionsContainer = (LinearLayout) findViewById(R.id.ll_container_one);  final TextView text = (TextView) findViewById(R.id.tv_one);  final Button button = (Button) findViewById(R.id.btn_one);    button.setOnClickListener(v -> {      // Slide slide = new Slide();      Slide slide = new Slide(Gravity.RIGHT);      TransitionManager.beginDelayedTransition(transitionsContainer, slide);        if (text.getVisibility() == View.VISIBLE) {          text.setVisibility(View.GONE);      } else {          text.setVisibility(View.VISIBLE);      }  });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/cc8fa52b656a004d0e2e95c43a6768d9.gif"></p>    <p style="text-align:center">Slide</p>    <h3><strong>Slide 构造方法</strong></h3>    <pre>  <code class="language-java">/**   * Constructor using the default {@link Gravity#BOTTOM}   * slide edge direction.   */  public Slide() {      setSlideEdge(Gravity.BOTTOM);  }</code></pre>    <p>设置滑出方向:</p>    <pre>  <code class="language-java">/**   * Constructor using the provided slide edge direction.   */  public Slide(@GravityFlag int slideEdge) {      setSlideEdge(slideEdge);  }</code></pre>    <h2><strong>Scale 缩放</strong></h2>    <h3><strong>布局如上 更改 Activity 中代码:</strong></h3>    <pre>  <code class="language-java">final LinearLayout transitionsContainer = (LinearLayout) findViewById(R.id.ll_container_one);  final TextView text = (TextView) findViewById(R.id.tv_one);  final Button button = (Button) findViewById(R.id.btn_one);    button.setOnClickListener(v -> {      // Scale scale = new Scale();      Scale scale = new Scale(0.7f);      TransitionManager.beginDelayedTransition(transitionsContainer, scale);        if (text.getVisibility() == View.VISIBLE) {          text.setVisibility(View.GONE);      } else {          text.setVisibility(View.VISIBLE);      }  });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4caaf3f400b0a67d7e23b60c2bc11e6e.gif"></p>    <p style="text-align:center">Scale</p>    <h3><strong>Scale 构造方法</strong></h3>    <pre>  <code class="language-java">public Scale() {   }    /**   * @param disappearedScale Value of scale on start of appearing or in finish of disappearing.   *                         Default value is 0. Can be useful for mixing some Visibility   *                         transitions, for example Scale and Fade   */  public Scale(float disappearedScale) {      setDisappearedScale(disappearedScale);  }</code></pre>    <p>参数设置了缩放起始值或者最终值。</p>    <h2><strong>TransitionSet 动画集合</strong></h2>    <pre>  <code class="language-java">final LinearLayout transitionsContainer = (LinearLayout) findViewById(R.id.ll_container_one);  final TextView text = (TextView) findViewById(R.id.tv_one);  final Button button = (Button) findViewById(R.id.btn_one);    button.setOnClickListener(v -> {        TransitionSet set = new TransitionSet()              .addTransition(new Scale(0.7f))              .addTransition(new Fade())              .setInterpolator(visible ? new LinearOutSlowInInterpolator() :                      new FastOutLinearInInterpolator());        TransitionManager.beginDelayedTransition(transitionsContainer, set);        if (text.getVisibility() == View.VISIBLE) {          text.setVisibility(View.GONE);      } else {          text.setVisibility(View.VISIBLE);      }  });</code></pre>    <h3>最终效果</h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/677e357c6baada35402723f4d2f6621d.gif"></p>    <p style="text-align:center">TransitionSet</p>    <h2><strong>Recolor 颜色渐变</strong></h2>    <p>空间的背景色或者文字颜色改变的动画</p>    <h3>布局</h3>    <pre>  <code class="language-java"><LinearLayout      android:id="@+id/ll_container_recolor"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:gravity="center"      android:orientation="vertical"      android:visibility="visible">          <Button          android:id="@+id/btn_recolor"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Recolor"/>        <Button          android:id="@+id/btn_normal"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_marginTop="10dp"          android:text="Normal"          android:visibility="visible"/>    </LinearLayout></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">final ViewGroup transitionsContainerRecolor = (ViewGroup) findViewById(R.id.ll_container_recolor);  final Button btnRecolor = (Button) findViewById(R.id.btn_recolor);  final Button btnNormal = (Button) findViewById(R.id.btn_normal);    int green = getResources().getColor(R.color.green);  int white = getResources().getColor(R.color.white);  int grey = getResources().getColor(R.color.grey);    btnRecolor.setOnClickListener(v -> {      TransitionManager.beginDelayedTransition(transitionsContainerRecolor, new Recolor());  //            btnRecolor.setBackgroundColor(visible ? green : white); // 无动画效果      btnRecolor.setTextColor(visible ? white : grey);  //            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {  //                btnRecolor.setBackground(new ColorDrawable(visible ? green : white));  //            } else {      btnRecolor.setBackgroundDrawable(new ColorDrawable(visible ? green : white));  //            }      visible = !visible;  });    btnNormal.setOnClickListener(v -> {      btnNormal.setBackgroundColor(visible ? green : white);      btnNormal.setTextColor(visible ? white : green);      visible = !visible;  });</code></pre>    <p>注意: btnRecolor.setBackgroundColor(visible ? green : white); // 无动画效果 通过 setBackgroundColor 背景色时没有动画效果,可以使用 setBackground , setBackgroundDrawable</p>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b141153f1968cb3f782b61858bee5e85.gif"></p>    <p style="text-align:center">ReColor</p>    <h2><strong>Rotate 旋转</strong></h2>    <h3><strong>布局</strong></h3>    <pre>  <code class="language-java"><LinearLayout      android:id="@+id/ll_container_rotate"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:gravity="center"      android:orientation="vertical"      android:visibility="visible">          <Button          android:id="@+id/btn_rotate"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Rotate"/>        <ImageView          android:id="@+id/iv_rotate"          android:layout_width="40dp"          android:layout_height="40dp"          android:layout_marginTop="10dp"          android:src="@drawable/ic_clear_black_24dp"          android:visibility="visible"/>    </LinearLayout></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">final ViewGroup transitionsContainerRotate = (ViewGroup) findViewById(R.id.ll_container_rotate);  final Button btnRotate = (Button) findViewById(R.id.btn_rotate);  ImageView ivRotate = (ImageView) findViewById(R.id.iv_rotate);    btnRotate.setOnClickListener(v -> {      TransitionManager.beginDelayedTransition(transitionsContainerRotate, new Rotate());      ivRotate.setRotation(isRotated ? 0 : 135);      isRotated = !isRotated;  });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3cc750a908fae12b6f0cda9310d80541.gif"></p>    <p style="text-align:center">Rotate</p>    <h2><strong>ChangeText 文字改变时动画</strong></h2>    <h3><strong>布局</strong></h3>    <pre>  <code class="language-java"><LinearLayout      android:id="@+id/ll_container_change_text"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:gravity="center"      android:orientation="vertical"      android:visibility="visible">        <Button          android:id="@+id/btn_change_text"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="ChangeText"/>        <TextView          android:id="@+id/tv_text"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_marginTop="16dp"          android:text="Transitions are awesome!"          android:visibility="visible"/>    </LinearLayout></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">final LinearLayout transitionsContainerChangeText = (LinearLayout) findViewById(R.id.ll_container_change_text);  final TextView tvText = (TextView) findViewById(R.id.tv_text);  final Button btnChangeText = (Button) findViewById(R.id.btn_change_text);  String secText = " Second Text";  String firstText = "First Text";    btnChangeText.setOnClickListener(v -> {      TransitionManager.beginDelayedTransition(transitionsContainerChangeText,              new ChangeText().setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN));        tvText.setText(isFirstText ? secText : firstText);      isFirstText = !isFirstText;    });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/16bccb8531c88a6c79cb489689eea533.gif"></p>    <p style="text-align:center">ChangeText</p>    <h2><strong>TransitionName 制作 打乱动画</strong></h2>    <p>使用场景:</p>    <ol>     <li> <p>需要动态生成 ViewGroup 的子 View , 并且子 View 内容需要更新时</p> </li>     <li> <p>需要制作随机时</p> </li>    </ol>    <h3><strong>布局</strong></h3>    <p>注意:这里把 Button 移到了 LinearLayout 的外面,原因是一会创建子 View 的时候会先删除所有子 View(Button 也会被删除)。</p>    <pre>  <code class="language-java"><Button      android:id="@+id/btn_transition_name"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="打乱"/>      <LinearLayout      android:id="@+id/ll_container_transition_name"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:gravity="center"      android:orientation="vertical"      android:visibility="visible"></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">// TransitionName 做打乱动画  final LinearLayout transitionsContainerTransitionName = (LinearLayout) findViewById(R.id.ll_container_transition_name);  final Button btnTransitionName = (Button) findViewById(R.id.btn_transition_name);    LayoutInflater inflater = LayoutInflater.from(this);  ArrayList<String> titles = new ArrayList<>();  for (int i = 0; i < 4; i++) {      titles.add(String.format(Locale.CHINA, "Item %d", i));  }  createViews(inflater, transitionsContainerTransitionName, titles);    btnTransitionName.setOnClickListener(v -> {      TransitionManager.beginDelayedTransition(transitionsContainerTransitionName, new ChangeBounds());      Collections.shuffle(titles);      createViews(inflater, transitionsContainerTransitionName, titles);  });    // 独立的方法  // In createViews we should provide transition name for every view.  private static void createViews(LayoutInflater inflater, ViewGroup layout, List<String> titles) {      layout.removeAllViews();      for (String title : titles) {          TextView textView = (TextView) inflater.inflate(R.layout.text_view, layout, false);          textView.setText(title);          TransitionManager.setTransitionName(textView, title);          layout.addView(textView);      }  }</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/52f66efc165533e94b6c14b6b041c2a1.gif"></p>    <p style="text-align:center">TransitionName</p>    <h2><strong>Explode and Propagation 爆炸和传播</strong></h2>    <p>爆炸效果,和移动过渡动画比较相似,不过子 View 的移动方向是由其所在的位置决定的。子 View 的移动方向需要通过计算得到(通过 setEpicenterCallback 方法)</p>    <h3><strong>关键代码</strong></h3>    <p>这个例子使用 RecyclerView 和 GridLayoutManager 做基本布局,点击里面的 item 让其消失。</p>    <pre>  <code class="language-java">public void onClick(View clickedView) {      // save rect of view in screen coordinates      final Rect viewRect = new Rect();      clickedView.getGlobalVisibleRect(viewRect);        // create Explode transition with epicenter      Transition explode = new Explode()          .setEpicenterCallback(new Transition.EpicenterCallback() {              @Override              public Rect onGetEpicenter(Transition transition) {                  return viewRect;              }          });      explode.setDuration(1000);      TransitionManager.beginDelayedTransition(recyclerView, explode);        // remove all views from Recycler View      recyclerView.setAdapter(null);  }</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0d30164aaafc276d93b45e4fd417d873.gif"></p>    <p style="text-align:center">Exlode</p>    <h2><strong>ChangeImageTransform</strong></h2>    <h2><strong>Path (Curved) motion 路径过渡动画</strong></h2>    <p>所有的过渡动画都需要两个值:起始值和结束值</p>    <p>比如:通过 ChangeBounds 来改变 view 的位置,通过 setPathMotion 来提供路径</p>    <h3><strong>布局代码</strong></h3>    <pre>  <code class="language-java"><FrameLayout      android:id="@+id/fl_container_path_motion"      android:layout_width="match_parent"      android:layout_height="match_parent">          <Button          android:id="@+id/btn_path_motion"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Path Motion"/>      </FrameLayout></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">// path motion 路径过渡动画  final FrameLayout transitionsContainerPathMotion = (FrameLayout) findViewById(R.id.fl_container_path_motion);  Button btnPathMotion = (Button) findViewById(R.id.btn_path_motion);    btnPathMotion.setOnClickListener(v -> {        TransitionManager.beginDelayedTransition(transitionsContainerPathMotion,              new ChangeBounds().setPathMotion(new ArcMotion()).setDuration(500));        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) btnPathMotion.getLayoutParams();      params.gravity = isReturnAnimation ? (Gravity.LEFT | Gravity.TOP) :              (Gravity.BOTTOM | Gravity.RIGHT);      btnPathMotion.setLayoutParams(params);      isReturnAnimation = !isReturnAnimation;    });</code></pre>    <p>这里通过 LayoutParams 来控制 Button 在其父控件中的位置。</p>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/957ce02954d8a587a69e5e9c6204334c.gif"></p>    <p style="text-align:center">Path Motion</p>    <h2><strong>Targets 设置动画的目标对象</strong></h2>    <h3><strong>小总结</strong></h3>    <p>定义动画:</p>    <pre>  <code class="language-java">TransitionManager.beginDelayedTransition( viewGroup, transition);</code></pre>    <p>默认情况下,这里的 transition 动画会作用于 viewGroup 中的所有子 View</p>    <p>当我们需要在一个 ViewGroup 中定义多个动画,作用于不同的子 View 该如何做?</p>    <h3><strong>比如 让一个 TextView 移动, 另一个 TextView 淡出</strong></h3>    <h3><strong>布局</strong></h3>    <pre>  <code class="language-java"><LinearLayout             android:id="@+id/ll_container_target"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:gravity="center"             android:orientation="vertical"             android:visibility="visible">               <Button                 android:id="@+id/btn_target"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:text="Target"/>               <TextView                 android:id="@+id/tv_target_fade"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_marginTop="16dp"                 android:text="Transitions are awesome fade!"                 android:visibility="visible"/>               <TextView                 android:id="@+id/tv_target_slide"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_marginTop="16dp"                 android:text="Transitions are awesome slide!"                 android:visibility="visible"/>           </LinearLayout></code></pre>    <h3><strong>Activity 代码</strong></h3>    <pre>  <code class="language-java">// Targets 设置动画的目标对象   final LinearLayout transitionsContainerTarget = (LinearLayout) findViewById(R.id.ll_container_target);   final Button btnTarget = (Button) findViewById(R.id.btn_target);   final TextView tvFade = (TextView) findViewById(R.id.tv_target_fade);   final TextView tvSlide = (TextView) findViewById(R.id.tv_target_slide);       btnTarget.setOnClickListener(v -> {       Slide slide = new Slide(Gravity.RIGHT);       slide.excludeTarget(tvFade, true);         Fade fade = new Fade();       fade.excludeTarget(tvSlide, true);         TransitionSet transitionSet = new TransitionSet()               .addTransition(slide)               .addTransition(fade);         TransitionManager.beginDelayedTransition(transitionsContainerTarget, transitionSet);         if (tvFade.getVisibility() == View.VISIBLE) {           tvFade.setVisibility(View.GONE);           tvSlide.setVisibility(View.GONE);       } else {           tvFade.setVisibility(View.VISIBLE);           tvSlide.setVisibility(View.VISIBLE);       }     });</code></pre>    <h3><strong>最终效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c4e18a8ba5b133fc77ec56cc360c633e.gif"></p>    <p style="text-align:center">Target处理</p>    <h3><strong>transition 其他有关 target 方法</strong></h3>    <p>Methods to add target:</p>    <ul>     <li>addTarget(View target) — view itself</li>     <li>addTarget(int targetViewId) — id of view</li>     <li>addTarget(String targetName) — do you remember about method TransitionManager.setTransitionName?</li>     <li>addTarget(Class targetType) — for example android.widget.TextView.class</li>    </ul>    <p>To remove target:</p>    <ul>     <li>removeTarget(View target)</li>     <li>removeTarget(int targetId)</li>     <li>removeTarget(String targetName)</li>     <li>removeTarget(Class target)</li>    </ul>    <p>To exclude some views:</p>    <ul>     <li>excludeTarget(View target, boolean exclude)</li>     <li>excludeTarget(int targetId, boolean exclude)</li>     <li>excludeTarget(Class type, boolean exclude)</li>     <li>excludeTarget(Class type, boolean exclude)</li>    </ul>    <p>And for excluding all children of some ViewGroup:</p>    <ul>     <li>excludeChildren(View target, boolean exclude)</li>     <li>excludeChildren(int targetId, boolean exclude)</li>     <li>excludeChildren(Class type, boolean exclude)</li>    </ul>    <h2><strong>使用 xml 创建 Transition</strong></h2>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <transitionSet xmlns:app="http://schemas.android.com/apk/res-auto"                app:transitionOrdering="together"                app:duration="400">      <changeBounds/>      <changeImageTransform/>      <fade         app:fadingMode="fade_in"         app:startDelay="200">          <targets>              <target app:targetId="@id/transition_title"/>          </targets>      </fade>  </transitionSet></code></pre>    <p>使用</p>    <pre>  <code class="language-java">TransitionInflater.from(getContext()).inflateTransition(R.anim.my_the_best_transition);</code></pre>    <h2><strong>Activity and Fragment transitions</strong></h2>    <h2><strong>Custom Transitions</strong></h2>    <p>参考:</p>    <ul>     <li><a href="/misc/goto?guid=4959722824848642100" rel="nofollow,noindex">Animate all the things. Transitions in Android</a></li>     <li><a href="/misc/goto?guid=4959722824946308584" rel="nofollow,noindex">原作者github</a></li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/89a9cdde42ae</p>    <p> </p>