日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
小Demo大知識(shí)-通過(guò)控制Button移動(dòng)來(lái)學(xué)習(xí)Android坐標(biāo)

今天分享一個(gè)簡(jiǎn)單的Demo。Demo實(shí)現(xiàn)的功能就是,用鼠標(biāo)點(diǎn)中button的時(shí)候,然后拖動(dòng)Button。這時(shí)候Button會(huì)根據(jù)你鼠標(biāo)的移動(dòng)而移動(dòng),同時(shí),你鼠標(biāo)點(diǎn)中的Button的位置也不會(huì)改變。比如你點(diǎn)在Button的左上角,那移動(dòng)的時(shí)候。鼠標(biāo)還是在Button的左上角

索縣網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)建站自2013年創(chuàng)立以來(lái)到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。

一言不合上效果圖 

 

大家不要介意上面那么模糊的gif圖,畢竟我是用手機(jī)拍的。(介意你又能拿我怎么辦。哈哈)

我們先來(lái)打個(gè)預(yù)防針,先學(xué)習(xí)基本的知識(shí)點(diǎn):

涉及到的方法一共有下面幾個(gè):

  • view獲取自身坐標(biāo):getLeft(),getTop(),getRight(),getBottom()
  • view獲取自身寬高:getHeight(),getWidth()
  • motionEvent獲取坐標(biāo):getX(),getY(),getRawX(),getRawY()

1.view獲取自身坐標(biāo)

如上圖所以,綠色區(qū)域的父視圖是黃色區(qū)域,所以left是55,top是55。

黃色區(qū)域的父視圖是藍(lán)色區(qū)域,所以left是60,top是115。 

2.view獲取自身寬高

沒(méi)錯(cuò)。從字面意思看就能理解,就是獲取View的寬高。

這里提到一個(gè)以前遇到的一個(gè)問(wèn)題,就是在Activity中有時(shí)候獲取某個(gè)View的width和height會(huì)為0。

3.motionEvent獲取坐標(biāo)

  • getX():獲取點(diǎn)擊事件相對(duì)控件左邊的x軸坐標(biāo),即點(diǎn)擊事件距離控件左邊的距離
  • getY():獲取點(diǎn)擊事件相對(duì)控件頂邊的y軸坐標(biāo),即點(diǎn)擊事件距離控件頂邊的距離
  • getRawX():獲取點(diǎn)擊事件相對(duì)整個(gè)屏幕左邊的x軸坐標(biāo),即點(diǎn)擊事件距離整個(gè)屏幕左邊的距離
  • getRawY():獲取點(diǎn)擊事件相對(duì)整個(gè)屏幕頂邊的y軸坐標(biāo),即點(diǎn)擊事件距離整個(gè)屏幕頂邊的距離

所以當(dāng)我們用鼠標(biāo)點(diǎn)擊Button中間時(shí)候,那這時(shí)候getX()就是我們鼠標(biāo)點(diǎn)擊的位置與Button左邊邊界的距離。getY()就是點(diǎn)擊的位置與Button頂邊邊界的距離。

其實(shí)設(shè)置Button跟著鼠標(biāo)滑動(dòng),很簡(jiǎn)單,就是在鼠標(biāo)滑動(dòng)的時(shí)候,重新設(shè)置Button的x和y坐標(biāo)。即使用setX()和setY()。這時(shí)候就有問(wèn)題了。那二個(gè)方法中該填入的值是多少呢。讓我們畫個(gè)圖來(lái)看下就知道了。

首先我們比如對(duì)一個(gè)Button設(shè)置setX(200),setY(200),這時(shí)候是如下圖所示這樣: 

所以實(shí)際上對(duì)一個(gè)Button設(shè)置setX(m),setY(n),實(shí)際上是這個(gè)Button的左上角的坐標(biāo)為(m,n)。所以我們?cè)谕蟿?dòng)的時(shí)候不能簡(jiǎn)單的把我們點(diǎn)擊的X和Y坐標(biāo)傳過(guò)去。  

如上圖所示,假如我們點(diǎn)中紅色的區(qū)域,來(lái)準(zhǔn)備移動(dòng)這個(gè)Button,并且鼠標(biāo)移動(dòng)了綠色區(qū)域那個(gè)地方,那么這個(gè)Button也會(huì)移到圖上所示那樣。這樣才是我們所期望的樣子。

但是如果單純把綠色區(qū)域的X和Y坐標(biāo)傳過(guò)去,讓Button來(lái)進(jìn)行setX和setY 。則會(huì)出現(xiàn)如下那個(gè)Button所示位置。所以發(fā)現(xiàn)比我們期望的位置更靠右邊及下邊了。   

這時(shí)候我們發(fā)現(xiàn)多的位置正好是綠色區(qū)域在這個(gè)Button內(nèi)部中相對(duì)位置的X和Y坐標(biāo)。

這下我們是不是就想到,對(duì)Button設(shè)置setX(getRawX()-getX())和setY(getRawY()- getY()),如果這時(shí)候你已經(jīng)這么想到了。恭喜你,你已經(jīng)距離最后的成功差一小步了。當(dāng)你高興的這么寫后,你會(huì)發(fā)現(xiàn)你移動(dòng)后的Button總是在鼠標(biāo)點(diǎn)擊的下方。你會(huì)發(fā)現(xiàn)。X軸的的確已經(jīng)正確了。但是Y軸還是錯(cuò)誤。如下圖所示:  

這時(shí)候你一定會(huì)問(wèn),WHY???

原來(lái)這么分析是沒(méi)問(wèn)題的。But這個(gè)我們前面的假設(shè)都是在這個(gè)坐標(biāo)系中,但是這個(gè)坐標(biāo)系的位置在哪里???  

錯(cuò)誤原因:

因?yàn)槲覀冋{(diào)用的getRawY()方法獲取到的是屏幕左上角到我們點(diǎn)的區(qū)域的Y軸的距離,也就是以藍(lán)色坐標(biāo)系來(lái)做參考。而我們對(duì)Button設(shè)置setY()方法的時(shí)候是綠色區(qū)域的左上角到我們點(diǎn)的區(qū)域的Y軸距離,也就是以紅色坐標(biāo)系來(lái)做參考。所以我們知道了。我們?cè)赮軸上還要減去狀態(tài)欄的高度及應(yīng)用標(biāo)題欄的高度才可以。

那么又有新的問(wèn)題了。如何獲取狀態(tài)欄的高度,和應(yīng)用標(biāo)題欄的高度:

獲取狀態(tài)欄高度

 
 
 
 
  1. int statusBarHeight = -1;   
  2. //獲取status_bar_height資源的ID   
  3. int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "Android");   
  4. if (resourceId > 0) {   
  5.     //根據(jù)資源ID獲取響應(yīng)的尺寸值   
  6.     statusBarHeight = getResources().getDimensionPixelSize(resourceId);   
  7. }  

獲取標(biāo)題欄高度

 
 
 
 
  1. // 獲取標(biāo)題欄高度   
  2. Window window = getWindow();   
  3. int contentViewTop = getWindow()   
  4.         .findViewById(Window.ID_ANDROID_CONTENT).getTop();   
  5. // statusBarHeight是上面所求的狀態(tài)欄的高度   
  6. titleBarHeight = contentViewTop - statusBarHeight;  

結(jié)論:

所以最后我們?cè)偻蟿?dòng)Button的時(shí)候,會(huì)對(duì)它setX(getRawX()-getX())及setY(getRawY()-getY()-狀態(tài)欄高度-標(biāo)題欄高度)。其中g(shù)etX()和getY()是在你點(diǎn)擊下去的時(shí)候就獲取的。也就是在motionEvent.getAction() == MotionEvent.ACTION_DOWN的時(shí)候去獲取這二個(gè)值即可。因?yàn)樵趍otionEvent.getAction() == MotionEvent.ACTION_MOVE的時(shí)候去獲取getX()和getY()可能因?yàn)槟阃蟿?dòng)的速度原因造成值不同,比如你拖動(dòng)很快,鼠標(biāo)先過(guò)去了。Button后面才跟隨著過(guò)來(lái)。這時(shí)候的getX()及getY()都不同。

既然點(diǎn)擊按鈕后可以拖動(dòng)Button,那肯定對(duì)Button設(shè)置了OnTouch監(jiān)聽(tīng)。直接上關(guān)鍵代碼: 

 
 
 
 
  1. package yunyuan.androiddemo.coordinatelayout;
  2. import android.app.Activity; 
  3. import android.os.Bundle; 
  4. import android.view.MotionEvent; 
  5. import android.view.View; 
  6. import android.view.Window; 
  7. import android.widget.Button; 
  8.  
  9. import butterknife.BindView; 
  10. import butterknife.ButterKnife; 
  11. import yunyuan.androiddemo.R; 
  12.  
  13. /** 
  14.  * Created by willy on 16/12/19. 
  15.  */ 
  16.  
  17. public class Act_CoordinateLayout extends Activity{ 
  18.  
  19.     @BindView(R.id.btn) 
  20.     Button btn; 
  21.  
  22.     float dx,dy; 
  23.  
  24.  
  25.     @Override 
  26.     protected void onCreate(Bundle savedInstanceState) { 
  27.         super.onCreate(savedInstanceState); 
  28.         setContentView(R.layout.act_coordinatelayout); 
  29.         ButterKnife.bind(this); 
  30.  
  31.         btn.setOnTouchListener(new Button.OnTouchListener() { 
  32.             @Override 
  33.             public boolean onTouch(View view, MotionEvent motionEvent) { 
  34.                 if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){ 
  35.                     dx = motionEvent.getX(); 
  36.                     dy = motionEvent.getY(); 
  37.  
  38.                 } else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){ 
  39.  
  40.                     view.setX(motionEvent.getRawX() - dx); 
  41.                     view.setY(motionEvent.getRawY()- dy - getStatusBarHeight() - getTitleBarHeight()); 
  42.                 } 
  43.                 return true; 
  44.             } 
  45.         }); 
  46.     } 
  47.  
  48.  
  49.     public int getStatusBarHeight(){ 
  50.         int result = 0; 
  51.         int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 
  52.         if (resourceId > 0) { 
  53.             result = getResources().getDimensionPixelSize(resourceId); 
  54.         } 
  55.         return result; 
  56.     } 
  57.  
  58.  
  59.     public int getTitleBarHeight(){ 
  60.         Window window = getWindow(); 
  61.         int contentViewTop = getWindow() 
  62.                 .findViewById(Window.ID_ANDROID_CONTENT).getTop(); 
  63.         // statusBarHeight是上面所求的狀態(tài)欄的高度 
  64.         int titleBarHeight = contentViewTop - getStatusBarHeight(); 
  65.         return titleBarHeight; 
  66.     } 
  67. }  

當(dāng)前題目:小Demo大知識(shí)-通過(guò)控制Button移動(dòng)來(lái)學(xué)習(xí)Android坐標(biāo)
URL分享:http://www.dlmjj.cn/article/dpsccpc.html