android onTouch事件详解

在安卓中,对于事件的处理往往是最麻烦的一部分。
首先,ontouch方法的返回值有true和false两种,如果布局如下:

<span style="font-size:14px;"><RelativeLayout 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:id="@+id/re"
    tools:context="com.example.ontouch.MainActivity" >
    <TextView
        android:id="@+id/tv"
        android:background="#ff00ff88"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:text="@string/hello_world" />
</RelativeLayout></span>


Java代码如下:

public class MainActivity extends Activity implements OnTouchListener
{

	private RelativeLayout relativeLayout;
	private TextView textView;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		relativeLayout = (RelativeLayout) findViewById(R.id.re);
		textView = (TextView) findViewById(R.id.tv);
		textView.setOnTouchListener(this);
		
	}
	@Override
	public boolean onTouch(View v, MotionEvent event)
	{
		int action = event.getAction();
		switch (action)
		{
		case MotionEvent.ACTION_DOWN:
			Log.i("info","down");
			break;
		case MotionEvent.ACTION_MOVE:
			Log.i("info", "move");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("info", "up");
			break;
		default:
			break;
		}
		return false;
	}

	
}


 
 

这时如果点击textview,你会发现只会打印"down",原因就是ontouch的返回值。返回值是false,默认的是不拦截当前事件,事件触发后就会传递走,如果改成true,就会发现把事件拦截下来,这是点击移动,就会down,move,move..up。 如果给外层布局和textview都加上监听会:

<pre name="code" class="java">public class MainActivity extends Activity implements OnTouchListener
{

	private RelativeLayout relativeLayout;
	private TextView textView;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		relativeLayout = (RelativeLayout) findViewById(R.id.re);
		relativeLayout.setOnTouchListener(new OnTouchListener()
		{
			
			@Override
			public boolean onTouch(View v, MotionEvent event)
			{
				int action = event.getAction();
				switch (action)
				{
				case MotionEvent.ACTION_DOWN:
					Log.i("info","re down");
					break;
				case MotionEvent.ACTION_MOVE:
					Log.i("info", "re move");
					break;
				case MotionEvent.ACTION_UP:
					Log.i("info", "re up");
					break;
				default:
					break;
				}
				return false;
			}
		});
		textView = (TextView) findViewById(R.id.tv);
		textView.setOnTouchListener(this);
		
	}
	@Override
	public boolean onTouch(View v, MotionEvent event)
	{
		int action = event.getAction();
		switch (action)
		{
		case MotionEvent.ACTION_DOWN:
			Log.i("info","down");
			break;
		case MotionEvent.ACTION_MOVE:
			Log.i("info", "move");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("info", "up");
			break;
		default:
			break;
		}
		return false;
	}

	
}
 
 

先down在re down down re down如果把textview的ontouch改成true

<pre name="code" class="java">public class MainActivity extends Activity implements OnTouchListener
{

	private RelativeLayout relativeLayout;
	private TextView textView;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		relativeLayout = (RelativeLayout) findViewById(R.id.re);
		relativeLayout.setOnTouchListener(new OnTouchListener()
		{
			
			@Override
			public boolean onTouch(View v, MotionEvent event)
			{
				int action = event.getAction();
				switch (action)
				{
				case MotionEvent.ACTION_DOWN:
					Log.i("info","re down");
					break;
				case MotionEvent.ACTION_MOVE:
					Log.i("info", "re move");
					break;
				case MotionEvent.ACTION_UP:
					Log.i("info", "re up");
					break;
				default:
					break;
				}
				return false;
			}
		});
		textView = (TextView) findViewById(R.id.tv);
		textView.setOnTouchListener(this);
		
	}
	@Override
	public boolean onTouch(View v, MotionEvent event)
	{
		int action = event.getAction();
		switch (action)
		{
		case MotionEvent.ACTION_DOWN:
			Log.i("info","down");
			break;
		case MotionEvent.ACTION_MOVE:
			Log.i("info", "move");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("info", "up");
			break;
		default:
			break;
		}
		return true;
	}

	
}


 
 

显示 down move move up..如果都改成ture和上面的一样。现在可以初步得出一个结论了,自控件的ontouch返回值会对父控件产生影响,如果子控件返回的是true,则事件就不会传递到父控件。这样看上去时间的传递像是先从子控件传到父控件,其实并不是这样的,而是事件产生后会先交给父控件,在父控件onInterceptTouchEvent方法中进行分配,大多数控件这个方法会默认的把事件先传递给子控件。如果将其返回值改成true,则事件就会被拦截给父控件。读者有兴趣可以自己试一下。

 
 
 

你可能感兴趣的:(android onTouch事件详解)