onTouchEvent 触摸事件介绍
@Override
public boolean onTouchEvent(MotionEvent event) {
//主要使用的就是这几个事件 ACTION_DOWN ACTION_MOVE ACTION_UP 如果有其他的要求的话,再启用其他的触摸事件
switch (event.getAction()){
case MotionEvent.ACTION_DOWN :
break;
case MotionEvent.ACTION_MOVE :
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
- 在我的练习经历中好像没有单独使用onTouchEvent的,都是结合着Scroller或者是GestureDetector等来使用的,比如横向的手势页面切换,还有就是第一部分说过的那个粘性的滑动
这里写个案例吧O(∩_∩)
- 手势切换横向页面的滑动 直接上代码啦,里面注释我觉得写的非常清楚了
//1、new出来一个GestureDetector,这个是主要目的,然后重写Listener的接口中的方法
GestureDetector mGestureDetector = new GestureDetector(new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) { //按下出发触发
return false;
}
@Override
public void onShowPress(MotionEvent e) {//在按下一段时间的时候触发这个事件,这个事件比LongPress触发的实践要短,O(∩_∩)O
}
@Override
public boolean onSingleTapUp(MotionEvent e) { //轻触抬起动作触发,长时间按下抬起是不触发的哦
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//在用户滑动屏幕的时候触发
return false;
}
@Override
public void onLongPress(MotionEvent e) {//这个是最持久的,时间最长的,坚持住!
}
//这个是用户的滑屏的动作 I am fling! 其实做手势操作,这一个callback足够应付了
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//1. 既然要处理横向滑动事件,那么就要判断是不是在横向滑动呢?这里就不去判断Y方向的误差了,如果想要user更爽,还是判断比较好哈
float startX = e1.getX();
float endX = e2.getX();
/*
* 这个是LOG日志信息
* 03-29 16:51:26.508 4274-4274/com.zh.young.gestureandtouchevent I/MainActivity: startX = 106.09497-------endX = 796.6846 向右滑动的结果
* 03-29 16:51:31.825 4274-4274/com.zh.young.gestureandtouchevent I/MainActivity: startX = 781.68823-------endX = 235.19531 向左滑动的结果
* 可以看出规律了,向右滑动endX的值比较大,向左滑动的时候endX的值比较小,那么我们就可以根据这个来判断用户是向哪滑动了,进而去响应事件
* */
//这样,我们规定,如果滑动的大小超过了100px,那么我们就让它滑向另外一个页面 如果scrollDistance大于0,那么走向左边的页面,否则滑向右边的页面,这个你可以自己动手试一试就理解了
int scrollDistance = (int) (endX - startX);
if(scrollDistance < 100){
startActivity(new Intent(MainActivity.this,SecondActivity.class));
//解释一下这个方法的意义,就是为上面的这两个Activity的切换提供的动画效果,左右滑动效果,如果有兴趣呢,可以看一下API,
//并且了解一下Android的坐标系
overridePendingTransition(R.anim.right_enter,R.anim.left_out);
}
return true;
}
});
//2、这么写,我猜是TouchEvent的接受事件的优先级较高,是不是这样呢?还没看过源码呢
@Override
public boolean onTouchEvent(MotionEvent event) {
//3、将事件传递给GestureDetector来处理掉
return mGestureDetector.onTouchEvent(event);
}
}
onScrollListener的使用
- 主要用在ListView的滑动中来控制滑动到哪啦,来决定是不是需要加载内容了,比如,eg:你的user已经滑动到了最后一个条目,那么你是不是需要从网络去获取数据了?那么你就要判断是不是滑动到最后一行了,那么下面这些代码就能解决
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//firstVisibleItem代表当前页可见的第一个item的index,visibleItemCount代表每页的条目数
//totalItemCount就是ListView中的所有的条目数
if(firstVisibleItem + visibleItemCount == totalItemCount){
Toast.makeText(MainActivity.this, "滑到底了", Toast.LENGTH_SHORT).show();
}
}
});
还差一个动作监听了,晚上就搞完了
- VelocityTracker的使用 没感觉有啥作用,是从onScroll里面分离出来的?(>﹏<) 下面看代码
//1、获取VelocityTracker的实例
VelocityTracker obtain = VelocityTracker.obtain();
//2.将事件交给VelocityTracker处理
obtain.addMovement(event);
//3.添加计算 第一个参数需要说明一下 1 代表 每微秒滑动多少px,1000代表每秒滑动多少像素 参数2代表最大速度
obtain.computeCurrentVelocity(1000,1000);
float xVelocity = obtain.getXVelocity();
Log.i(TAG,"mVelocityTracker : " +xVelocity);
ListView的定制
- 具有弹性的ListView
- 说一下我自己对这个定制的体会哈,总感觉这个东西不如Google官方给出的ListView有感觉,一味的模仿总不是那么好吧,不管怎样还是要给出这个代码,据作者医生说这样是为了给读者一个思路去查看源码
1、继承ListView重写overScrollBy()方法
- 说一下我自己对这个定制的体会哈,总感觉这个东西不如Google官方给出的ListView有感觉,一味的模仿总不是那么好吧,不管怎样还是要给出这个代码,据作者医生说这样是为了给读者一个思路去查看源码
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, 200, isTouchEvent);
}
这里有一点尴尬了,一共三个知识点 onTouchEvent ToolBar ObjectAnimator 好像我只会一项哎,有的受了~
累死累活知识点找全了
1、ToolBar 这个是Google为了那个材料设计弄出来的好像,targetSdkVersion好像要调到21以上哎,不然不清楚,用了一下感觉比Appbar好看,需要的就是在你的module的gradle里面的dependencies加上下面这行代码compile 'com.android.support:appcompat-v7:25.3.0'
使用v7包里面的,与前面版本兼容,
- 使用方法
1、和其他的widget一样,可以使用Java和XML引入,不贴代码了就
2、主要是在java代码中为ToolBar引入各种属性,像菜单
//这个控制这菜单选项是否显示 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.demo,menu); return true; }
- 使用方法
2、ObjectAnimator 这个是属性动画,更细致的没有找到,只找到了用法
translationY = ObjectAnimator.ofFloat(toolbar, "TranslationY", -150);
* 你没看错,这个是没办法实例化的一个类,要通过ofXXX的形式获取,解释一下这个XXX代表int,float等类型,主要是指后面写的那个值的类型,就像上面的-150 * 参数一是要执行动画的widget,参数二执行的动画名称,这个自己搜吧, * Animator和Animation之间的区别,就是Animation是不会真正的移动位置的,只是视觉上面的错觉,但是Animator是真正移动了位置
- OK,下面我们来看这个代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); //这里我是用XML形式声明的,那么从这里获取 setSupportActionBar(toolbar); //这个很重要,不然不会显示的,这个也是和其他的widget的区别了 toolbar.setLogo(R.mipmap.ic_launcher); //设置LOGO,显示在左上角,还有很多自己尝试吧 initAnimation(); } private void initAnimation() { translationY = ObjectAnimator.ofFloat(toolbar, "TranslationY", -150); translationY.setDuration(500); } @Override public boolean onTouchEvent(MotionEvent event) { //这个主要是进行简单的手势的判断了 switch (event.getAction()){ case MotionEvent.ACTION_DOWN : mLastY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE : int newY = (int) event.getY(); if(newY - mLastY > 0){ translationY.start(); //满足条件就执行动画吧 } mLastY = newY; break; case MotionEvent.ACTION_UP : break; } return true; }
- ListView的一个重要知识点,在ListView中显示多种条目,单纯的ListView只能显示一类widget组成的列表