View的滑动原理和多种滑动方法
2024-10-07 22:56:16
参考链接:
http://blog.csdn.net/chunqiuwei/article/details/50679568#
http://blog.csdn.net/zly921112/article/details/50436538
view滑动种类:
1.根据layout()方法来产生滑动
xml代码 (下面的布局也是这个一样的)
<?xml version="1.0" encoding="utf-8"?> <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="vertical"
tools:context=".MainActivity"> <study.view.com.viewstudy.DragView
android:id="@+id/dv"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#000" /> </LinearLayout>
java部分(包含计算出偏移量)
1 package study.view.com.viewstudy;
2
3 import android.content.Context;
4 import android.util.AttributeSet;
5 import android.view.MotionEvent;
6 import android.view.View;
7
8
9 public class DragView extends View {
10
11
12 public DragView(Context context) {
13 this(context, null);
14 }
15
16 public DragView(Context context, AttributeSet attrs) {
17 this(context, attrs, 0);
18 }
19
20 public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
21 super(context, attrs, defStyleAttr);
22 init(context);
23 }
24
25 private void init(Context context) {
26 }
27
28
29 private int startX;
30 private int startY;
31
32 @Override
33 public boolean onTouchEvent(MotionEvent event) {
34 int x = (int) event.getX();//表示相对于当前View的x
35 int y = (int) event.getY();//表示相对于当前View的y
36 switch (event.getAction()) {
37 /**
38 *
39 MotionEvent中的方法
40 getX()获取点击位置距离当前View左边的距离
41 getY()获取点击位置距离当前View上边的距离
42 getRawX()获取点击位置距离屏幕左边的距离
43 getRawY()获取点击位置距离屏幕上边的距离
44 */
45 case MotionEvent.ACTION_DOWN:
46 startX = x;
47 startY = y;
48 break;
49 case MotionEvent.ACTION_MOVE:
50 int distanceX = x - startX;
51 int distanceY = y - startY;
52 /**
53 layout()中的方法
54 getTop()获取到的是View自身顶边到父布局顶边的距离
55 getBottom()获取到的是View自身底边到父布局顶边的距离
56 getLeft()获取到的是View自身左边到父布局左边的距离
57 getRight()获取到的是View自身右边到父布局左边的距离
58 */
59 layout(
60 getLeft()+distanceX,
61 getTop()+distanceY,
62 getRight()+distanceX,
63 getBottom()+distanceY
64 );
65 break;
66 case MotionEvent.ACTION_UP:
67
68
69 break;
70 }
71 return true;
72 }
73
74
75 }
2.offsetLeftAndRight(),offsetTopAndBottom()实现
计算出偏移量后只需要下面代码即可
offsetLeftAndRight(distanceX);
offsetTopAndBottom(distanceY);
3.view本身是不滑动的,滑动的是view的内容。view利用其view类内自带的方法scrollTo和ScrollBy来实现滑动
scrollTo()移动到某点,scrollBy()移动的偏移量 (把View位置看成固定的,内容移动,并且他的坐标系正好跟我们平时的坐标系相反)
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
//记录滑动的位置
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
} public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
java部分
package study.view.com.viewstudy; import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; public class DragView extends View { public DragView(Context context) {
this(context, null);
} public DragView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
} private void init(Context context) {
} private int startX;
private int startY; @Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();//表示相对于当前View的x
int y = (int) event.getY();//表示相对于当前View的y
switch (event.getAction()) {
/**
*
MotionEvent中的方法
getX()获取点击位置距离当前View左边的距离
getY()获取点击位置距离当前View上边的距离
getRawX()获取点击位置距离屏幕左边的距离
getRawY()获取点击位置距离屏幕上边的距离
*/
case MotionEvent.ACTION_DOWN:
startX = x;
startY = y;
break;
case MotionEvent.ACTION_MOVE:
int distanceX = x - startX;
int distanceY = y - startY;
//修改的地方
((View)getParent()).scrollBy(-distanceX,-distanceY);
break;
case MotionEvent.ACTION_UP: break;
}
return true;
} }
4.利用动画,让view产生滑动效果
java代码部分
package study.view.com.viewstudy; import android.animation.ObjectAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button bt = (Button) findViewById(R.id.bt);
final TextView tv = (TextView) findViewById(R.id.tv);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv,"translationX",300);
objectAnimator.setDuration(2000).start(); }
});
}
}
xml部分
<?xml version="1.0" encoding="utf-8"?>
<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:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity"> <TextView
android:id="@+id/tv"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#f00" /> <Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我" /> </LinearLayout>
5.通过动态的修改LayoutParams的margin等属性让View来产生滑动
计算出偏移量(下面有计算代码)
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
lp.topMargin = getTop()+distanceY;
lp.leftMargin = getLeft() + distanceX;
setLayoutParams(lp);
6.Scroller实现(Scroller是将一次较长的滑动,按一定时间分成多次较小的滑动实现视觉上的弹性滑动)
基于上面代码
package study.view.com.viewstudy; import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;
import android.widget.TextView; @SuppressLint("AppCompatCustomView")
public class DragView extends TextView { private Scroller scroller; public DragView(Context context) {
this(context, null);
} public DragView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
} private void init(Context context) {
scroller = new Scroller(context);
} @Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset()){
((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
invalidate();//这里不断的递归修改坐标形成视觉上的弹性滑动
}
} private int startX;
private int startY; @Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();//表示相对于当前view的x
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = x;
startY = y;
break;
case MotionEvent.ACTION_MOVE:
int distanceX = x - startX;
int distanceY = y - startY;
((View)getParent()).scrollBy(-distanceX, -distanceY); break;
case MotionEvent.ACTION_UP:
View parent = (View) getParent();
scroller.startScroll(
parent.getScrollX(),
parent.getScrollY(),
-parent.getScrollX(),
-parent.getScrollY());
invalidate();//这里调用了就会触发ondraw()然后会调用computeScroll()方法
break;
}
return true;
} }
最新文章
- 局部打印插件 jquery.PrintArea.js
- php学习笔记-基础篇
- golang自动导入postgresql脚本
- JSON 之 SuperObject(3): 访问
- LeetCode 152
- 在php添加mongo过程中出现的mongo.so: >; undefined symbol: php_json_encode in Unknown on line 0. After installation mongo driver for php 的错误
- AspNet Core :创建自定义 EF Core 链接数据库
- 青否云 - 小程序待办事项 wxapp开源系统
- Map value类型不同的写法
- MySQL_关于索引空间的的一些记录
- 二十:让行内元素在div中垂直居中
- 四十二、Linux 线程——线程同步之条件变量之线程状态转换
- 用Eclipse导入Maven工程
- JavaScript与正则表达式
- .NET 用 Unity 依赖注入&mdash;&mdash;概述注册和解析类型(1)
- touch修改文件时间戳
- hdu-1036(格式题+精确度)
- android中RecyclerView控件实现瀑布流布局
- Javascript 思维导图 绘制基础内容(值得一看)
- SSH 反向代理