view x y 轴
|-------------------------->x
|
|
|
|
y
view 的位置参数
left:view左上角相对于父容器横坐标
top:view左上角相对于父容器纵坐标
righ:view右下角相对于父容器横坐标
bottom:view右下角相对于父容器的纵坐标
那么就很容易得到view的width 和 height
width = right - left
height = bottom - top
对应的get方法:(要在view layout完成之后获取,否则就会是0)
getLeft
getTop
getRight
getBottom
3.0之后增加了x , y ,translationX ,translationY 四个值(也是相对于父容器的值)
translationX 和translationY默认值是0 ,表示的是view 相对于父容器的平移值
对应的关系:
x = left + translationX
y= top + translationY
note:在平移的过程中left。top 。right ,bottom 是不变的,变的只是x,y 和translationX 和translationY,
left top right bottom 保存的是view的初始位置
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private static final String TAG = "MainActivity";
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) this.findViewById(R.id.button1);
mTextView = (TextView) this.findViewById(R.id.text);
mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "text Click", Toast.LENGTH_SHORT).show();
}
});
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
print();
mTextView.setTranslationX(mTextView.getTranslationX() + 6);
mButton.setTranslationX(mButton.getTranslationX() + 10);
mButton.setTranslationY(mButton.getTranslationY() + 10);
}
});
}
private void print() {
Log.d(TAG, "getLeft: " + mTextView.getLeft());
Log.d(TAG, "getTop: " + mTextView.getTop());
Log.d(TAG, "getRight: " + mTextView.getRight());
Log.d(TAG, "getBottom: " + mTextView.getBottom());
Log.d(TAG, "getX: " + mTextView.getX());
Log.d(TAG, "getY: " + mTextView.getY());
Log.d(TAG, "getTranslationX: " + mTextView.getTranslationX());
Log.d(TAG, "getTranslationY: " + mTextView.getTranslationY());
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.jinxiong.test5.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_dark"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:text="Hello World!"/>
</LinearLayout>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="but"
/>
</LinearLayout>
MotionEvent 和 TouchSlop
典型的事件:
ACTION_DOWN 手指刚接触到屏幕
ACTION_MOVE手指在屏幕上移动
ACTION_UP 手指离开屏幕
一次手指触摸屏幕会产生相应一些事件:
点击屏幕马上离开 : ACTION_DOWN ------> ACTION_UP
点击屏幕滑动一段距离: ACTION_DOWN-->ACTION_MOVE-->ACTION_MOVE.........-->ACTION_UP 经历多个的move事件
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
}
});
通过MotionEvent 我们可以得到事件类型和这个接触点的坐标
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "getX: " + event.getX());
Log.d(TAG, "getY: " + event.getY());
Log.d(TAG, "getRawX: " + event.getRawX());
Log.d(TAG, "getRawY: " + event.getRawY());
return true;
}
});
getX ,getY得到的是接触点相对于当前点击的view的左上角的距离
getRawX ,getRawY 得到是接触点相对于整个屏幕的左上角的距离
Log.d(TAG, "onCreate: " + ViewConfiguration.get(this).getScaledTouchSlop());
TouchSlop 是一个常量值,系统识别事件是否是是滑动用于比较,单位为px ,不同的设备不一样
/**
* Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
*/
public class ViewConfiguration {<span style="font-family: Arial, Helvetica, sans-serif;">}这个类包含很多在UI上用到的一些常量</span>
VelocityTracker
用于追踪手指在滑动过程中的速度
在OnTouchEvent中追踪点钱点击事件的速度:
linearLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// if (event.getAction() == MotionEvent.ACTION_MOVE) {
VelocityTracker velocity = VelocityTracker.obtain();
velocity.addMovement(event);//必须调用,<span style="color: rgb(150, 152, 150); font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace; font-size: 13px; line-height: 18.5714px; white-space: pre; widows: 1;">将事件加入到VelocityTracker类实例中 </span>
velocity.computeCurrentVelocity(200);//调用<span style="font-family: Arial, Helvetica, sans-serif;">velocity.getXVelocity(),</span><span style="font-family: Arial, Helvetica, sans-serif;">getYVelocity ,必须设置这个时间值,单位为毫秒</span>
Log.d(TAG, "getXVelocity: " + velocity.getXVelocity());
Log.d(TAG, "getYVelocity: " + velocity.getYVelocity());
velocity.clear();//不需要的时候清空回收
velocity.recycle();
return true;
// }
// return false;
}
});
GestureDetector
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout linearLayout = (LinearLayout) this.findViewById(R.id.root);
mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
Log.d(TAG, "onDown: ");//手指轻触屏幕的瞬间,由一个ACTION_DOWN触发
return true;
}
@Override
public void onShowPress(MotionEvent e) {//手指轻触屏幕后尚未松开或者拖动,由一个Action_Down触发,
//与onDown相比较,强调的是没有松开和拖动
Log.d(TAG, "onShowPress: ");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d(TAG, "onSingleTapUp: ");//手指轻触之后离开,伴随着一个UP事件,单击事件
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d(TAG, "onScroll: ");//手指按下屏幕并且 拖动 ,有一个down 和多个move事件
return true;
}
@Override
public void onLongPress(MotionEvent e) {//长按,mGestureDetector.setIsLongpressEnabled(false);设置为false之后不触发
Log.d(TAG, "onLongPress: ");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(TAG, "onFling: ");//快速滑动,有一个down 多个move 和一个up触发,
return true;
}
});
mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(TAG, "onSingleTapConfirmed: ");//严格的单击事件与doubleTap不可共存
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {//双击行为
Log.d(TAG, "onDoubleTap: ");
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.d(TAG, "onDoubleTapEvent: ");//表示发生了双击行为
return true;
}
});
linearLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "linearLayout onTouch: ACTION_DOWN");
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "linearLayout onTouch: ACTION_MOVE");
case MotionEvent.ACTION_UP:
Log.d(TAG, "linearLayout onTouch: ACTION_UP");
}
return mGestureDetector.onTouchEvent(event);
}
});
mGestureDetector.setIsLongpressEnabled(false);
}
08-28 10:14:39.140 1479-1479/MainActivity: linearLayout onTouch: ACTION_DOWN
08-28 10:14:39.140 1479-1479/MainActivity: linearLayout onTouch: ACTION_MOVE//手多
08-28 10:14:39.140 1479-1479/MainActivity: linearLayout onTouch: ACTION_UP
08-28 10:14:39.140 1479-1479/MainActivity: onDown:
08-28 10:14:39.240 1479-1479/MainActivity: linearLayout onTouch: ACTION_UP
08-28 10:14:39.240 1479-1479/MainActivity: onSingleTapUp: //伴随着UP事件
08-28 10:14:39.440 1479-1479/MainActivity: onSingleTapConfirmed:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:id="@+id/root"
android:background="@android:color/holo_red_dark"
tools:context="com.example.jinxiong.test6.MainActivity">
</LinearLayout>
一般双击事件的监听是用GestureDetector的 ,其他的一半直接在OnTouch中监听
或者这样new 一个GestureDetector
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener());