在我的应用程序中,我有一个webview,允许用户通过滑动手势水平滚动。
我使用objectanimator为滚动设置动画,但即使使用简单的scrollTo(),问题仍然存在。
问题:当我到某个位置时使用:scrollTo(500,0);它经常会向一侧跳过一定数量的像素,就像100px的抖动一样。
如果我在第一次滑动完成后继续向右滑动,则错误不会发生并且它会按预期运行,但是当我停止滑动最后一次滑动的那一刻以随机抖动结束。
代码非常简单,基本上是:myView.scrollTo(X,Y)。我完全不知道为什么会这样。谁有类似的经历?
更新从touchevent中输入代码,一些已经过时的内容是繁琐的试错。
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(final MotionEvent event) {
if(swipeable && !animationRunning){
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
swipeStartPosition = event.getX();
break;
case MotionEvent.ACTION_MOVE:
// Nothing here, move along.
break;
case MotionEvent.ACTION_UP:
float swipeDistance = Math.abs(event.getX() - swipeStartPosition);
// Check if event is click or swipe.
// A swipe is hardcoded to a distance of 50px.
if (swipeDistance > 50) {
// Swipe.
if (event.getX() > swipeStartPosition) {
// Right swipe (previous).
// Don't swipe if you're on the first page.
if (targetPage == 0) {
Toast.makeText(getContext(), "No sections that way, try the other way.", Toast.LENGTH_SHORT).show();
} else {
prevPage = targetPage;
targetPage--;
//inform main activity about pagechange to update UI
mMainActivity.setTargetPage(prevPage, targetPage);
/*
mWebView.postDelayed( new Runnable () {
@Override
public void run() {
mWebView.scrollTo(2560, 0);
}
}, 3000);
*/
//scrollTo(2560, 0);//targetPage * pageWidth, 0);
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
objectAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animator arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator arg0) {
// TODO Auto-generated method stub
animationRunning = false;
}
@Override
public void onAnimationCancel(Animator arg0) {
// TODO Auto-generated method stub
}
});
objectAnimator.start();
}
} else {
// Left swipe (next).
if (computeHorizontalScrollRange() <= (computeHorizontalScrollOffset() + computeHorizontalScrollExtent())) {
Toast.makeText(getContext(), "No sections that way, try the other way.", Toast.LENGTH_SHORT).show();
} else {
prevPage = targetPage;
targetPage++;
mMainActivity.setTargetPage(prevPage, targetPage);
/*
mWebView.postDelayed( new Runnable () {
@Override
public void run() {
mWebView.scrollTo(5120, 0);
}
}, 3000);
*/
//scrollTo(5120, 0); //targetPage * pageWidth, 0);
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
objectAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animator arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator arg0) {
// TODO Auto-generated method stub
animationRunning = false;
}
@Override
public void onAnimationCancel(Animator arg0) {
// TODO Auto-generated method stub
}
});
objectAnimator.start();
}
}
} else {
// Click.
// Do nothing here.
}
// int pageWidth = getWidth();
//
// int targetPage = (int)Math.round( (pos + event.getX()) / (float)pageWidth );
//
//
// scrollTo(targetPage * pageWidth, 0);
break;
}
}
return super.onTouchEvent(event);
}
此外,正在发生的位移似乎与最初的touchevent本身绑定,而不是滚动。如果我执行以下操作并延迟3秒,我会看到在触摸事件后短时间内再次发生位移,但是当scrollTo()在3秒后触发时它会实际跳转到正确的位置:
mWebView.postDelayed( new Runnable () {
@Override
public void run() {
mWebView.scrollTo(2560, 0);
}
}, 3000);
这一切都令人费解......
答案 0 :(得分:0)
事实证明,在原始代码的某处,有些事搞砸了。 这是一个非常不同,更简单的例子,它完美地运作。
float x1,x2;
float y1,y2;
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
break;
case MotionEvent.ACTION_UP:
x2 = event.getX();
y2 = event.getY();
if(x1 < x2){
//left to right
prevPage = targetPage;
targetPage--;
Toast.makeText(getContext(), "left to right", Toast.LENGTH_SHORT).show();
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
objectAnimator.start();
}
if(x1 > x2){
//right to left
prevPage = targetPage;
targetPage++;
Toast.makeText(getContext(), "right to left", Toast.LENGTH_SHORT).show();
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
objectAnimator.start();
}
/*
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * displaymetrics.widthPixels)).setDuration(300);
objectAnimator.start();
*/
break;
}
return true;
}