<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                **轉載請注明本文出自Cym的博客([http://blog.csdn.net/cym492224103](http://blog.csdn.net/cym492224103)**),謝謝支持!** ** ** 前言 用戶跟你的App進行交互時,Material Design中的動畫給予用戶動作的反饋和提供視覺的一致感。 包括之前我學習過的: [Activity transitions(Activity過渡效果)](http://blog.csdn.net/cym492224103/article/details/41761267) [Animate Vector Drawables(可繪矢量動畫)](http://blog.csdn.net/cym492224103/article/details/41677825) 除我們已經學習過的動畫之外,Material Design還給我們提供了什么動畫? Touch feedback(觸摸反饋) Reveal effect(揭露效果) Curved motion(曲線運動) View state changes?(視圖狀態改變) **Touch feedback**(觸摸反饋) 當用戶與用戶界面進行交互時,materialdesign中的觸摸反饋在觸摸點上提供了一種瞬時視覺確認。按鈕的默認觸摸反饋動畫使用新的[RippleDrawable](http://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html)類,它使用漣漪(波紋)效應在不同狀態間轉換。 在大多數情況下,你應該在你的布局XML文件中使用如下的方法去指定視圖的背景: ?android:attr/selectableItemBackground?(有界波紋) ?android:attr/selectableItemBackgroundBorderless?(無界波紋) 注意:selectableItemBackgroundBorderless是API級別21上的新屬性。 效果如下: ![](https://box.kancloud.cn/2016-02-23_56cc073f8f76b.jpg) layout: ~~~ <Button android:layout_width="100dp" android:layout_height="100dp" android:background="?android:attr/selectableItemBackground" android:text="有界" android:textColor="@android:color/white" android:colorControlHighlight="@android:color/holo_red_dark"/> <Button android:layout_width="100dp" android:layout_height="100dp" android:background="?android:attr/selectableItemBackgroundBorderless" android:textColor="@android:color/white" android:text="無界"/> ~~~ 或者,你可以定義一個[RippleDrawable](http://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html)作為波紋元素的XML資源 ~~~ <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/accent_dark"> <item> <shape android:shape="oval"> <solid android:color="?android:colorAccent" /> </shape> </item> </ripple> ~~~ 你可以給RippleDrawable對象指定一種顏色。要更改默認的觸摸反饋顏色,使用主題的android:colorControlHighlight屬性**。** **Reveal effect**(揭示效果) 使用[ViewAnimationUtils.createCircularReveal()](http://developer.android.com/reference/android/view/ViewAnimationUtils.html#createCircularReveal(android.view.View,)?方法 ![](https://box.kancloud.cn/2016-02-23_56cc073fa49c6.jpg) ~~~ public Animator createAnimation(View v, Boolean isFirst) { Animator animator; if (isFirst) { animator = ViewAnimationUtils.createCircularReveal( v,// 操作的視圖 0,// 動畫開始的中心點X 0,// 動畫開始的中心點Y v.getWidth(),// 動畫開始半徑 0);// 動畫結束半徑 } else { animator = ViewAnimationUtils.createCircularReveal( v,// 操作的視圖 0,// 動畫開始的中心點X 0,// 動畫開始的中心點Y 0,// 動畫開始半徑 v.getWidth());// 動畫結束半徑 } animator.setInterpolator(new DecelerateInterpolator()); animator.setDuration(500); return animator; } static boolean isFirst = false; @Override public void onClick(View v) { createAnimation(myView, isFirst).start(); isFirst = !isFirst; } ~~~ **Curved motion**(曲線運動) Material design中的動畫依靠曲線,這個曲線適用于時間插值器和控件運動模式。 [PathInterpolator](http://developer.android.com/reference/android/view/animation/PathInterpolator.html)類是一個基于貝塞爾曲線(Bézier curve)或路徑([Path](http://developer.android.com/reference/android/graphics/Path.html))對象上的新的插值器。 在materialdesign規范中,系統提供了三個基本的曲線: @interpolator/fast_out_linear_in.xml @interpolator/fast_out_slow_in.xml @interpolator/linear_out_slow_in.xml 你可以傳遞一個[PathInterpolator](http://developer.android.com/reference/android/view/animation/PathInterpolator.html)對象給[Animator.setInterpolator()](http://developer.android.com/reference/android/animation/Animator.html#setInterpolator(android.animation.TimeInterpolator))方法。 [ObjectAnimator](http://developer.android.com/reference/android/animation/ObjectAnimator.html)類有了新的構造方法,使你能夠一次能同時使用兩個或多個屬性去繪制動畫的路徑。例如,下面的動畫使用一個Path對象進行視圖X和Y屬性的動畫繪制: ~~~ ObjectAnimator mAnimator; mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); ... mAnimator.start(); ~~~ 在Android 5.0 提供的API Demos -》Animation/Path Animations 就有一個例子使用了曲線動畫: ![](https://box.kancloud.cn/2016-02-23_56cc073fd80c3.jpg) Path Animations 源碼: ~~~ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.animation; import android.animation.ObjectAnimator; import android.animation.TypeConverter; import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.RectF; import android.os.Bundle; import android.util.AttributeSet; import android.util.FloatMath; import android.util.Log; import android.util.Property; import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.widget.FrameLayout; import android.widget.RadioGroup; import com.example.android.apis.R; /**This application demonstrates the use of Path animation. */ public class PathAnimations extends Activity implements RadioGroup.OnCheckedChangeListener, View.OnLayoutChangeListener { final static Path sTraversalPath = new Path(); final static float TRAVERSE_PATH_SIZE = 7.0f; final static Property<PathAnimations, Point> POINT_PROPERTY = new Property<PathAnimations, Point>(Point.class, "point") { @Override public Point get(PathAnimations object) { View v = object.findViewById(R.id.moved_item); return new Point(Math.round(v.getX()), Math.round(v.getY())); } @Override public void set(PathAnimations object, Point value) { object.setCoordinates(value.x, value.y); } }; static { float inverse_sqrt8 = FloatMath.sqrt(0.125f); RectF bounds = new RectF(1, 1, 3, 3); sTraversalPath.addArc(bounds, 45, 180); sTraversalPath.addArc(bounds, 225, 180); bounds.set(1.5f + inverse_sqrt8, 1.5f + inverse_sqrt8, 2.5f + inverse_sqrt8, 2.5f + inverse_sqrt8); sTraversalPath.addArc(bounds, 45, 180); sTraversalPath.addArc(bounds, 225, 180); bounds.set(4, 1, 6, 3); sTraversalPath.addArc(bounds, 135, -180); sTraversalPath.addArc(bounds, -45, -180); bounds.set(4.5f - inverse_sqrt8, 1.5f + inverse_sqrt8, 5.5f - inverse_sqrt8, 2.5f + inverse_sqrt8); sTraversalPath.addArc(bounds, 135, -180); sTraversalPath.addArc(bounds, -45, -180); sTraversalPath.addCircle(3.5f, 3.5f, 0.5f, Path.Direction.CCW); sTraversalPath.addArc(new RectF(1, 2, 6, 6), 0, 180); } private CanvasView mCanvasView; private ObjectAnimator mAnimator; /**Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.path_animations); mCanvasView = (CanvasView) findViewById(R.id.canvas); mCanvasView.addOnLayoutChangeListener(this); ((RadioGroup) findViewById(R.id.path_animation_type)).setOnCheckedChangeListener(this); } public void setCoordinates(int x, int y) { changeCoordinates((float) x, (float) y); } public void changeCoordinates(float x, float y) { View v = findViewById(R.id.moved_item); v.setX(x); v.setY(y); } public void setPoint(PointF point) { changeCoordinates(point.x, point.y); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { startAnimator(checkedId); } @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { int checkedId = ((RadioGroup)findViewById(R.id.path_animation_type)).getCheckedRadioButtonId(); if (checkedId != RadioGroup.NO_ID) { startAnimator(checkedId); } } private void startAnimator(int checkedId) { if (mAnimator != null) { mAnimator.cancel(); mAnimator = null; } View view = findViewById(R.id.moved_item); Path path = mCanvasView.getPath(); if (path.isEmpty()) { return; } switch (checkedId) { case R.id.named_components: // Use the named "x" and "y" properties for individual (x, y) // coordinates of the Path and set them on the view object. // The setX(float) and setY(float) methods are called on view. // An int version of this method also exists for animating // int Properties. mAnimator = ObjectAnimator.ofFloat(view, "x", "y", path); break; case R.id.property_components: // Use two Properties for individual (x, y) coordinates of the Path // and set them on the view object. // An int version of this method also exists for animating // int Properties. mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); break; case R.id.multi_int: // Use a multi-int setter to animate along a Path. The method // setCoordinates(int x, int y) is called on this during the animation. // Either "setCoordinates" or "coordinates" are acceptable parameters // because the "set" can be implied. mAnimator = ObjectAnimator.ofMultiInt(this, "setCoordinates", path); break; case R.id.multi_float: // Use a multi-float setter to animate along a Path. The method // changeCoordinates(float x, float y) is called on this during the animation. mAnimator = ObjectAnimator.ofMultiFloat(this, "changeCoordinates", path); break; case R.id.named_setter: // Use the named "point" property to animate along the Path. // There must be a method setPoint(PointF) on the animated object. // Because setPoint takes a PointF parameter, no TypeConverter is necessary. // In this case, the animated object is PathAnimations. mAnimator = ObjectAnimator.ofObject(this, "point", null, path); break; case R.id.property_setter: // Use the POINT_PROPERTY property to animate along the Path. // POINT_PROPERTY takes a Point, not a PointF, so the TypeConverter // PointFToPointConverter is necessary. mAnimator = ObjectAnimator.ofObject(this, POINT_PROPERTY, new PointFToPointConverter(), path); break; } mAnimator.setDuration(10000); mAnimator.setRepeatMode(Animation.RESTART); mAnimator.setRepeatCount(ValueAnimator.INFINITE); mAnimator.setInterpolator(new LinearInterpolator()); mAnimator.start(); } public static class CanvasView extends FrameLayout { Path mPath = new Path(); Paint mPathPaint = new Paint(); public CanvasView(Context context) { super(context); init(); } public CanvasView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CanvasView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setWillNotDraw(false); mPathPaint.setColor(0xFFFF0000); mPathPaint.setStrokeWidth(2.0f); mPathPaint.setStyle(Paint.Style.STROKE); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { Matrix scale = new Matrix(); float scaleWidth = (right-left)/TRAVERSE_PATH_SIZE; float scaleHeight= (bottom-top)/TRAVERSE_PATH_SIZE; scale.setScale(scaleWidth, scaleHeight); sTraversalPath.transform(scale, mPath); } } public Path getPath() { return mPath; } @Override public void draw(Canvas canvas) { canvas.drawPath(mPath, mPathPaint); super.draw(canvas); } } private static class PointFToPointConverter extends TypeConverter<PointF, Point> { Point mPoint = new Point(); public PointFToPointConverter() { super(PointF.class, Point.class); } @Override public Point convert(PointF value) { mPoint.set(Math.round(value.x), Math.round(value.y)); return mPoint; } } } ~~~ layout: ~~~ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <RadioGroup android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/path_animation_type" > <RadioButton android:id="@+id/named_components" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Named Components"/> <RadioButton android:id="@+id/property_components" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Property Components"/> <RadioButton android:id="@+id/multi_int" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Multi-int"/> <RadioButton android:id="@+id/multi_float" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Multi-float"/> <RadioButton android:id="@+id/named_setter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Named Property"/> <RadioButton android:id="@+id/property_setter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Property"/> </RadioGroup> </ScrollView> <view class="com.example.android.apis.animation.PathAnimations$CanvasView" android:id="@+id/canvas" android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="1"> <ImageView android:id="@+id/moved_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/frog"/> </view> </LinearLayout> ~~~ **View state changes(視圖狀態改變)** [StateListAnimator](http://developer.android.com/reference/android/animation/StateListAnimator.html)類可以讓你定義動畫集,能在view狀態改變時工作。下面的實例顯示了如何定義一個XML資源的[StateListAnimator](http://developer.android.com/reference/android/animation/StateListAnimator.html)。 使用步驟 1.定義一個XML資源的[StateListAnimator](http://developer.android.com/reference/android/animation/StateListAnimator.html) ~~~ <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <set> <objectAnimator android:propertyName="translationZ" android:duration="@android:integer/config_shortAnimTime" android:valueTo="10" android:valueType="floatType"/> <objectAnimator android:propertyName="rotationX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="360" android:valueType="floatType"/> </set> </item> <item android:state_pressed="false" > <set> <objectAnimator android:propertyName="translationZ" android:duration="10000" android:valueTo="0" android:valueType="floatType"/> <objectAnimator android:propertyName="rotationX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="0" android:valueType="floatType"/> </set> </item> </selector> ~~~ 定義了翻轉的效果的xml, 配置兩種方式: 1.layout:android:stateListAnimator屬性將其分配給你的視圖, 2.代碼:使用[AnimationInflater.loadStateListAnimator()](http://developer.android.com/reference/android/animation/AnimatorInflater.html#loadStateListAnimator(android.content.Context,)方法,并且通過[View.setStateListAnimator()](http://developer.android.com/reference/android/view/View.html#setStateListAnimator(android.animation.StateListAnimator))方法分配動畫到你的視圖上。 效果如下: ![](https://box.kancloud.cn/2016-02-23_56cc074026da3.jpg) 當然動畫任你自己定義,如果只定義Z軸的話也可以輕松的實現此效果: ![](https://box.kancloud.cn/2016-02-23_56cc07406cba7.jpg) [AnimatedStateListDrawable](http://developer.android.com/reference/android/graphics/drawable/AnimatedStateListDrawable.html)類讓你去創建drawable資源,該資源在相關聯的視圖的狀態更改時展示動畫。一些Android5.0中的系統控件使用這些默認的動畫。下面的例子顯示了如何定義一個[AnimatedStateListDrawable](http://developer.android.com/reference/android/graphics/drawable/AnimatedStateListDrawable.html)作為XML資源: ~~~ <!-- res/drawable/myanimstatedrawable.xml --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- provide a different drawable for each state--> <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state_pressed="true"/> <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state_focused="true"/> <item android:id="@id/default" android:drawable="@drawable/drawableD"/> <!-- specify a transition --> <transition android:fromId="@+id/default" android:toId="@+id/pressed"> <animation-list> <item android:duration="15" android:drawable="@drawable/dt1"/> <item android:duration="15" android:drawable="@drawable/dt2"/> ... </animation-list> </transition> ... </animated-selector> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看