文章目录
源码地址
view滑动的6种方法
layout(), offsetLeftAndRight()与offsetTopAndBottom(), LayoutParams, 动画, scollTo 与 scollBy以及Scroller。
layout()
自定义view
/**
* Created by ck on 2019/3/21.
*/
public class MyCustomView extends View {
private float x;
private float y;
public MyCustomView(Context context) {
super(context);
}
public MyCustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//获取触摸点的横纵坐标
x = event.getX();
y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
int dx = (int) (x1 - x);
int dy = (int) (y1 - y);
layout(getLeft() + dx,getTop() + dy,getRight() + dx,getBottom() + dy);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
xml中使用
<?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="match_parent"
android:layout_height="match_parent"
tools:context="com.test.ck.viewslide.MainActivity">
<com.test.ck.viewslide.MyCustomView
android:layout_width="100dp"
android:layout_height="80dp"
android:background="@color/colorAccent"/>
</LinearLayout>
offsetLeftAndRight()与offsetTopAndBottom()
offsetLeftAndRight()与offsetTopAndBottom()的使用和layout()方法几乎没有区别,用这2个方法取代layout方法即可
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//获取触摸点的横纵坐标
x = event.getX();
y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
int dx = (int) (x1 - x);
int dy = (int) (y1 - y);
offsetLeftAndRight(dx);
offsetTopAndBottom(dy);
// layout(getLeft() + dx,getTop() + dy,getRight() + dx,getBottom() + dy);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
LayoutParams
将onTouchEvent方法下 case MotionEvent.ACTION_MOVE内的代码替换如下
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
int dx = (int) (x1 - x);
int dy = (int) (y1 - y);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + dx;
layoutParams.topMargin = getTop() + dy;
setLayoutParams(layoutParams);
break;
此处使用LinearLayout.LayoutParams是因为其父布局是LinearLayout.除此之外还可使用ViewGroup.MarginLayoutParams
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + dx;
layoutParams.topMargin = getTop() + dy;
setLayoutParams(layoutParams);
动画(此次不做说明,会在以后再写)
scollTo 与 scollBy
scrollTo(x,y)表示移动到一个具体的坐标点,而scrollBy(dx,dy)则表示移动的增量为dx、dy.scrollBy(dx,dy)方法最终还是调用的scrollTo(x,y)
scrollTo(x,y)和scrollBy(dx,dy)方法源码:
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
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();
}
}
}
scollTo 与 scollBy的使用
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
int dx = (int) (x1 - x);
int dy = (int) (y1 - y);
// scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View
// dx,dy必须是负的
((View)getParent()).scrollBy(-dx,-dy);
break;
Scroller
Scroller本身是不能实现View的滑动的,它需要与View的computeScroll()方法配合才能实现弹性滑动的效果
点击button实现滑动效果(scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View)
自定义view
/**
* Created by ck on 2019/3/21.
*/
public class MyCustomView extends View {
private float x;
private float y;
private Scroller scroller;
public MyCustomView(Context context) {
super(context);
}
public MyCustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//初始化Scroller
scroller = new Scroller(context);
}
public void smoothTo(int x1,int y1) {
int scrollX = getScrollX();
int scrollY = getScrollY();
int disX = x1 - scrollX;
int disY = y1 - scrollY;
scroller.startScroll(scrollX,scrollY,disX,disY,2000);
invalidate();
}
/**
* 此方法会在onDraw()方法中调用
*/
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()){
//scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View
((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
invalidate();
}
}
}
activity内的调用
public class MainActivity extends AppCompatActivity {
private MyCustomView myCustomView;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myCustomView = (MyCustomView) findViewById(R.id.myCustomView);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//x轴向右移动100,y轴向下移动100
myCustomView.smoothTo(-100,-100);
}
});
}
}