如何在安卓系统中使ImageView左右平滑滑动?

20

我需要使一个ImageView在屏幕上从左向右滑动并带有平滑的动画(我希望在过渡期间ImageView可见)。我尝试了以下代码:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;

camion.animate()
    .translationX(width)
    .setDuration(2000)
    .setInterpolator(new LinearInterpolator())
    .setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            //camion.setVisibility(View.GONE);
        }
    });

ImageView 移动起来不流畅,动画效果也不如我所希望的那样。 我在代码上做错了什么?


请查看此答案:https://dev59.com/1mnWa4cB1Zd3GeqP4dXd#12999391 - Zied R.
@ZiedRebhi 我尝试了这个例子,但动画仍然很卡顿。 - LS_
你好奇地问一下,你是在什么设备上进行测试?或者你是在模拟器上测试呢? - Dom
@Dom 我正在使用安卓 L 版本的 Moto G 2014 进行测试。 - LS_
8个回答

45

创建这种类型的补间动画很简单。只需按照以下步骤操作:

第一步

res目录内创建一个名为anim的文件夹,并将此文件命名为slide.xml

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fillAfter="true">

   <translate
        android:fromXDelta="0%p"
        android:toXDelta="75%p"
        android:duration="800" />
</set>

您可以通过更改fromXDeltatoXDelta这两个属性来自定义动画。 %p是相对于父元素而言的意思,它表示将图像移动75%相对于其父元素。

步骤2

// Refer the ImageView like this
imageView = (ImageView) findViewById(R.id.img);

// Load the animation like this
animSlide = AnimationUtils.loadAnimation(getApplicationContext(),
                    R.anim.slide);

// Start the animation like this
imageView.startAnimation(animSlide);

如果需要的话,你也可以使用setInterpolator()setListeners()。我没有在此处展示它们,以保持简单。如果需要,请告诉我。

注意

正如你一再提到的那样,你遇到了卡顿的动画。我在3台真实设备和2个模拟器上测试了这个动画,所有设备都很流畅。这些测试包括像Moto E这样的低端设备,以及Nexus 5和Galaxy S6等高端设备。

如果您仍然在运行此代码时遇到延迟,则测试设备必须是原因。代码完美无缺。

更新

我刚刚在我的Moto G上运行了Lollipop系统,动画非常流畅。这是一个非常小而轻巧的动画,绝不会有任何延迟。如果您仍在遇到延迟,那么可能是您正在测试的设备,或者是Activity上的其他代码使UI变慢或无响应。尝试确定哪种情况适用于您:

  • 我现在已经在6台设备上进行了测试,没有任何延迟。因此,您可以放心地相信,您的生产应用程序不会有任何卡顿,可能是您的设备太慢了。
  • 如果您正在执行某些重操作,例如访问文件系统、数据库或任何其他重操作,则可能会减缓UI线程,导致丢帧。尝试使用AsyncTask来处理这些重操作。

1
问题是背景图片太大,需要大量的CPU来渲染,我已经缩小了它的大小,现在一切正常了。非常感谢您的答复!我会尽快给你悬赏。 - LS_
1
很高兴知道现在它正常工作了。我也花了很多时间为你在许多设备上进行测试。希望你能接受答案并奖励赏金。谢谢。 - Aritra Roy
@Signo,是否可以接受答案并颁发悬赏?我也刚刚给你的问题点了赞。 - Aritra Roy
1
@Signo 我能理解。这一点问题都没有。如果您能分配赏金,那就太好了。谢谢。 - Aritra Roy
1
非常流畅,加一。 - BradleyIW
显示剩余3条评论

6
TranslateAnimation animate = new TranslateAnimation(0, -view.getWidth(), 0, 0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);

6

试试这个。它会使图片视图动起来。

        ImageView img_animation = (ImageView) findViewById(R.id.img_animation);
        Display display = getWindowManager().getDefaultDisplay();
        float width = display.getWidth();
        TranslateAnimation animation = new TranslateAnimation(0, width - 50, 0, 0); // new TranslateAnimation(xFrom,xTo, yFrom,yTo)
        animation.setDuration(1000); // animation duration
        animation.setRepeatCount(5); // animation repeat count
        animation.setRepeatMode(2); // repeat animation (left to right, right to
                                    // left )
        // animation.setFillAfter(true);

        img_animation.startAnimation(animation); // start animation

1
我已经尝试过这个解决方案(我在一个旧的SO问题中找到了它),但即使使用这种方法,动画仍然很卡顿。 - LS_
好的,我正在尝试为您完成这个任务。在等待更多答案之前,请稍等。 - Gopal Singh Sirvi
请看这个链接:https://dev59.com/LGzXa4cB1Zd3GeqPPQuy - Gopal Singh Sirvi
1
嗯,我不认为他们想通过观察小提琴来实现这一点。我尝试了这种方法,但它会缩放图像。 - LS_

3
希望这对您有用。
动画.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Animation" >

    <ImageView
        android:id="@+id/img_animation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="42dp"
        android:src="@drawable/emo_im_laughing" />

</RelativeLayout>

Animation.java

import android.os.Bundle;
import android.app.Activity;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

public class Animation extends Activity {

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

  ImageView img_animation = (ImageView) findViewById(R.id.img_animation);

  TranslateAnimation animation = new TranslateAnimation(0.0f, 400.0f,
    0.0f, 0.0f);
  animation.setDuration(5000);
  animation.setRepeatCount(5);
  animation.setRepeatMode(2);
  animation.setFillAfter(true);
  img_animation.startAnimation(animation);

 }
}

如何在翻译动画结束后获取视图的当前位置? - Akash Attal

3
请尝试下面的代码:
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 1500.0f); // new TranslateAnimation (float fromXDelta,float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(2000); // animation duration
animation.setRepeatCount(1); // animation repeat count if u repeat only once set to 1 if u don't repeat set to 0
animation.setFillAfter(false);
your_view .startAnimation(animation);//your_view for mine is imageView  

如何在平移动画结束后获取视图的当前位置? - Akash Attal

1
public class MainActivity extends Activity {

       int windowwidth;
       int windowheight;

       private LayoutParams layoutParams;

       @Override
       public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);

              windowwidth = getWindowManager().getDefaultDisplay().getWidth();
              windowheight = getWindowManager().getDefaultDisplay().getHeight();
              final ImageView img = (ImageView) findViewById(R.id.imageView1);

              img.setOnTouchListener(new View.OnTouchListener() {

                     @Override
                     public boolean onTouch(View v, MotionEvent event) {
                           LayoutParams layoutParams = (LayoutParams) img
                                         .getLayoutParams();
                           switch (event.getAction()) {
                           case MotionEvent.ACTION_DOWN:
                                  break;
                           case MotionEvent.ACTION_MOVE:
                                  int x_cord = (int) event.getRawX();
                                  int y_cord = (int) event.getRawY();

                                  if (x_cord > windowwidth) {
                                         x_cord = windowwidth;
                                  }
                                  if (y_cord > windowheight) {
                                         y_cord = windowheight;
                                  }

                                  layoutParams.leftMargin = x_cord - 25;
                                  layoutParams.topMargin = y_cord - 75;

                                  img.setLayoutParams(layoutParams);
                                  break;
                           default:
                                  break;
                           }
                           return true;
                     }
              });
       }
}

1
这个问题已经有几个答案了,其中一个已经被接受。你可能想编辑你的答案,解释它与其他答案的不同之处以及它的优点。 - Blackwood

0
现在我们有MotionLayout,可以尝试使用它来实现非常干净和流畅的滑动动画。

0

使用 @Aritra Roy 的答案,将 imageview右到左移动。

使用以下代码:

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fillAfter="true">

    <translate
        android:fromXDelta="75%p"
        android:toXDelta="0%p"
        android:duration="100000" />
</set>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接