在安卓中,对于事件的处理往往是最麻烦的一部分。
首先,ontouch方法的返回值有true和false两种,如果布局如下:
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" >
android:id="@+id/tv"
android:background="#ff00ff88"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:text="@string/hello_world" />
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都加上监听会:
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
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,则事件就会被拦截给父控件。读者有兴趣可以自己试一下。