我有一个内部有一些图像的线性布局(添加了这些图像 动态地使布局的宽度不时变化,
我想要 这个布局像从左到右的选框一样动画(我不能 将textview与marquee一起使用,因为它不支持rtl)所以我 必须处理动画。 布局的宽度可能会改变所以我 无法为动画方法setDuration设置静态持续时间, 当我使用例如10000毫秒的持续时间有时它 移动太快,有时太慢(因为宽度变化)现在问题: 是否有一些自定义方法,例如setSpeed用于动画类? 我怎样才能实现这个目标?我希望这种布局能够以相同的速度为任何尺寸制作动画。
答案 0 :(得分:2)
您无法设置直接为视图设置动画的速度,但您可以对其进行操作以达到您想要的效果:
您可以将LinearInterpolator设置为动画,使其在整个动画中具有相同的常规速度,并实现一个侦听器,在onAnimationEnd中执行您想要的操作,,这里有一个棘手的部分:
速度规则是:Speed = Distance / Time
让我们在代码中逻辑地应用它。我们将考虑距离是图像的总宽度(或者您的父视图是线性布局)。然后将该宽度乘以1000以使持续时间以毫秒为单位,然后将结果除以您想要确定速度的任何内容。现在,无论图像的总宽度如何,您的动画速度都应该相同。
同样,您可以将图像的总宽度乘以10这样的常数。它将是相同的比率。
以下是在代码中完成的操作:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
int layoutWidth = linearLayout.getWidth();
int animationSpeed = (layoutWidth * 1000) / 100;
linearLayout.animate().translationX(layoutWidth).setDuration(animationSpeed).setInterpolator(new LinearInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
linearLayout.setVisibility(View.GONE);
}
});
如果你想让动画无限,你可以这样做:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
int layoutWidth = linearLayout.getWidth();
int animationSpeed = (layoutWidth * 1000) / 100;
final TranslateAnimation translateAnimation = new TranslateAnimation(0, layoutWidth, 0, 0);
translateAnimation.setInterpolator(new LinearInterpolator());
translateAnimation.setDuration(animationSpeed);
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
linearLayout.startAnimation(translateAnimation);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
linearLayout.startAnimation(translateAnimation);
答案 1 :(得分:0)
在打开我的Android Studio之前,一个简单的问题,在添加图片时,您的布局是否有必要更改其大小?您可以在布局外使用HorizontalScrollView来保持图像滚动而不更改布局大小,并使用scrollTo()或smoothScrollTo()滚动动态图像。或使用对象动画滚动静态视图,将图像添加到布局内。
更新1:
您需要计算动画期间布局的每单位移动的初始持续时间,然后每当您向布局添加新图像时,该持续时间/单位都可用于更改动画持续时间。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_test);
final LinearLayout ll=(LinearLayout)findViewById(R.id.scrollImages);
durationperunit = duration/ll.getLayoutParams().width; // duration per move. and this speed has to be maintained while adding images
duration= speedperunit* ll.getLayoutParams().width;
ll.animate().setDuration(duration);
ll.animate().xBy(ll.getWidth()).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
Rect rect = getDisplaySize();
LinearLayout ll = (LinearLayout) findViewById(R.id.scrollImages);
if (ll.getX()+ll.getWidth() <= rect.width()) {
direction = 0;
}
if (ll.getX() + ll.getWidth() >= rect.width()) {
direction = 1;
}
if (direction == 0) ll.animate().xBy(ll.getWidth());
else ll.animate().xBy(-ll.getWidth());
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat (Animator animation){
}
@Override
public void onAnimationStart (Animator animation){
}
});
}
现在,您知道在&#34; duration&#34;中进行布局单次移动所需的时间。每当布局宽度发生变化时,使用它来更新动画的setDuration()。请注意,当布局宽度增加时,动画持续时间必须增加。因此,在添加图像时,(您的布局宽度也会增加)代码必须类似于下面的内容,以及之前计算的&#34;每次移动的持续时间&#34;值。
/*within adding image function after layout width change*/
LinearLayout ll=(LinearLayout)findViewById(R.id.scrollImages);
// Now calculate new duration for new width of the layout. Assuming layout width changed already.
duration= durationperunit* ll.getLayoutParams().width;
// Set the newly calculated duration
ll.animate().setDuration(duration);