View的事件体系---V3.2 View的滑动
2016-04-14 23:32
309 查看
一、View的滑动一般通过以下三种方式实现:
a. 通过View本身提供的ScrollTo/ScrollBy方法
b. 通过动画给View施加平移效果来实现滑动
c. 通过改变View的LayoutParams参数使View重新布局来实现滑动效果
二、使用ScrollTo/ScrollBy
a. 这是View本身提供的实现滑动的方法
b. 通过对比源码发现,scrollBy也是调用了ScrollTo方法,实现了基于当前位置的相对滑动,scrollTo方法实现了基于所传递参数的绝对滑动
c. 在滑动过程中,mScrollX的值总是等于View左边缘和View内容左边缘在水平方向上的距离,mScrollY的值总是等于View上边缘和View内容上边缘在竖直方向上的距离。View的边缘指View的位置,有四个顶点组成,View内容的边缘是指View中的内容的边缘,scrollTo/scrollBy只能改变View内容的位置而不能改变View在布局中的位置
d. mScrollX mScrollY单位为像素,当View左边缘在View内容左边缘的右边时,mScrollX为正值,反之为负值。当View上边缘在View内容上边缘的下边时,mScrollY为正值,反之为负值。
e. 从左往右滑动,那么mScrollX为负值,反之为正值。当从上往下滑动时,mScrollY为负值,反之为正值。
三、使用动画
a. 使用动画是View进行滑动,主要对其translationX translationY两个属性进行修改,可以使用传统的View动画,也可以使用属性动画来完成
b. 采用View动画的话,可以通过anim文件,进行编写,如下
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="1000" android:fillAfter="true" android:fromXDelta="0" android:fromYDelta="0"
android:toXDelta="100" android:toYDelta="100" android:interpolator="@android:interpolator/accelerate_decelerate" /></set>
c. 属性动画,更为简洁,如下
ObjectAnimator.ofInt(parent,"translationX",0,100).setDuration(1000).start();
d. 传统View动画和属性动画是有区别的,传统的View动画只是从表象上吧View进行了移动,但其本质并没有发生位置改变,如果注册过onclick事件,会发现移动后View点击是无效的,而有效点仍然在原位置,而属性动画的出现,很好的解决了这一问题。
四、通过改变布局参数
a. 通过改变LayoutParams参数,也可以实现View的滑动,示例如下
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) name.getLayoutParams(); params.leftMargin+=150; params.rightMargin+=150; name.setLayoutParams(params);
五、三种方式对比
a. ScrollTo/ScrollBy:操作简单,适用于对View内容的滑动
b. 动画:操作简单,适用于没有交互的View和实现复杂的动画效果
c. 改变布局参数:操作稍微复杂,适用于有交互的View
完整代码如下:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.example.zhonglq.myapplication; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private TextView name; private RelativeLayout parent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); name = (TextView) this.findViewById(R.id.name); parent = (RelativeLayout) this.findViewById(R.id.parent); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); // 解决长按屏幕后无法拖动的现象 // gestureDetector.setIsLongpressEnabled(false); } public void move(View view){ Toast.makeText(this,"move",Toast.LENGTH_SHORT).show(); // ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) name.getLayoutParams(); // params.leftMargin+=150; // params.rightMargin+=150; // name.setLayoutParams(params); parent.scrollTo(-30, 30); ObjectAnimator.ofInt(parent,"translationX",0,100).setDuration(1000).start(); } GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() { /** * 手指轻轻触摸屏幕的一瞬间,1个Action_down触发 * @param e * @return */ @Override public boolean onDown(MotionEvent e) { return false; } /** * 手指轻轻触摸屏幕,尚未松开或拖动,由1个Action_down触发 * 与onDown相比,强调的是没有松开或者拖动的状态 * @param e */ @Override public void onShowPress(MotionEvent e) { } /** * 手指松开,伴随1个action_up * @param e * @return */ @Override public boolean onSingleTapUp(MotionEvent e) { return false; } /** * 手指按下屏幕并拖动,1个ACTION_DOWN N个ACTION_MOVE * @param e1 * @param e2 * @param distanceX * @param distanceY * @return */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } /** * 长按屏幕 * @param e */ @Override public void onLongPress(MotionEvent e) { } /** * 手指按下触摸屏,快速滑动后松开,强调的是快速滑动行为 * @param e1 * @param e2 * @param velocityX * @param velocityY * @return */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } }); GestureDetector.OnDoubleTapListener onDoubleTapListener = new GestureDetector.OnDoubleTapListener() { /** * 严格的单击行为 * 和onSingleTapUp的区别为,如果触发了onSingleTapConfirmed,那么后面不可能在紧跟着另外一个单击行为, * 这只可能是单击,而不是双击中的一次单击 * @param e * @return */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { return false; } /** * 双击 两次连续的单击构成,不可能和onSingleTapConfirmed并存 * @param e * @return */ @Override public boolean onDoubleTap(MotionEvent e) { return false; } /** * 表示发生了双击行为,在双击的期间,ACTION_DOWN ACTION_MOVE ACTION_UP都会触发此回调 * @param e * @return */ @Override public boolean onDoubleTapEvent(MotionEvent e) { return false; } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }</span>
相关文章推荐
- linux下编译下载的源代码
- React one-way flow
- Redundant Paths POJ, 3177
- 用VueJS+webpack+semantic-UI+Laravel开发单页应用
- 大数据的存储和读取
- PSobj [6] 调色之复古向
- 2.2.1 鸟哥的Linux学习之路
- Android概述
- 银行排队
- 【BFS】HDU1242Rescue
- Android笔记【4】--Android studio issue -->Plugin is too old 滚动显示效果
- 3D物体识别的假设检验
- Java 线程池
- 二次贝塞尔曲线的实现(基于Canvas与JavaScript)
- Jenkins创建slave节点----Windows平台
- 最大子数组
- Python gevent学习笔记-2
- R语言 小程序
- Android Studio内配置和使用OpenCV3.x(不依靠Manager)
- python请编写一个函数,它接受一个 list,然后把list中的所有字符串变成大写后返回