事件传递
事件传递的机制图:
利用事件传递机制简单的做一个下拉刷新的,
activity_main.xml
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshlayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"></ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private SwipeRefreshLayout mRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView= (ListView) findViewById(R.id.listview);
mRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.swiperefreshlayout);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,new String[]{"a","b","c","d","e","f","g","b","c","d","e","f","g","b","c","d","e","f","g"});
mListView.setAdapter(adapter);
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mRefreshLayout.setRefreshing(false);
}
});
}
}
注意:需要导入android.support.v4.jar包
还可以自已定义一个View来实现刷新内容
首先自定义一个View,MyTouch.java
public class MyTouch extends FrameLayout{
private ListView content;
public MyTouch(Context context) {
super(context);
}
public MyTouch(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View update=inflater.inflate(R.layout.activity_update,null);
addView(update);
content= (ListView) inflater.inflate(R.layout.activity_listview,null);
addView(content);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(context,android.R.layout.simple_list_item_1,
new String[]{"a","b","c","d","e","f","g","b","c","d","e","f","g","b","c","d","e","f","g"});
content.setAdapter(adapter);
}
public MyTouch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (content.getFirstVisiblePosition()==0){
View firstView=content.getChildAt(content.getFirstVisiblePosition());
if (firstView.getY()>=0){
return true;
}
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
float oldY=0;
float y=0;
int offset=0;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
oldY=event.getY();
break;
case MotionEvent.ACTION_MOVE:
y=event.getY();
float distance=y-oldY;
content.setTranslationY(content.getTranslationY()+distance);
oldY=y;
invalidate();
break;
case MotionEvent.ACTION_UP:
ObjectAnimator.ofFloat(content,"translationY",content.getTranslationY(),0).setDuration(300).start();
break;
}
return true;
}
}
activity_main.xml
<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="horizontal"
tools:context=".MainActivity">
<com.example.administrator.mytouch.MyTouch
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.administrator.mytouch.MyTouch>
</LinearLayout>
activity_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
</ListView>
activity_update.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="下拉刷新"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
手势操作
Android 为手势检测提供了一个GestureDetector类,GestrueDetector实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestrureListener实例,GestureDetector.OnGestrueListener就是一个监听器,负责对用户的手势行为提供响应。
GestrueDetector.OnGestureListener里包含的事件处理抽象方法如下。
- boolean onDown(MotionEvent e):当触碰事件按下时触发该方法。
- boolean onFling(MotionEvent e1,MotionEvent e2,float velocitX,floatvelocity):当用户在触屏上拖过是触发该方法。其中velocityX,velocityY代表拖过动作在横向,纵向上的速度。
- void onLongPress(MotionEvent e):当用户在屏幕上长按时触发该方法。
- boolean onScroll(MotionEvent e1,MotionEvent e2,float distance,float distance):当用户在屏幕上滚动式触发该方法。
- void onShowPress(MotionEvent e):当用户在触摸屏上按下,而且还未移动和松开时触发该方法。
- boolean onSingleTapUp(MotionEvent e):用户在触摸屏上的轻击事件将会触发该方法。
(注意:这里也可以传入GestureDetector.SimpleOnGestureListener()监听器,只对我们需要的方法进行重写。)
先写一个双击事件,自定义一个Button,MyButton.java
public class MyButton extends Button{
private GestureDetector mGesture;
interface OnDoubleTouchClick{
public void onDoubleTouchClick(View v);
}
private OnDoubleTouchClick onDoubleTouchClickListener;
public void setOnDoubleTouchClickListener(OnDoubleTouchClick onDoubleTouchClickListener) {
this.onDoubleTouchClickListener = onDoubleTouchClickListener;
}
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
mGesture=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
if (onDoubleTouchClickListener!=null){
onDoubleTouchClickListener.onDoubleTouchClick(MyButton.this);
}
return true;
}
});
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGesture.onTouchEvent(event);
return super.onTouchEvent(event);
}
}
activity_main.xml
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.administrator.mygesture.MyButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手势按钮"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private MyButton button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (MyButton) findViewById(R.id.button);
button.setOnDoubleTouchClickListener(new MyButton.OnDoubleTouchClick() {
@Override
public void onDoubleTouchClick(View v) {
Toast.makeText(MainActivity.this, "点击了两次", Toast.LENGTH_SHORT).show();
}
});
}
}
滑动事件,只需要在监听事件里添加onFiling()方法即可,里面注明要监听事件的距离时长
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(e2.getX()-e1.getX())>50){
ObjectAnimator.ofFloat(MyButton.this,"translationX",getTranslationX(),getTranslationX()+e2.getX()-e1.getX()).setDuration(500).start();
return true;
}
else if(Math.abs(e2.getY()-e1.getY())>50){
ObjectAnimator.ofFloat(MyButton.this,"translationY",getTranslationY(),getTranslationY()+e2.getY()-e1.getY()).setDuration(500).start();
}
return super.onFling(e1, e2, velocityX, velocityY);
}
拖动事件,只需在监听事件里添加onScroll()方法,
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
setTranslationX(getTranslationX()+e2.getX()-e1.getX());
setTranslationY(getTranslationY()+e2.getY()-e1.getY());
return true;
}