Android 控制元件框架、View的分發機制和自定義View

SamanLan發表於2017-12-13

看了一天的書,再在網上搜了一些知識點,對View的一些知識點還是有一些不太清晰的地方,做了一些筆記

控制元件框架

控制元件分成兩類
  • ViewGroup控制元件
  • View控制元件 ViewGroup可以作為父控制元件包含多個View,並管理。上層控制元件負責下層子控制元件的測量與繪製,並傳遞互動事件。頂層是一個ViewParent物件,所有互動管理事件都由它來統一排程和分配,從而可以對整個檢視進行整體控制。

佈局

在Activity中使用setContentView()方法來設定一個佈局,只有呼叫該方法佈局內容才會顯示出來。 UI介面架構圖:

DecorView作為視窗介面的頂層檢視,封裝了一些視窗操作的通用方法。裡面所有View的監聽事件,都通過WindowManagerService來接收,並通過Activity物件來回撥相應的Listener。

  • TitleView是標題欄。
  • ContentView是一個Framelayout。
  • **設定requestWindowFeature(Window.FEATURE_NO_TITLE)**來設定隱藏標題欄全屏顯示,一定要在setContentView()方法之前呼叫才能生效。

在onCreat()方法中呼叫setContentView()後,ActivityManagerService會回撥onResume()方法,此時系統才會把整個DecorView新增進PhoneWindow中,並讓其顯示出來,從而最終完成介面的繪製。


View的位置引數

View的位置由top、left、right、bottom決定,分別對應左上角縱座標、左上角橫座標、右下角橫座標、右下角縱座標。座標是相對與父容器來說。 從3.0開始,增加了幾個引數 x、y、translationX、translationY,分別對應View左上角座標和View的左上角相對於父容器的偏移量。 x=left+translationX y=top+translationY View在平移的過程中,top和left表示的是原始左上角的位置資訊,其值不會發生改變,此時改變的是x、y、translationX、translationY。(這就是為什麼View的動畫執行後真身還在原來的地方的原因)


View的事件體系

幾個物件
  • MotionEvent:手指接觸螢幕後所產生的一系列事件
    • ACTION_DOWN:手指剛接觸螢幕
    • ACTION_MOVE:手指在螢幕上移動
    • ACTION_UP:手指從螢幕鬆開的一瞬間
    • 幾個方法:
      • getX/getY:返回相對於當前View左上角的x、y座標
      • getRawX/getRawY:返回相對於手機螢幕左上角的x、y座標
  • TouchSlop:是系統所能識別出的被認為是滑動的最小距離,是一個常量,和裝置有關,不同裝置可能不同
    • 獲取這個常量:ViewConfiguration.get(getContext()).getScaledTouchSlop()
  • VelocityTracker:速度追蹤,用於追蹤手指在滑動過程的速度,包括水平和豎直方向的速度。
//在View的onTouchEvent方法中追蹤當前單擊事件的速度
VelocityTracker velocityTracker=VelocityTracker.obtain();
velocityTracker.addMovement(event);
//想知道當前的滑動速度
velocityTracker.computeCurrentVelocity(1000);//獲取速度必須先計算速度,這裡指的是1000毫秒內的速度
int xVelocityTracker=(int)velocityTracker.getXVelocity();
int yVelocityTracker=(int)velocityTracker.getYVelocity();
//往右滑和往下滑速度是正值,反之則是負值。
複製程式碼
  • GestureDetector:手勢檢測
    • onSingleTapUp:單擊
    • onFling:快速滑動
    • onScroll:滑動
    • onLongPress:長按
    • onDoubleTap:雙擊
//首先建立一個GestureDetector物件並實現OnGestureListener或者OnDoubleTapListener介面
GestureDetector mGestureDetector=new GestureDetector(this);
//解決長按螢幕後無法拖動的現象
//託管View的onTouchEvent方法,在方法裡新增
boolean consume=mGestureDetector.onTouchEvent(event);
return consume;
複製程式碼
  • Scroller:彈性滑動物件.Scroller本身無法讓View彈性滑動,需要VIew和computeScroll配合使用。
//這個是模版
Scroller scroller=new Scroller(context);
private void smoothScrollTo(int destX,int destY){
    int scrollX=getScrollX();
    int deltaX=destX-scrollX;//滑動的距離
    scroller.startScroll(scrollX,0,deltaX,0,1000);
    invalidate();//重繪
}
@Override
public void computeScroll(){//重繪會呼叫這個方法,是空實現,由我們來實現
    if(scroller.computeScrollOffset()){//根據時間的流逝和剩下要滑動的距離計算currX的和currY的值,返回true代表滑動未完成
        scrollerTo(scroller.getCurrX(),scroller.getCurrY());
        postInvalidate();//滑動未完成,繼續重繪
    }
}
複製程式碼

View的滑動
  • 使用scrollTo/scrollBy
  • 使用動畫
  • 改變佈局引數

View的事件分發機制
  • 思維導圖

View的事件分發機制思維導圖

  • 過程邏輯
    View的事件分發機制過程邏輯

自定義View

  • 思維導圖
    自定義View思維導圖

相關文章