您的位置:首页 > 其它

Scroller实现View的滑动

2017-11-17 00:54 260 查看
弃用scrollBy的原因?

滑动时,是瞬间完成的,用户体验不佳(在手拖着移动的时候不会看出明显区别,如果有一段是自动完成的,scrollBy会瞬间完成,Scroller就平滑的多了)

这个弹性滑动又是怎么实现的呢?

Scroller本身不能实现弹性滑动,需要和View中的computeScroller()配合。

实现步骤:(也是用的自定义控件)

1.在构造方法中初始化Scroller对象

private Scroller mScroller;


public SlidingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);

mScroller = new Scroller(context);

}

2.重写View的computeScroller()方法

@Override
public void computeScroll() {
super.computeScroll();

if (mScroller.computeScrollOffset()) {

((View)getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();//View的刷新视图方法

}

}

3.我们写一个smoothScrollTo()方法,这里定义的操作是平移一段距离,2000是执行平移需要的时间

public void smoothScrollTo(int destX, int destY) {

int scrollX = getScrollX();
int delta = destX - scrollX;

mScroller.startScroll(scrollX, 0, delta, 0, 2000);

invalidate();

}

4.代码中使用

//6.这里调用
//mSlidingView.smoothScrollTo(-400, 0);


全部代码

自定义控件

public class SlidingView extends View {
public SlidingView(Context context) {
super(context);
}

public SlidingView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mScroller = new Scroller(context); }

public SlidingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

private int lastX;
private int lastY;

private Scroller mScroller;

@Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { ((View)getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate();//View的刷新视图方法 } }

public void smoothScrollTo(int destX, int destY) { int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0, 2000); invalidate(); }

public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getX();
int y = (int) event.getY();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

lastX = x;
lastY = y;

break;
case MotionEvent.ACTION_MOVE:

int offsetX = x - lastX;
int offsetY = y - lastY;

//1.layout
//getTop()就是顶部距离父容器顶部,
//getTop()就是底部距离父容器顶部
// layout(getLeft() + offsetX, getTop() + offsetY,
// getRight() + offsetX, getBottom() + offsetY);

//2.offsetLeftAndRight()
//类似方法1
// offsetLeftAndRight(offsetX);
// offsetTopAndBottom(offsetY);

//3.改变布局参数(1)LayoutParams(根据不同父布局选择),这里是ConstraintLayout
//(2)ViewGroup的MarginLayoutParams
//测试发现用不了
// ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams)
// getLayoutParams();
// ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)
// getLayoutParams();
// layoutParams.leftMargin = getLeft() + offsetX;
// layoutParams.topMargin = getTop() + offsetY;
// setLayoutParams(layoutParams);

//4.属性动画(相比普通动画,是真是移动了位置,而不是表象)
//不用在这里定义

//5.scrollTo,scrollBy
// ((View)getParent()).scrollBy(-offsetX, -offsetY);

//6.Scroller

break;
}
return true;
}
}

xml中引用自定义控件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.example.test.ViewTranslateActivity">

<com.example.test.widget.SlidingView
android:id="@+id/slidingView"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"/>

</android.support.constraint.ConstraintLayout>

使用

public class ViewTranslateActivity extends AppCompatActivity {

@BindView(R.id.slidingView)
SlidingView mSlidingView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_translate);
ButterKnife.bind(this);

//4(1).普通动画
// mSlidingView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
//4(2).属性动画
// ObjectAnimator.ofFloat(mSlidingView, "translationX", 0, 300).setDuration(1000).start();

//6.这里调用 //mSlidingView.smoothScrollTo(-400, 0);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: