《Android群英傳》小結(jié)

1摔敛、Android體系與系統(tǒng)架構(gòu)

1、Android大致分為四層,即Linux內(nèi)核層、庫和運(yùn)行時(shí)翘瓮、Framework層和應(yīng)用層

  • Linux層包含了Android系統(tǒng)的核心服務(wù),包括硬件驅(qū)動(dòng)裤翩、進(jìn)程管理资盅、安全系統(tǒng)等。
  • Dalvik的特點(diǎn)是運(yùn)行時(shí)編譯踊赠,而在Android5.X版本開始呵扛,ART模式已經(jīng)取代了Dalvik,ART采用的是安裝時(shí)就進(jìn)行編譯臼疫。

2择份、Context

  • 創(chuàng)建Context的時(shí)機(jī)就是在創(chuàng)建Context的實(shí)體類的時(shí)候。

2烫堤、Android控件架構(gòu)與自定義控件詳解

1、Android控件架構(gòu)

  • findViewById就是在控件樹中以樹的深度優(yōu)先遍歷來查找對(duì)應(yīng)元素凤价。
  • 每個(gè)Activity都包含一個(gè)Window對(duì)象鸽斟,在Android中Window對(duì)象通常由PhoneWindow來實(shí)現(xiàn),PhoneWindow將一個(gè)DecorView設(shè)置為整個(gè)應(yīng)用窗口的根View利诺。這里面所有的View的監(jiān)聽事件富蓄,都通過WindowManagerService來進(jìn)行接收,并通過Activity對(duì)象來回調(diào)相應(yīng)的onClickListener慢逾。在顯示上立倍,它將屏幕分為兩部分灭红,一個(gè)是TitleView,另一個(gè)是ContentView口注。ContentView是一個(gè)id為content的FrameLayout变擒。
  • requestWindowFeature(Window.FEATURE_NO_TITLE)來設(shè)置全屏,視圖樹中的布局只有Content了寝志,所以調(diào)用requestWindowFeature()方法一定要在調(diào)用setContentView()方法之前才能生效娇斑。
  • 當(dāng)程序在onCreate()方法中調(diào)用setContentView()方法后,ActivityManagerService會(huì)回調(diào)onResume()方法材部,此時(shí)系統(tǒng)才會(huì)把整個(gè)DecorView添加到PhoneWindow中毫缆,并讓其顯示出來,從而最終完成界面的繪制乐导。

2苦丁、View的測(cè)量

  • MeasureSpec是一個(gè)32位的int值,其中高2位為測(cè)量的模式物臂,低30位為測(cè)量的大小旺拉,在計(jì)算中使用位運(yùn)算的原因是為了提高并優(yōu)化效率。
  • View類默認(rèn)的onMeasure()方法只支持EXACTLY模式鹦聪,所以如果在自定義控件的時(shí)候不重寫onMeasure()方法的話账阻,就只能使用EXACTLY模式。

3泽本、ViewGroup的測(cè)量

  • ViewGroup的大小為wrap_content時(shí)淘太,ViewGroup就需要對(duì)子View進(jìn)行遍歷,以便獲得所有子View的大小规丽,從而來決定自己的大小蒲牧。而在其他模式下則會(huì)通過具體的指定值來設(shè)置自身的大小。

4赌莺、ViewGroup的繪制

  • 不指定ViewGroup的背景顏色冰抢,那么ViewGroup的onDraw()方法都不會(huì)被調(diào)用,但是艘狭,ViewGroup會(huì)使用dispatchDraw()方法來繪制其子View挎扰。

5、自定義View

  • onFinishInflate():從XML加載組件后回調(diào)巢音。

  • onSizeChanged():組件大小改變時(shí)回調(diào)遵倦。

  • 有些控件像TextView有給getPaint()方法,可以拿到畫筆官撼,從而我們可以修改繪制效果梧躺。

  • postInvalidateDelayed():隔幾毫秒刷新一次

  • 閃動(dòng)的TextView:

    public class FlashTextView extends android.support.v7.widget.AppCompatTextView {
      
          private int mViewWidth;
          private TextPaint mPaint;
          private LinearGradient mLinearGradient;
          private Matrix mGradientMatrix;
          private int mTranslate;
      
          public FlashTextView(Context context) {
              super(context);
          }
      
          public FlashTextView(Context context, @Nullable AttributeSet attrs) {
              super(context, attrs);
          }
      
          public FlashTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
      
          @Override
          protected void onSizeChanged(int w, int h, int oldw, int oldh) {
              super.onSizeChanged(w, h, oldw, oldh);
      
              if (mViewWidth == 0){
                  mViewWidth = getMeasuredWidth();
                  if (mViewWidth > 0){
                      mPaint = getPaint();
                      mLinearGradient = new LinearGradient(0,0,mViewWidth,0,new int[]{Color.BLUE,0xffffffff,Color.BLUE},null, Shader.TileMode.CLAMP);
                      mPaint.setShader(mLinearGradient);
                      mGradientMatrix = new Matrix();
                  }
              }
          }
      
          @Override
          protected void onDraw(Canvas canvas) {
              super.onDraw(canvas);
      
              if (mGradientMatrix != null){
                  mTranslate += mViewWidth / 5;
                  if (mTranslate > 2*mViewWidth){
                      mTranslate = -mViewWidth ;
                  }
                  mGradientMatrix.setTranslate(mTranslate,0);
                  mLinearGradient.setLocalMatrix(mGradientMatrix);
                  postInvalidateDelayed(100);  //每隔100ms刷新一次
              }
          }
      }
    

3、Android Scroll分析

1傲绣、Android坐標(biāo)系

  • getRawX()和getRawY()獲取的是Android坐標(biāo)系中的坐標(biāo)掠哥,也就是離屏幕的距離巩踏。
  • getX()和getY()獲得的坐標(biāo)是視圖坐標(biāo)系中的坐標(biāo),也就是離父控件的距離续搀。
  • getRight()獲取View自身的右邊到其父控件左邊的距離塞琼,getBotttom()獲取View自身的底邊到父控件頂部的距離。

2目代、ScrollTo與ScrollBy

  • ScrollTo與ScrollBy移動(dòng)的是View的內(nèi)容屈梁,在ViewGroup使用則移動(dòng)所有子View,在View中使用則移動(dòng)內(nèi)容榛了,所以想要移動(dòng)View可以這樣:getParent.scrollBy(-offsetX在讶,-offsetY);
  • ScrollTo與ScrollBy移動(dòng)的效果其實(shí)是手機(jī)屏幕的移動(dòng),內(nèi)容看成是靜止的霜大,所以scrollBy中參數(shù)為正构哺,那么內(nèi)容往負(fù)方向移動(dòng),反之战坤,往正方向曙强。

3、Scroller

  • 不管是ScrollBy還是ScrollTo途茫,子View的平移都是瞬間發(fā)生的碟嘴,通過Scroller類可以實(shí)現(xiàn)平滑移動(dòng)效果,它將每一段距離劃分成N個(gè)非常小的偏移量囊卜,每個(gè)小偏移量通過ScrollBy瞬間移動(dòng)娜扇,但整體上就有一個(gè)平滑效果。

  • computeScroll():使用Scroller類的核心方法栅组,系統(tǒng)在繪制View的時(shí)候會(huì)在draw()方法中調(diào)用該方法雀瓢。這個(gè)方法實(shí)際上就是使用的scrollTo方法,再結(jié)合Scroller對(duì)象玉掸,幫助獲取當(dāng)前的滾動(dòng)值刃麸。

    case MotionEvent.ACTION_UP:
              //手指離開執(zhí)行滑動(dòng)過程
              View viewGroup = (View) getParent();
              mScroller.startScroll(viewGroup.getScrollX(),
                      viewGroup.getScrollY(),
                      -viewGroup.getScrollX(),
                      -viewGroup.getScrollY());
              invalidate();
              break;
    @Override
    public void computeScroll() {
      super.computeScroll();
      if (mScroller.computeScrollOffset()){   //判斷是否完成了整個(gè)滑動(dòng)
          ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());  //getCurr獲取當(dāng)前滑動(dòng)坐標(biāo)
          invalidate();  //重新繪制來不斷調(diào)用computeScroll()
      }
    }
    
  • ViewDragHelper(側(cè)拉為例)

    public class DragViewGroup extends FrameLayout {
      
          private ViewDragHelper mViewDragHelper;
          private View mMenuView;
          private View mMainView;
      
          public DragViewGroup(@NonNull Context context) {
              super(context);
          }
      
          public DragViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
              super(context, attrs);
          }
      
          public DragViewGroup(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
      
          private void init(){
              mViewDragHelper = ViewDragHelper.create(this, mCallback);  //初始化ViewDragHelper
          }
      
          @Override
          protected void onFinishInflate() {
              super.onFinishInflate();
              mMenuView = getChildAt(0);
              mMainView = getChildAt(1);
          }
      
          @Override
          public boolean onInterceptTouchEvent(MotionEvent ev) {
              return mViewDragHelper.shouldInterceptTouchEvent(ev);  //將事件傳遞給ViewDragHelper
          }
      
          @Override
          public boolean onTouchEvent(MotionEvent event) {
              mViewDragHelper.processTouchEvent(event);  //將事件傳遞給ViewDragHelper
              return true;
          }
      
          @Override
          public void computeScroll() {
              super.computeScroll();
              if (mViewDragHelper.continueSettling(true)){
                  ViewCompat.postInvalidateOnAnimation(this);
              }
          }
      
          private ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
              //何時(shí)開始檢測(cè)觸摸事件
              @Override
              public boolean tryCaptureView(View child, int pointerId) {
                  return mMainView == child;
              }
              //處理垂直滑動(dòng)
              @Override
              public int clampViewPositionVertical(View child, int top, int dy) {
                  return super.clampViewPositionVertical(child, top, dy);
              }
              //處理水平滑動(dòng)
              @Override
              public int clampViewPositionHorizontal(View child, int left, int dx) {
                  return left;
              }
              //拖動(dòng)結(jié)束后調(diào)用
              @Override
              public void onViewReleased(View releasedChild, float xvel, float yvel) {
                  super.onViewReleased(releasedChild, xvel, yvel);
                  if (mMainView.getLeft() < 500){
                      mViewDragHelper.smoothSlideViewTo(mMainView,0,0);
                      ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                  }else{
                      mViewDragHelper.smoothSlideViewTo(mMainView,300,0);
                      ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                  }
              }
              //觸摸到View后回調(diào)
              @Override
              public void onViewCaptured(View capturedChild, int activePointerId) {
                  super.onViewCaptured(capturedChild, activePointerId);
              }
              //拖動(dòng)狀態(tài)改變時(shí)回調(diào)
              @Override
              public void onViewDragStateChanged(int state) {
                  super.onViewDragStateChanged(state);
              }
              //位置改變時(shí)回調(diào)
              @Override
              public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
                  super.onViewPositionChanged(changedView, left, top, dx, dy);
              }
          };
      }
    

4、Android繪圖機(jī)制與處理技巧

1司浪、2D繪制基礎(chǔ)

  • DrawArc:繪制弧形泊业、扇形,參數(shù)useCenter表示要不要連接圓心閉合啊易。
  • DrawPosText:在指定位置繪制文本脱吱。
  • Canvas.save()保存畫布,讓后續(xù)操作在新的圖層上操作一樣认罩,而Canvas.restore()圖層合并。
  • Canvas.rotate()可用于像時(shí)鐘的刻度線续捂,這些不方便計(jì)算坐標(biāo)垦垂,用旋轉(zhuǎn)更易解決宦搬。

5、Android動(dòng)畫機(jī)制與使用技巧

1劫拗、Android View動(dòng)畫框架

  • 視圖動(dòng)畫:提供了AlphaAnimation间校、RotateAnimation、TranslateAnimation页慷、ScaleAnimation憔足、AnimationSet
    優(yōu)點(diǎn):效率比較高且使用方便。
    缺點(diǎn):不具備交互性酒繁,當(dāng)某個(gè)View做視圖動(dòng)畫后滓彰,其響應(yīng)事件依然在原來的位置。

  • 屬性動(dòng)畫:3.0后出現(xiàn)州袒,解決了視圖動(dòng)畫的缺點(diǎn)
    ObjectAnimator:要操作的屬性必須具有g(shù)et揭绑、set方法,不然無效
    PropertyValuesHolder:相當(dāng)于AnimationSet

    PropertyValuesHolder pv1 = PropertyValuesHolder.ofFloat("translationX", 300f);
    PropertyValuesHolder pv2 = PropertyValuesHolder.ofFloat("ScaleX", 1f,0.1f);
    PropertyValuesHolder pv3 = PropertyValuesHolder.ofFloat("ScaleY", 1f,0.1f);
    ObjectAnimator.ofPropertyValuesHolder(view,pv1,pv2,pv3).start();    
    
  • View直接使用Animator

    view.animate().translationX(100).setDuration(500).withStartAction(new Runnable() {
          @Override
          public void run() {
    
          }
      });
    

2郎哭、Android布局動(dòng)畫

  • 布局動(dòng)畫是指作用在ViewGroup上他匪,給ViewGroup增加添加View時(shí)添加一個(gè)動(dòng)畫過渡效果。

  • 通過XML屬性android:animateLayoutChanges="true"來開啟默認(rèn)效果夸研,且無法修改替換這個(gè)效邦蜜。

  • 還可以通過LayoutAnimationController來定義一個(gè)子View的過渡效果:

    LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
    ScaleAnimation sa = new ScaleAnimation(0,1,0,1);
    sa.setDuration(2000);
    //參數(shù)2不為0時(shí),可以設(shè)置View的顯示順序
    LayoutAnimationController controller = new LayoutAnimationController(sa,0.5f);
    //ORDER_RANDOM:隨機(jī)  ORDER_REVERSE:反序 ORDER_NORMAL:順序
    controller.setOrder(LayoutAnimationController.ORDER_NORMAL); 
    ll.setLayoutAnimation(controller);
    

3亥至、自定義動(dòng)畫

  • 繼承Animation悼沈,重寫:

    /**
    *  interpolatedTime插值器時(shí)間因子
    */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        Matrix matrix = t.getMatrix();
        matrix.XXXX   //通過matrix各種操作實(shí)現(xiàn)動(dòng)畫
    }
    //初始化操作
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }
    

4、Android 5.X SVG矢量動(dòng)畫機(jī)制

  • SVG放大不會(huì)失真

  • <path>標(biāo)簽:
    M = moveto(M X,Y):將畫筆移動(dòng)到指定的坐標(biāo)位置抬闯,但未發(fā)生繪制井辆。
    L = lineto(L X,Y):畫直線到指定的坐標(biāo)位置。
    H = horizontal lineto(H X):畫水平線到指定的X坐標(biāo)位置溶握。
    V = vertical lineto(V Y):畫垂直線到指定的Y坐標(biāo)位置杯缺。
    C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次貝賽曲線。
    S = smooth curveto(S X2,Y2,ENDX,ENDY):三次貝賽曲線睡榆。
    Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次貝賽曲線萍肆。
    T = smooth quadratic Belzier curve(T ENDX,ENDY):映射前面路徑后的終點(diǎn)。
    A = eliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧線胀屿。
    Z = closepath():關(guān)閉路徑塘揣。
    注意:
    指令大寫表示絕對(duì)坐標(biāo),參照全局坐標(biāo)系宿崭,小寫表示相對(duì)坐標(biāo)亲铡,參照父容器坐標(biāo)系。
    指令和數(shù)據(jù)間的空格可以省略。
    同一個(gè)指令出現(xiàn)多次可以只用一個(gè)奖蔓。

  • SVG常用指令:
    A:
    RX,RY指所在橢圓的半軸大小赞草。
    XROTATION指橢圓的X軸與水平方向順時(shí)針方向的夾角。
    FLAG1只有兩個(gè)值吆鹤,1表示大角度弧線厨疙,0為小角度弧線。
    FLAG2只有兩個(gè)值疑务,確定從起點(diǎn)至終點(diǎn)的方向沾凄,1為順時(shí)針,0為逆時(shí)針知允。
    X,Y為終點(diǎn)坐標(biāo)撒蟀。

  • Android使用SVG
    VectorDrawable:

      <?xml version="1.0" encoding="utf-8"?>
      <!--viewportHeight表示200dp劃分100份-->
      <!--height和width的比例與viewportHeight和viewportWidth的比例必須一致
       不然會(huì)發(fā)生圖形壓縮、形變-->
      <vector xmlns:android="http://schemas.android.com/apk/res/android"
          android:height="200dp"
          android:width="200dp"
          android:viewportHeight="100"
          android:viewportWidth="100">
      
          <group android:name="test"
                 android:rotation="0">
              <path android:fillColor="@android:color/holo_blue_light"
                  android:pathData="M 25 50 a 25,25 0 1,0 50,0"
                />
          </group>
      </vector>
    

    AnimatedVectorDrawable:
    AnimatedVectorDrawable的作用就是給VectorDrawable提供動(dòng)畫效果廊镜。

    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
      android:drawable="@drawable/vector">
      <!--name必須與VectorDrawable中name保持一致-->
      <target
          android:name="test"
          android:animation="@animator/anim"/>
    
    </animated-vector>
    

    動(dòng)畫:

    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
      android:duration="4000"
      android:propertyName="rotation"
      android:valueFrom="0"
      android:valueTo="360"/>
    <!--propertyName選擇控制什么屬性-->
    

    使用:

    <ImageView
      android:id="@+id/iv_image"
      android:layout_width="wrap_content"
      android:src="@drawable/animation_vector"
      android:layout_height="wrap_content"/>
    ((Animatable)imageView.getDrawable()).start();
    

6牙肝、Activity

1、清空任務(wù)棧

  • android:clearTaskOnLaunch="true":每次返該Activity嗤朴,都將Activity之上的所有Activity清除配椭。
  • android:finishOnTaskLaunch="true":當(dāng)離開這個(gè)Activity所處的Task,那么用戶再返回時(shí)雹姊,該Activity就會(huì)被finish股缸。
  • android:alwaysRetainTaskState="true":該Activity所在的Task不接受任何清理命令,一直保持當(dāng)前Task狀態(tài)吱雏。

7敦姻、Android性能優(yōu)化

1、布局優(yōu)化

  • <ViewStub>與View.GONE:<ViewStub>標(biāo)簽只會(huì)在顯示時(shí)歧杏,才去渲染整個(gè)布局镰惦,而View.GONE,在初始化布局樹的已經(jīng)添加在布局樹上了犬绒。
    2旺入、代碼優(yōu)化
  • 任何Java類,都占用大約500字節(jié)的內(nèi)存空間凯力,創(chuàng)建一個(gè)類的實(shí)例大約消耗15字節(jié)的內(nèi)存茵瘾。
  • 靜態(tài)方法比普通方法提高15%左右的訪問速度。

8咐鹤、Android 5.X新特性

1拗秘、陰影效果

  • Z軸由elevation和translationZ。
  • 通過 android:elevation="xxdp"在XML布局中使用設(shè)置View的視圖高度祈惶,也可以通過代碼view.setTranslationZ(XXX)雕旨。

2扮匠、Tinting(著色)

  • android:tint="@color/XXX"
    android:tintMode="multiply" 模式

3、Clipping(裁剪)

  • 首先需要使用ViewOutlineProvider來修改outline奸腺,然后再通過setOutlineProvider將outline作用給視圖餐禁。

      ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
          @Override
          public void getOutline(View view, Outline outline) {
              outline.setOval(0,0,view.getWidth(),view.getHeight());  //修改為特定形狀
          }
      };
      view.setClipToOutline(true);
      view.setOutlineProvider(viewOutlineProvider);
    

4、CardView

  • 懸浮效果

     <android.support.v7.widget.CardView
      android:layout_gravity="center"
      app:cardBackgroundColor="@color/colorAccent"
      app:cardElevation="10dp"
      app:cardCornerRadius="10dp"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
    
      <TextView
          android:id="@+id/btn"
          android:gravity="center"
          android:text="11111"
          android:layout_width="200dp"
          android:layout_height="200dp"/>
    </android.support.v7.widget.CardView>
    

5突照、Activity過渡動(dòng)畫

  • Android 5.X提供了三種Transition類型:
    進(jìn)入:進(jìn)入的過渡動(dòng)畫,決定Activity中所有的視圖怎么進(jìn)入屏幕氧吐。
    退出:退出的過渡動(dòng)畫讹蘑,決定Activity中所有的視圖怎么退出屏幕。
    共享元素:決定兩個(gè)Activity之間的過渡筑舅,怎么共享它們的視圖座慰。
    其中,進(jìn)入和退出效果包括:
    explode(分解):從屏幕中間進(jìn)或出翠拣,移動(dòng)視圖版仔。
    slide(滑動(dòng)):從屏幕邊緣進(jìn)或出,移動(dòng)視圖误墓。
    fade(淡出):通過改變屏幕上視圖的不透明度達(dá)到添加或移除視圖蛮粮。
    其中,共享元素包括:
    changeBounds:改變目標(biāo)視圖的布局邊界谜慌。
    changeClipBounds:裁剪目標(biāo)視圖邊界然想。
    changeTransform:改變目標(biāo)視圖的縮放比例和旋轉(zhuǎn)角度。
    changeImageTranform:改變目標(biāo)圖片的大小和縮放比例欣范。
    進(jìn)入與退出過渡動(dòng)畫:

    MainActivity:
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    //explode動(dòng)畫為例
    public void explode(View view){
        Intent intent = new Intent(this,TestActivity.class);
        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }
    TestAvtivity:
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    getWindow().setEnterTransition(new Explode());
    setContentView(XXX);
    

    共享元素過渡動(dòng)畫:

    <Button
      android:layout_width="wrap_content"
      android:transitionName="fab"
      android:layout_height="wrap_content"
      android:background="@mipmap/ic_launcher"
      android:onClick="share"/>
    
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void share(View view){
      Intent intent = new Intent(this,TestActivity.class);
      startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,view,"fab").toBundle());
    }
    TestActivity:
    <ImageView
      android:layout_gravity="center"
      android:transitionName="fab"
      android:layout_width="wrap_content"
      android:background="@mipmap/ic_launcher"
      android:layout_height="wrap_content"/>
    

6变泄、Ripple水波紋效果

  • android:background="?android:attr/selectableItemBackgroundBorderless" 無邊界
  • android:background="?android:attr/selectableItemBackground" 有邊界

7、Circular Reveal
具體表現(xiàn)為一個(gè)View以圓形的形式展示恼琼、揭示出來妨蛹。

final View view = findViewById(R.id.iv);
    view.setOnClickListener(new View.OnClickListener() {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onClick(View v) {
            Animator animator 
                    = ViewAnimationUtils.createCircularReveal(view, view.getWidth() / 2, 
                    view.getHeight() / 2, 0, view.getWidth());
            animator.setDuration(2000);
            animator.start();
        }
    });

8、View state changes Animation

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
    <set>
        <objectAnimator
            android:propertyName="rotationX"
            android:duration="@android:integer/config_longAnimTime"
            android:valueTo="360"
            android:valueType="floatType"
            />
    </set>
</item>

<item android:state_pressed="false">
    <set>
        <objectAnimator
            android:propertyName="rotationX"
            android:duration="@android:integer/config_longAnimTime"
            android:valueTo="0"
            android:valueType="floatType"
            />
    </set>
</item>
</selector>
布局使用:
<Button
    android:layout_gravity="center"
    android:stateListAnimator="@animator/state_list_anim"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晴竞,一起剝皮案震驚了整個(gè)濱河市蛙卤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颓鲜,老刑警劉巖表窘,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異甜滨,居然都是意外死亡乐严,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門衣摩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昂验,“玉大人捂敌,你說我怎么就攤上這事〖惹伲” “怎么了占婉?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長甫恩。 經(jīng)常有香客問我逆济,道長,這世上最難降的妖魔是什么磺箕? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任奖慌,我火速辦了婚禮,結(jié)果婚禮上松靡,老公的妹妹穿的比我還像新娘简僧。我一直安慰自己,他們只是感情好雕欺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布岛马。 她就那樣靜靜地躺著,像睡著了一般屠列。 火紅的嫁衣襯著肌膚如雪啦逆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天脸哀,我揣著相機(jī)與錄音蹦浦,去河邊找鬼。 笑死撞蜂,一個(gè)胖子當(dāng)著我的面吹牛盲镶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝌诡,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼溉贿,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了浦旱?” 一聲冷哼從身側(cè)響起宇色,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颁湖,沒想到半個(gè)月后宣蠕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甥捺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年抢蚀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镰禾。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡皿曲,死狀恐怖唱逢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屋休,我是刑警寧澤坞古,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站劫樟,受9級(jí)特大地震影響痪枫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毅哗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一听怕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虑绵,春花似錦、人聲如沸闽烙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽黑竞。三九已至捕发,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間很魂,已是汗流浹背扎酷。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遏匆,地道東北人法挨。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像幅聘,于是被迫代替她去往敵國和親凡纳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容