下面的很多東西 都是網(wǎng)上找的 也一直那么用。
終于有一天自己較真。 想要看看 下面就是我的發(fā)現(xiàn)。
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN: // touch down so check if the
temp[0] = (int) event.getX(); // 觸摸點(diǎn)距離控件左邊部的距離
temp[1] = y - v.getTop(); // 觸摸點(diǎn)距離控件頂部的距離
int i = (int) event.getY();
if(y - v.getTop() ==event.getY()){
int b= 00;
}
先看上面這段 不完全的代碼
event.getRawY() - v.getTop() ==event.getY() 這句話 等于true嗎? 如果你只看網(wǎng)上的那些 這句話 是沒有問題的。當(dāng)時(shí)當(dāng)你打印的話嗎, 那么就會(huì)知道 永遠(yuǎn)不會(huì)成功。 他們查了75 對(duì) 永遠(yuǎn)查了這么多。 相信有的看出來了。 就是差的狀態(tài)欄高度。 這就是很大坑。 v.getTop() 的意思 是當(dāng)前view 相對(duì)于父 view的高度。 但是這個(gè)是跑出狀態(tài)欄的。 大家懂了吧。
int ty = y - temp[1];
int by = y - temp[1] + v.getHeight();
//temp[1] 觸摸點(diǎn)到控件定點(diǎn)的距離 唄Y減去 得到的值 就是 控件頂端距離屏幕上面的 距離。 也就是Y坐標(biāo)( 他為什么虎沒有誤差。 狀態(tài)欄的高度被減去了。) 加上v.getHeight() 就是底端的距離
// 所以 ty by dedao 就是控件 頂部和底部 距離最上面的距離 也就是Y 坐標(biāo)
if (ty<0){
ty=0;
// 沒有這種情況 ty時(shí)間上就是v.getTop()(只有一層父view的時(shí)候) 這樣方便理解。 其他的要是要這么算。 就是為了莊明 不會(huì)小于0 最多等于0
}else if (ty>windowHeight-v.getHeight()){
ty = windowHeight-v.getHeight();
}
下面都是網(wǎng)上的。 我會(huì)慢慢去驗(yàn)算
一、getX、getRawX、getTranslationX等的圖形表示**</pre>
首先我們來看看這幾個(gè)方法在圖形上的表示,然后再用代碼的形式進(jìn)行驗(yàn)證我們來看下這幾個(gè)方法的幾何圖形的表示:
上面只是用圖片表示了這幾個(gè)距離的意義,下面我們用文字來描述一下,然后通過案例來驗(yàn)證一下大家就徹底明白這幾個(gè)距離的意義了。
二、getX、getRawX、getTranslationX意義的文字描述**</pre>
event.getX():表示的是觸摸的點(diǎn)距離自身左邊界的距離
event.getY():表示的是觸摸的點(diǎn)距離自身上邊界的距離
event.getRawX:表示的是觸摸點(diǎn)距離屏幕左邊界的距離
event.getRawY:表示的是觸摸點(diǎn)距離屏幕上邊界的距離
View.getWidth():表示的是當(dāng)前控件的寬度,即getRight()-getLeft()</pre>
View.getHeight():表示的是當(dāng)前控件的高度,即getBottom()-getTop()
View.getTop():子View的頂部到父View頂部的距離
View.getRight():子View的右邊界到父View的左邊界的距離
View.getBottom():子View的底部到父View的頂部的距離
View.getLeft():子View的左邊界到父View的左邊界的距離
View.getTranslationX()計(jì)算的是該View在X軸的偏移量。初始值為0,向左偏移值為負(fù),向右偏移值為正。
View.getTranslationY()計(jì)算的是該View在Y軸的偏移量。初始值為0,向上偏移為負(fù),向下偏移為證。 </pre>
細(xì)心的同學(xué)會(huì)發(fā)下上面多了個(gè)getTranslationX,這個(gè)計(jì)算的是該View在X軸的偏移量。初始值為0,向左偏移值為負(fù),向右偏移值為正。由于用用圖形不好表示,在后面會(huì)有一個(gè)案例來說明它的意義。
</pre>
<pre style="white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; margin: 0px 0px 24px; background-color: rgb(240, 240, 240); overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">三、案例理解getX、getRawX、getTranslationX的用法</pre>
接下來我們通過兩個(gè)案例來理解getX、getRawX、getTranslationX的意義,首先來看下運(yùn)行效果圖:
然后我來解釋下這個(gè)布局首先最外面那個(gè)是手機(jī)屏幕,然后里面的白色矩形是里面黑色矩形的父View,中間的那個(gè)小的白點(diǎn)是我們點(diǎn)擊的一個(gè)點(diǎn),它處于屏幕的正中央,其中屏幕的分辨率是480*320,我們都知道在這種分辨率下1dp=1px,然后白色矩形的寬和高都是300dp,中間黑色矩形的寬和高都是150dp,中間黑色區(qū)域是rlCenter,中間的小白點(diǎn)是ivDot大家可以算一下rlCenter.getWidth,rlCenter.getX,rlCenter.getRawX以及rlCenter.getTop,rlCenter.getBottom等,然后和后面打印的日志對(duì)比下,首先來看下代碼:
[java] view plaincopy
package com.example.test;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
private boolean isFocus=false;
private RelativeLayout rlCenter;
private int screenWidth;
private int screenHeight;
private float x,y;
private float rawX,rawY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
rlCenter=(RelativeLayout) findViewById(R.id.rl_center);
screenWidth = ScreenUtils.getScreenWidth(MainActivity.this);
screenHeight = ScreenUtils.getScreenHeight(MainActivity.this);
Log.i("MainActivity","screenWidth:"+screenWidth);
Log.i("MainActivity","screenHeight:"+screenHeight);
rlCenter.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
x=event.getX();
y=event.getY();
rawX=event.getRawX();
rawY=event.getRawY();
Log.i("MainActivity", "event.getX()="+x+","+"event.getY()="+y+","+"event.getRawX()="+rawX+"event.getRawY()="+rawY);
break;
}
return false;
}
});
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus&&!isFocus){
Log.i("MainActivity", "rlCenter.getWidth="+rlCenter.getWidth()+","+"rlCenter.getHeight="+rlCenter.getHeight());
Log.i("MainActivity", "rlCenter.getLeft="+rlCenter.getLeft()+","+"rlCenter.getRight="+rlCenter.getRight()+","+"rlCenter.getTop="+rlCenter.getTop()+","+"rlCenter.getBottom="+rlCenter.getBottom());
}
isFocus=true;
}
}
然后看下打印的結(jié)果:
與你計(jì)算的一樣嗎?其中大家看到的可能會(huì)有0.0幾的誤差因?yàn)橹虚g的那個(gè)小白點(diǎn)是2dp,可能點(diǎn)擊的時(shí)候并不是剛好是正中間但是并不影響我們的測(cè)試。好了到這里相信大家對(duì)這幾個(gè)概念應(yīng)該有了比較清楚的認(rèn)識(shí)。接著我們來看下getTranslationX,上面我們提到它計(jì)算的是該View在X軸的偏移量。初始值為0,向左偏移值為負(fù),向右偏移值為正。怎么來驗(yàn)證它呢?用屬性動(dòng)畫及可以做到,首先我們來看下代碼:
[java] view plaincopy
<embed id="ZeroClipboardMovie_2" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
package com.example.test2;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
public class MainActivity extends Activity{
private ImageView ivTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivTest=(ImageView) findViewById(R.id.iv_test);
ivTest.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.i("MainActivity","ivTest.getTranslationX()="+ivTest.getTranslationX()+","+"ivTest.getTranslationY()="+ivTest.getTranslationY());
ObjectAnimator.ofFloat(ivTest,"translationX",100f).setDuration(1000).start();
}
});
}
}
來看看它的打印結(jié)果:
看到了吧,剛開始打印的getTranslationX為0,然后我們執(zhí)行屬性動(dòng)畫這個(gè)屬性動(dòng)畫就是讓這個(gè)View向右移動(dòng)100px之后再打印發(fā)現(xiàn)它的值變成了100,這也驗(yàn)證了我們的說法。
1、getRawX、getRawY與getX、getY的區(qū)別
這四個(gè)方法都返回一個(gè)float類型的參數(shù),單位為像素(Pixel)。
getRawX()、getRawY()返回的是觸摸點(diǎn)相對(duì)于屏幕的位置,
而getX()、getY()返回的則是觸摸點(diǎn)相對(duì)于View的位置。
2、View中的getScrollX、getScrollY
getScrollX()與getScrollY()的值由調(diào)用View的scrollTo(int x, int y)或者scrollBy(int x, int y)產(chǎn)生
其中scrollTo是將View中的內(nèi)容移動(dòng)到指定的坐標(biāo)x、y處,此x、y是相對(duì)于View的左上角,而不是屏幕的左上角。
scrollBy(int x, int y)則是改變View中的相對(duì)位置,參數(shù)x、y為距離上一次的相對(duì)位置。
圖:
屏幕中心放置了一個(gè)button,而button的內(nèi)容被放置在了它的左上角
調(diào)用button的scrollTo(-100, -100)方法,button內(nèi)的內(nèi)容被移至相對(duì)button左上角(-100,-100)的位置
對(duì)上圖調(diào)用scrollBy(-100,-100)方法,button內(nèi)的內(nèi)容被移至相對(duì)于上圖的(-100,-100)位置
值得注意的是,當(dāng)View中的內(nèi)容向右移動(dòng)時(shí),getScrollX()的值為負(fù)數(shù),同理,向scrollTo與scrollBy的x中傳入負(fù)數(shù),view中的內(nèi)容向右移動(dòng),反之向左。
當(dāng)View中的內(nèi)容向下移動(dòng)時(shí),getScrollY()的值為負(fù)數(shù),同理,向scrollTo與scrollBy的y中傳入負(fù)數(shù),view中的內(nèi)容向下移動(dòng),反之向上。
3、View 提供的獲取坐標(biāo)的方法:都是以父布局的頂邊和左邊為對(duì)比
getTop()
獲取到的是View本身的頂邊到其父布局頂邊的距離getLeft()
獲取到的是View本身的左邊到其父布局左邊的距離getRight()
獲取到的是View本身的右邊到其父布局左邊的距離getBottom()
獲取到的是View本身的下邊到其父布局頂邊的距離