Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 自定義控件學習之三 控件布局常用知識總結

android 自定義控件學習之三 控件布局常用知識總結

編輯:關於Android編程

1、View是什麼 View是Android所有控件的基類,簡單到TextView、Button,復雜到RelativeLayout,LinearLayout,其共同基類都是View。 所以,View可以理解為控件的抽象,也是一個控件。 除此之外,還有ViewGroup,字面意義上,它表示控件組,內部可以包含許多個控件。 ViewGroup也繼承自View,這意味著,一個View的可以是單個控件,也可以是多個控件組成的一組控件,這就形成了View樹。 下面這個圖很好地體現了View的繼承關系 \

 

2、View的相關參數   View的位置決定於它的四個頂點,對應View的四個屬性: Top:左上角縱坐標,通過getTop ()獲得 Left:左上角橫坐標,通過getLeft()獲得 Right: 右下角橫坐標,通過getRight ()獲得 Bottom: 右下角縱坐標,通過getBottom ()獲得   這些坐標都是相對於View的父容器所說的,是一種相對坐標。 下面這張圖表示的是View中涉及位置參數的各個方法對應的具體含義。 最外層是手機屏幕,中間是一個ViewGroup嵌套一個View。 涉及到的其他方法請繼續往下看。 \

 

 

此外,參數x,y表示View左上角的橫縱坐標, translationX和translationY表示View的左上角相對於父容器的偏移量。 他們都有相應的Get/Set方法 這幾個參數也是相對於父容器的坐標 可以知道,這幾個參數換算關系如下 x = left +translationX y = top +translationY   利用這些參數,我們來自定義一個能隨手指滑動而改變位置的View 實現如下效果: 初始位置: \

 

手指滑動後,自定義View走到了圖示位置:

\

 

代碼如下: 自定義View [java]view plaincopy
  1. publicclassDragViewextendsView{
  2.  
  3. intlastX;
  4. intlastY;
  5.  
  6. publicDragView(Contextcontext){
  7. super(context);
  8. }
  9.  
  10. publicDragView(Contextcontext,AttributeSetattrs){
  11. super(context,attrs);
  12. }
  13.  
  14. @Override
  15. protectedvoidonDraw(Canvascanvas){
  16. super.onDraw(canvas);
  17. }
  18.  
  19. @Override
  20. publicbooleanonTouchEvent(MotionEventevent){
  21.  
  22. intx=(int)event.getX();
  23. inty=(int)event.getY();
  24. Log.e("觸發onTouchEvent",x+"::::::"+y);
  25.  
  26. switch(event.getAction()){
  27. caseMotionEvent.ACTION_DOWN:{
  28. lastX=x;
  29. lastY=y;
  30. }
  31. break;
  32. caseMotionEvent.ACTION_MOVE:{
  33. intoffsetX=x-lastX;
  34. intoffsetY=y-lastY;
  35. Log.e("觸發ACTION_MOVE",offsetX+"::::::"+offsetY);
  36. layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
  37. Log.d("DragView",getLeft()+"______"+getTop()+"-------"+getBottom()+"-------"+getRight());
  38. }
  39. break;
  40. }
  41.  
  42. returntrue;
  43. }
  44. }

布局:
[html]view plaincopy
  1. xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. tools:context="com.lian.scrolltest.MainActivity">
  10.  
  11. android:layout_width="100dp"
  12. android:layout_height="100dp"
  13. android:background="#000000"
  14.  
  15. />
  16.  

 

MainActivity直接顯示布局即可   很好地實現了如上效果     3、MotionEvent和TouchSlop   (1)MotionEvent 我們在自定義View的時候,常常需要在onTouchEvent()中定義觸摸行為 典型的觸摸事件類型包括: ACTION_DOWN:手指剛剛接觸屏幕 ACTION_MOVE:手指在屏幕上移動 ACTION_UP:手指從屏幕離開   通過MotionEvent對象,我們可以得到點擊事件的一系列位置參數 getX(),getY():觸摸事件發生的位置相對於View的坐標 getRawX(),getRawY()返回返回相對於屏幕左上角的x 和 y 坐標   (2)TouchSlop 表示系統能辨識出的認為是滑動的最小距離。 若兩次滑動小於此常量,判定為不屬於滑動操作 這個常量的大小和手機有關。   通過如下方式獲得: [java]view plaincopy
  1. ViewConfiguration.get(getContext()).getScaledTouchSlop();
  我們處理滑動事件時,可以用這個參數進行過濾。   4、VelocityTracker、GestureDetector、Scroller (1)VelocityTracker 用於追蹤滑動過程中的速度,包括水平和豎直方向的速度。   使用方法: 在View的onTouchEvent()中將Event托管給VelocityTracker, 采用相應API獲取參數 [java]view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. //獲取對象
  2. VelocityTrackervelocityTracker=VelocityTracker.obtain();
  3. //托管event
  4. velocityTracker.addMovement(event);
  5. //設置時間間隔,結果會表示為每1000毫秒經過多少像素,若設置為100,結果表示為沒100毫秒經過多少像素
  6. velocityTracker.computeCurrentVelocity(1000);
  7. //獲取X和Y方向上的速度
  8. intxVelicity=(int)velocityTracker.getXVelocity();
  9. intyVelicity=(int)velocityTracker.getYVelocity();
比如1秒內X方向滑動了100像素,那麼參數設置為1000時,結果就為100,表示1000毫秒劃過100像素 參數設置為100時,結果就為10(表示每100毫秒劃過10像素)   不需要使用時,對其進行回收 [java]view plaincopy
  1. velocityTracker.clear();
  2. velocityTracker.recycle();

(2)GestureDetector GestureDetector中將封裝了一系列觸摸行為,包括單擊、滑動、長按,雙擊等。 使用:   在自定義View中實現onGestureDetector接口,在其中重寫onSingleTapTop()-單擊事件、onFiling()-快速滑動、omLongPress()-長按、onDoubleTap()-雙擊 等方法,定義自己的事件處理邏輯 還有,在onTouchEvent()中:
[java]view plaincopy
  1. //獲取對象
  2. GestureDetectorgestureDetector=newGestureDetector(this);
  3. //解決長按屏幕後無法拖動的問題
  4. gestureDetector.setIsLongpressEnabled(false);
  5. //托管event
  6. booleanconsume=gestureDetector.onTouchEvent(event);
  7. returnconsume;
    (3)Scroller 用於實現View的彈性滑動。 為了讓View實現滑動,我們常常使用scrollTo和ScrollBy,但其過程是瞬間完成的,沒有過度效果,用戶體驗並不好。 使用Scroller和View的computeScroll配合,可以實現有過渡效果的滑動       三、View的滑動   滑動是自定義View使用最多的效果之一, 有三種實現方式: a、View的scrollTo/ScrollBy方法   b、使用動畫為View施加平移效果   c、改變View的LayoutParams是的View重新布局實現滑動   1、使用scrollTo/ScrollBy   源碼: [java]view plaincopy
  1. /**
  2. *Setthescrolledpositionofyourview.Thiswillcauseacallto
  3. *{@link#onScrollChanged(int,int,int,int)}andtheviewwillbe
  4. *invalidated.
  5. *@paramxthexpositiontoscrollto
  6. *@paramytheypositiontoscrollto
  7. */
  8. publicvoidscrollTo(intx,inty){
  9. if(mScrollX!=x||mScrollY!=y){
  10. intoldX=mScrollX;
  11. intoldY=mScrollY;
  12. mScrollX=x;
  13. mScrollY=y;
  14. invalidateParentCaches();
  15. onScrollChanged(mScrollX,mScrollY,oldX,oldY);
  16. if(!awakenScrollBars()){
  17. postInvalidateOnAnimation();
  18. }
  19. }
  20. }
  21.  
  22. /**
  23. *Movethescrolledpositionofyourview.Thiswillcauseacallto
  24. *{@link#onScrollChanged(int,int,int,int)}andtheviewwillbe
  25. *invalidated.
  26. *@paramxtheamountofpixelstoscrollbyhorizontally
  27. *@paramytheamountofpixelstoscrollbyvertically
  28. */
  29. publicvoidscrollBy(intx,inty){
  30. scrollTo(mScrollX+x,mScrollY+y);
  31. }
    scrollBy實際上也調用scrollTo方法,實現基於當前位置的滑動,scrollTo實現基於所傳遞參數的絕對滑動 mScrollX和mScrollY可以動過get方法得到。 mScrollX的值總是等於View的左邊緣到View的內容左邊緣水平方向的距離, mScrollY的值總是等於View的上邊緣和View的內容上邊緣豎直方向的距離。   需要注意的是,scrollBy和scrollTo只能改變View的內容的位置而不能改變View在布局中的位置 在View的內容位置改變是,mScrollX和mScrollY值可正可負   2、使用動畫 通過動畫可以讓一個View進行平移,主要是操作View的translationX和translationY屬性,可以用View動畫,也可以用屬性動畫。 以屬性動畫為例, 我們在上面例子的基礎上添加一個按鈕 \

點擊按鈕,View在1秒鐘的時間內向右平移200像素

\

通過如下代碼:

[java]view plaincopy
  1. Buttonbutton=(Button)findViewById(R.id.btn);
  2. button.setOnClickListener(newView.OnClickListener(){
  3. @Override
  4. publicvoidonClick(Viewv){
  5. dragView.animate().translationX(200).setDuration(1000).start();
  6. }
  7. });
3.改變布局參數 即改變LayoutParams, 比如我們讓以上自定義View向右平移100像素 只要將此View的marginLeft參數值增加100px   同樣以上為例,將自定義View的寬度增加100px,向右平移100px [java]view plaincopy
  1. button.setOnClickListener(newView.OnClickListener(){
  2. @Override
  3. publicvoidonClick(Viewv){
  4. RelativeLayout.LayoutParamslayoutParams=(RelativeLayout.LayoutParams)dragView.getLayoutParams();
  5. layoutParams.width+=100;
  6. layoutParams.leftMargin+=100;
  7. dragView.requestLayout();
  8. //或者dragView.setLayoutParams(layoutParams);
  9. }
  10. });
​ 點擊按鈕發現View向右滑動而且變胖了,但是瞬間滑動過去的,沒有動畫效果 \
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved