昨天试着自己写这个长按,欲仙欲死.今天静下心来,好好地百度了一波,终于找到了.俺就是CV的命了.主要就是GestureDetector.安卓自己有提供''''
找到了启舰大神14年的博客
https://blog.csdn.net/harvic880925/article/details/39520901
private class gestureListener implements GestureDetector.OnGestureListener {
/**
* 用户按下屏幕就会触发
*/
@Override
public boolean onDown(MotionEvent e) {
return false;
}
/**
* 如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动的,
* 那么onShowPress就会执行,具体这个瞬间是多久,我也不清楚呃
* 0.5-1s
*/
@Override
public void onShowPress(MotionEvent e) {
}
/**
* 从名子也可以看出,一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,
* 才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,
* 所以也就不会触发这个事件
* 触发顺序:
* 点击一下非常快的(不滑动)Touchup:
* onDown->onSingleTapUp->onSingleTapConfirmed
* 点击一下稍微慢点的(不滑动)Touchup:
* onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
Toast.makeText(MainActivity.this, "不要单击", Toast.LENGTH_SHORT).show();
return false;
}
/**
* 在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,
* 都会多次触发,这个方法 在ACTION_MOVE动作发生时就会触发
* 滑屏:手指触动屏幕后,稍微滑动后立即松开
* onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
* 拖动
* onDown------》onScroll----》onScroll------》onFiling
*
* 可见,无论是滑屏,还是拖动,影响的只是中间OnScroll触发的数量多少而已,
* 最终都会触发onFling事件!
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
/**
* 长按触摸屏,超过一定时长,就会触发这个事件
* 触发顺序:
* onDown->onShowPress->onLongPress
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onLongPress(MotionEvent event) {
setLongPressDoing(event);
}
/**
* 滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,
* 多个ACTION_MOVE, 1个ACTION_UP触发
* 参数解释:
* @param e1 第1个ACTION_DOWN MotionEvent
* @param e2 最后一个ACTION_MOVE MotionEvent
* @param velocityX X轴上的移动速度,像素/秒
* @param velocityY Y轴上的移动速度,像素/秒
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setLongPressDoing(MotionEvent event){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
float y = event.getY();
//按下点 距上距下
int v1 = (int) Math.abs(bottom - y);
float min = Math.min(v1, y);
flag = !flag;
if (flag) {
Animator animator = ViewAnimationUtils.createCircularReveal(
change,//作用在哪个View上面
(int) x,
(int) y,//扩散的中心点
min,//开始扩散初始半径
defaul.getWidth());//扩散结束半径
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
change.setVisibility(View.VISIBLE);
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
tvshow.setVisibility(View.VISIBLE);
}
});
} else {
Animator animator = ViewAnimationUtils.createCircularReveal(
change,//作用在哪个View上面
(int) x,
(int) y,//扩散的中心点
defaul.getWidth(),//开始扩散初始半径
min);//扩散结束半径
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
change.setVisibility(View.GONE);
tvshow.setVisibility(View.GONE);
}
});
}
break;
default:
break;
}
}
这个可以自己发挥 ,但是吧我感觉这个玩意儿一个页面搞一个就行了
/*
* 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,
* 将捕捉到的MotionEvent交给GestureDetector
* 来分析是否有合适的callback函数来处理用户的手势
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
需要绑定
//自定义手势监听器
gestureListener gestureListener = new gestureListener();
gestureDetector = new GestureDetector(gestureListener);
//为当前View设置触控
framelayout.setOnTouchListener(this);
framelayout.setLongClickable(true);
framelayout.setClickable(true);
framelayout.setFocusable(true);
把昨天的通知栏长按完善之后
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
private boolean flag = false;
private TextView tvshow;
private FrameLayout framelayout;
private TextView change;
private TextView defaul;
private int bottom;
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//自定义手势监听器
gestureListener gestureListener = new gestureListener();
gestureDetector = new GestureDetector(gestureListener);
//为当前View设置触控
framelayout.setOnTouchListener(this);
framelayout.setLongClickable(true);
framelayout.setClickable(true);
framelayout.setFocusable(true);
//添加双击事件
gestureDetector.setOnDoubleTapListener(new MydoubleClick());
bottom = defaul.getBottom();
}
/*
* 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,
* 将捕捉到的MotionEvent交给GestureDetector
* 来分析是否有合适的callback函数来处理用户的手势
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private void initView() {
tvshow = (TextView) findViewById(R.id.tvshow);
framelayout = (FrameLayout) findViewById(R.id.framelayout);
change = (TextView) findViewById(R.id.change);
defaul = (TextView) findViewById(R.id.defaul);
}
private class gestureListener implements GestureDetector.OnGestureListener {
/**
* 用户按下屏幕就会触发
*/
@Override
public boolean onDown(MotionEvent e) {
return false;
}
/**
* 如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动的,
* 那么onShowPress就会执行,具体这个瞬间是多久,我也不清楚呃
* 0.5-1s
*/
@Override
public void onShowPress(MotionEvent e) {
}
/**
* 从名子也可以看出,一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,
* 才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,
* 所以也就不会触发这个事件
* 触发顺序:
* 点击一下非常快的(不滑动)Touchup:
* onDown->onSingleTapUp->onSingleTapConfirmed
* 点击一下稍微慢点的(不滑动)Touchup:
* onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
Toast.makeText(MainActivity.this, "不要单击", Toast.LENGTH_SHORT).show();
return false;
}
/**
* 在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,
* 都会多次触发,这个方法 在ACTION_MOVE动作发生时就会触发
* 滑屏:手指触动屏幕后,稍微滑动后立即松开
* onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
* 拖动
* onDown------》onScroll----》onScroll------》onFiling
*
* 可见,无论是滑屏,还是拖动,影响的只是中间OnScroll触发的数量多少而已,
* 最终都会触发onFling事件!
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
/**
* 长按触摸屏,超过一定时长,就会触发这个事件
* 触发顺序:
* onDown->onShowPress->onLongPress
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onLongPress(MotionEvent event) {
setLongPressDoing(event);
}
/**
* 滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,
* 多个ACTION_MOVE, 1个ACTION_UP触发
* 参数解释:
* @param e1 第1个ACTION_DOWN MotionEvent
* @param e2 最后一个ACTION_MOVE MotionEvent
* @param velocityX X轴上的移动速度,像素/秒
* @param velocityY Y轴上的移动速度,像素/秒
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setLongPressDoing(MotionEvent event){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
float y = event.getY();
//按下点 距上距下
int v1 = (int) Math.abs(bottom - y);
float min = Math.min(v1, y);
flag = !flag;
if (flag) {
Animator animator = ViewAnimationUtils.createCircularReveal(
change,//作用在哪个View上面
(int) x,
(int) y,//扩散的中心点
min,//开始扩散初始半径
defaul.getWidth());//扩散结束半径
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
change.setVisibility(View.VISIBLE);
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
tvshow.setVisibility(View.VISIBLE);
}
});
} else {
Animator animator = ViewAnimationUtils.createCircularReveal(
change,//作用在哪个View上面
(int) x,
(int) y,//扩散的中心点
defaul.getWidth(),//开始扩散初始半径
min);//扩散结束半径
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
change.setVisibility(View.GONE);
tvshow.setVisibility(View.GONE);
}
});
}
break;
default:
break;
}
}
private class MydoubleClick implements GestureDetector.OnDoubleTapListener{
/**
* 单击事件。用来判定该次点击是SingleTap而不是DoubleTap,
* 如果连续点击两次就是DoubleTap手势,
* 如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,
* 然后触发SingleTapConfirmed事件。
* 触发顺序是:
* OnDown->OnsingleTapUp->OnsingleTapConfirmed
* 关于onSingleTapConfirmed和onSingleTapUp的一点区别:
* OnGestureListener有这样的一个方法onSingleTapUp,和onSingleTapConfirmed容易混淆。
* 二者的区别是:
* onSingleTapUp,只要手抬起就会执行,
* 而对于onSingleTapConfirmed来说,
* 如果双击的话,则onSingleTapConfirmed不会执行。
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
/**
* 双击事件
*/
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(MainActivity.this, "AAAA", Toast.LENGTH_SHORT).show();
return false;
}
/**
* 虽然说 写了很多注释,但是没看明白,,正儿八经用的时候也是需要试验的
* 双击间隔中发生的动作。指触发onDoubleTap以后,
* 在双击之间发生的其它动作,包含down、up和move事件
*/
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/framelayout"
android:layout_width="200dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/defaul"
android:padding="10dp"
android:textColor="#fff"
android:textSize="20sp"
android:gravity="center"
android:text="开始就显示的"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="100dp" />
<TextView
android:visibility="gone"
android:id="@+id/change"
android:padding="10dp"
android:textColor="#fff"
android:textSize="20sp"
android:gravity="center"
android:background="@color/colorPrimaryDark"
android:text="可以是布局"
android:layout_width="match_parent"
android:layout_height="100dp" />
</FrameLayout>
<TextView
android:background="#f0f"
android:id="@+id/tvshow"
android:gravity="center_vertical"
android:visibility="gone"
android:text="更多 设置>"
android:layout_width="200dp"
android:layout_height="30dp" />
</LinearLayout>
接着,还有双击的监听
GestureDetector.OnDoubleTapListener
private class MydoubleClick implements GestureDetector.OnDoubleTapListener{
/**
* 单击事件。用来判定该次点击是SingleTap而不是DoubleTap,
* 如果连续点击两次就是DoubleTap手势,
* 如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,
* 然后触发SingleTapConfirmed事件。
* 触发顺序是:
* OnDown->OnsingleTapUp->OnsingleTapConfirmed
* 关于onSingleTapConfirmed和onSingleTapUp的一点区别:
* OnGestureListener有这样的一个方法onSingleTapUp,和onSingleTapConfirmed容易混淆。
* 二者的区别是:
* onSingleTapUp,只要手抬起就会执行,
* 而对于onSingleTapConfirmed来说,
* 如果双击的话,则onSingleTapConfirmed不会执行。
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
/**
* 双击事件
*/
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(MainActivity.this, "AAAA", Toast.LENGTH_SHORT).show();
return false;
}
/**
* 虽然说 写了很多注释,但是没看明白,,正儿八经用的时候也是需要试验的
* 双击间隔中发生的动作。指触发onDoubleTap以后,
* 在双击之间发生的其它动作,包含down、up和move事件
*/
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
}
//添加双击事件
gestureDetector.setOnDoubleTapListener(new MydoubleClick());
试了下效果还不错还剩这么最后一个,应该是官方自己写的差不多的
看到了,这个是类C,艹,Class 基本上继承就行了,它实现了上面说的那俩个的所有接口,不抽象了,用哪个重写那个
然后突然就没了!