HorizontalScrollView 的无限平滑 scrollX
Infinite smooth scrollX for HorizontalScrollView
您将如何实现从左到右(反之亦然)的无限平滑水平滚动?
HorizontalScrollView
只包含一个 TextView
元素,里面有很长的文本,因此我想滚动该文本而不是用户。
我发现 ObjectAnimator
是实现平滑滚动的唯一方法。现在的问题是正确地循环它。我找到了两个接近的解决方案,尽管它们没有按预期工作:
使用CycleInterpolator()
。无法实现流畅的行为:
ObjectAnimator animRight = ObjectAnimator.ofInt(hScrollVIew, "scrollX", hScrollVIew.getRight());
animRight.setRepeatCount(ValueAnimator.INFINITE);
animRight.setInterpolator(new CycleInterpolator(1f));
animRight.setDuration(4000);
animRight.setStartDelay(0);
animRight.start();
创建 2 个动画(左和右),它们会一个接一个地调用。此解决方案在第一个动画后有奇怪的延迟效果。
final ObjectAnimator animRight = ObjectAnimator.ofInt(hScrollVIew, "scrollX", holder.hsvTitleHolder.getRight());
animRight.setDuration(SCROLL_DURATION);
final ObjectAnimator animLeft = ObjectAnimator.ofInt(hScrollVIew, "scrollX", 0);
animLeft.setDuration(SCROLL_DURATION);
animRight.addListener(new Animator.AnimatorListener() {
Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
hScrollVIew.clearAnimation();
animLeft.start();
}
@Override
public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
});
animLeft.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
hScrollVIew.clearAnimation();
animRight.start();
}
@Override
public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
});
animRight.start();
如果有人遇到类似问题,请分享您的经验。
使用这样的代码:
final HorizontalScrollView hsv = new HorizontalScrollView(this);
final TextView tv = new TextView(this);
tv.setTextSize(48);
tv.setText("Our evil heaven for living is to yearn others agreeable.");
hsv.addView(tv);
setContentView(hsv);
View.OnClickListener ocl = new View.OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator animRight = ObjectAnimator.ofInt(hsv, "scrollX", 0, tv.getWidth() - hsv.getWidth());
animRight.setRepeatCount(3);
// you could use CycleInterpolator(0.5f) but the
// effect with CycleInterpolator is not so smooth
// so use that custom Interpolator
animRight.setInterpolator(new Interpolator() {
@Override
public float getInterpolation(float input) {
return (float) Math.pow(Math.sin(Math.PI * input), 2);
// you could also use similar interpolation:
// return (float) (1 - Math.cos(2 * Math.PI * input)) / 2;
}
});
animRight.setDuration(4000);
animRight.start();
}
};
tv.setOnClickListener(ocl);
您将如何实现从左到右(反之亦然)的无限平滑水平滚动?
HorizontalScrollView
只包含一个 TextView
元素,里面有很长的文本,因此我想滚动该文本而不是用户。
我发现 ObjectAnimator
是实现平滑滚动的唯一方法。现在的问题是正确地循环它。我找到了两个接近的解决方案,尽管它们没有按预期工作:
使用
CycleInterpolator()
。无法实现流畅的行为:ObjectAnimator animRight = ObjectAnimator.ofInt(hScrollVIew, "scrollX", hScrollVIew.getRight()); animRight.setRepeatCount(ValueAnimator.INFINITE); animRight.setInterpolator(new CycleInterpolator(1f)); animRight.setDuration(4000); animRight.setStartDelay(0); animRight.start();
创建 2 个动画(左和右),它们会一个接一个地调用。此解决方案在第一个动画后有奇怪的延迟效果。
final ObjectAnimator animRight = ObjectAnimator.ofInt(hScrollVIew, "scrollX", holder.hsvTitleHolder.getRight()); animRight.setDuration(SCROLL_DURATION); final ObjectAnimator animLeft = ObjectAnimator.ofInt(hScrollVIew, "scrollX", 0); animLeft.setDuration(SCROLL_DURATION); animRight.addListener(new Animator.AnimatorListener() { Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { hScrollVIew.clearAnimation(); animLeft.start(); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); animLeft.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { hScrollVIew.clearAnimation(); animRight.start(); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); animRight.start();
如果有人遇到类似问题,请分享您的经验。
使用这样的代码:
final HorizontalScrollView hsv = new HorizontalScrollView(this);
final TextView tv = new TextView(this);
tv.setTextSize(48);
tv.setText("Our evil heaven for living is to yearn others agreeable.");
hsv.addView(tv);
setContentView(hsv);
View.OnClickListener ocl = new View.OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator animRight = ObjectAnimator.ofInt(hsv, "scrollX", 0, tv.getWidth() - hsv.getWidth());
animRight.setRepeatCount(3);
// you could use CycleInterpolator(0.5f) but the
// effect with CycleInterpolator is not so smooth
// so use that custom Interpolator
animRight.setInterpolator(new Interpolator() {
@Override
public float getInterpolation(float input) {
return (float) Math.pow(Math.sin(Math.PI * input), 2);
// you could also use similar interpolation:
// return (float) (1 - Math.cos(2 * Math.PI * input)) / 2;
}
});
animRight.setDuration(4000);
animRight.start();
}
};
tv.setOnClickListener(ocl);