I have a series of ImageViews
that I programatically added into a LinearLayout
, so they all end up horizontally lined up.
But when I try to use a TranslateAnimation
to move all the images at once, a 1 pixel white gap flashes between every ImageView
for about .02 seconds and then disappears. And this seems to consistently happen every 2 seconds or so.
TranslateAnimation moveLeft = new TranslateAnimation(0, -1250, 0, 0);
moveLeft.setDuration(10000);
moveLeft.setFillAfter(true);
I make my ImageViews
all at the same time before I move them. (Also, the ImageViews
have all default settings) I've also confirmed that there are no white gaps between the ImageViews
before I move them.
The flickering only happens when I set all the ImageViews
's animations to moveLeft
.
Also, here is the class in question :
public class Terrain {
Bitmap tile;
InputStream is;
ImageView imageViewPlatform;
Drawable tileDrawable;
ArrayList<ImageView> terrainArray = new ArrayList<ImageView>();
ArrayList<TranslateAnimation> moveLeftArray = new ArrayList<TranslateAnimation>();
int count = 0;
int terrainBlockNumber = 0;
boolean initialized = false;
TranslateAnimation moveLeft;
public void initialize(Activity activity){
is = activity.getResources().openRawResource(+R.drawable.game_tile);
tile = BitmapFactory.decodeStream(is);
tileDrawable = new BitmapDrawable(activity.getResources(), tile);
moveLeft = new TranslateAnimation(0, -1250, 0, 0);
moveLeft.setDuration(10000);
moveLeft.setFillAfter(true);
initialized = true;
Log.d("Terrain", "Terrain images are initialized.");
}
public void draw(Activity activity, LinearLayout linearLayout,
LinearLayout.LayoutParams layoutParams) {
if (!initialized) {
throw new RuntimeException("initialize() method must " +
"be called before the draw() method.");
}else{
terrainArray.add(new ImageView(activity));
++count;
terrainArray.get(count-1).setImageDrawable(tileDrawable);
linearLayout.addView(terrainArray.get(count-1), layoutParams);
}
}
public void move(Activity activity) {
terrainBlockNumber++;
final int terrainAnimationBlock = terrainBlockNumber;
moveLeft.setAnimationListener(new Animation.AnimationListener() {
int currentCount = terrainAnimationBlock;
@Override
public void onAnimationStart(Animation animation) {
Log.d("Animation Started", "Block Number is " + currentCount);
}
@Override
public void onAnimationEnd(Animation animation) {
terrainArray.get(currentCount - 1).setVisibility(View.GONE);
Log.d("Terrain Deletion", "Block number " +
currentCount + " has been deleted.");
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
terrainArray.get(terrainBlockNumber - 1).startAnimation(moveLeft);
}
}
}
This is the XML file for the activity
<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="com.example.project.PlayActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout"
android:weightSum="1"
android:layout_alignParentTop="true"
android:layout_marginTop="200dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</LinearLayout>
</RelativeLayout>
UPDATE :
Moving the entire LinearLayout
does not seem to work either. Although, moving the entire LinearLayout
isn't really helpful. It cuts off ImageViews
that are off-screen.
But since you requested it, all I did was change the move method to :
public void move(LinearLayout linearLayout){
linearLayout.setAnimation(moveLeft);
}
All the images did actually move at the same speed, and there is still the flickering between the images.
UPDATE 2
I have confirmed that it has something to do with my images/how they're formatted/the size of the images or something along those lines. If it is any help, the image I use is 95 X 84 pixels. (It's really tiny)
答案 0 :(得分:0)
Try to put the ImageView
s in a LinearLayout
or other ViewGroup
and animate the entire ViewGroup
and see if that helps.
答案 1 :(得分:0)
如果您有多张图片,可能需要:
使用RecyclerView。这使您可以更好地控制动画和装饰,并同时优化内存使用。 This answer将帮助您了解如何制作动画。
确保您不会不断调整图片大小。如果动画需要处理原本太大的图像,则可能会影响动画的质量(即使用缩略图和固定大小以避免代价高昂的计算)
例如,如果您的原始图像为600x800,但您的图像为
视图有一个centerCrop / fit / etc最终占用200x200的空间,
android将进行大量调整以匹配这些设置。该
它做的计算越多,你失去的机会就越多
帧。换句话说:你所经历的是低帧率,
当android无法完成所有绘图时发生这种情况
下次屏幕刷新的时间计算。
你可以攻击不同的问题:
使用正确的图像尺寸减少计算
较小的图像也意味着更少的内存使用量,这减少了内存重新分配或强制垃圾收集的需要。
避免计算/渲染不可见的东西。要么因为它们不在屏幕之外,要么是因为某些东西与它们重叠。在您的情况下,回收者视图可能有助于仅加载可见屏幕上的图像,而不是浪费空间和计算在目前看不见的图像上。
减少布局重写。 Android尝试仅渲染具有更新的部分,而不是重新渲染所有屏幕。但是,如果您的布局强制其他布局重新计算其大小,则最终可能会强制执行整个调整大小。在您的情况下,不使用LinearLayout
列出图片。相反,使用一些实际上为这类事物设计的布局。正如我所说,RecyclerView
默认LinearLayoutManager
的效果非常好。