5

我想使用动画显示ImageViewsGridView我可以显示它们并正确应用动画。

但问题是,如果我在 ImageView1 上应用动画,然后在 ImageView2 上应用动画(在 ImageView1 上的动画结束之前),那么 ImageView1 上的动画会被中断,并且 ImageView1 直接设置为最终状态。

请注意,我使用ThreadPoolExecutor2 个线程下载图像。每当图像下载完成时,我都会调用addImage(image)下面的方法,ImageAdapter然后依次添加图像GridViewGridView刷新以显示最新的图像集。在这里,在渲染时,新图像会显示动画,这个动画(我猜)会中断当前动画图像的动画。

图像适配器:

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private List<Bitmap> images;
    private ArrayList<Integer> colors;
    private boolean[] alreadyLoadedIndexes;
    Animation animation;
    AnimatorSet animator;

    public void addImage(Bitmap img) {
        images.add(img);
        notifyDataSetChanged();
    }

    public void setAnimation(Animation animation) {
        this.animator = null;
        this.animation = animation;
    }

    public void setAnimator(AnimatorSet animation) {
        this.animation = null;
        this.animator = animation;
    }

    public void resetImages() {
        images.clear();
        notifyDataSetChanged();
        alreadyLoadedIndexes = null;
        alreadyLoadedIndexes = new boolean[20];
    }

    // Constructor
    public ImageAdapter(Context c) {
        mContext = c;
        images = new ArrayList<Bitmap>();
        colors = new ArrayList<Integer>();
        colors.add(Color.CYAN);
        colors.add(Color.BLUE);
        colors.add(Color.GRAY);
        colors.add(Color.YELLOW);
        colors.add(Color.MAGENTA);
        alreadyLoadedIndexes = new boolean[20];
    }

    @Override
    public int getCount() {
        return 20;
    }

    @Override
    public Object getItem(int position) {
        return 20;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(mContext);

        imageView
                .setBackgroundColor(colors.get((int) ((Math.sqrt(position) + 2 * position) % 5)));

        // If image at index 'position' is available
        if (images.size() > position) {

            // If loading this image first time then only apply animation
            if (!alreadyLoadedIndexes[position]) {

                // If animation is specified
                if (this.animation != null) {
                    imageView.setImageBitmap(images.get(position));
                    imageView.startAnimation(animation);

                }
                // If animator set is specified
                else if (this.animator != null) {
                    imageView.setImageBitmap(null);
                    imageView.setBackgroundColor(colors.get((int) ((Math
                            .sqrt(position) + 2 * position) % 5)));
                    animator.setTarget(imageView);
                    animator.start();
                    Log.e("", "setting image after " + animator.getDuration()
                            / 2);
                    new Handler().postDelayed(
                            new runnable(imageView, images.get(position)), 500);

                } else {
                    // Use default animation if nothing is specified.
                    imageView.setImageBitmap(images.get(position));
                    animation = AnimationUtils.loadAnimation(mContext,
                            R.anim.fade_in);
                    imageView.startAnimation(animation);
                }

            } else {
                imageView.setImageBitmap(images.get(position));
            }

            alreadyLoadedIndexes[position] = true;

        }

        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
        return imageView;
    }

    class runnable implements Runnable {

        ImageView image;
        Bitmap bitmap;

        public runnable(ImageView img, Bitmap bitmap) {
            this.image = img;
            this.bitmap = bitmap;
        }

        @Override
        public void run() {
            Log.e("", "setting image.");
            image.setImageBitmap(bitmap);
        }

    }

}
4

5 回答 5

1

尝试 GridView 的布局动画控制器,它将根据持续时间逐项为视图设置动画。检查这个链接

于 2013-12-22T15:06:05.113 回答
0

你有一些选择。

Animation in your adapter首先,如果您不想更改代码,可以使用class。为此检查这个

在您的适配器类中,getView您必须像这样调用动画,

 Animation animation = null;
 animation = AnimationUtils.loadAnimation(context, R.anim.push_left_in);
 animation.setDuration(500);
 convertView.startAnimation(animation);
 return convertView;

其次,您应该使用GridLayoutAnimationController,其中一个布局动画控制器用于为网格布局的子项设置动画。

于 2013-12-27T12:16:33.540 回答
0

只是一个猜测。我不确定它是否会有所帮助,也不确定我是否正确阅读了您的代码。我想这个问题比我想象的要难。但是,您为每个项目使用相同的动画对象。也许您应该为每个项目创建一个新动画。这可能是您的动画在启动新动画时停止的原因,因为新调用只是重用并重新启动它。

祝你好运。

于 2013-12-28T09:10:45.733 回答
0

您是否尝试过在适配器 getView 方法之外应用动画,例如:

mGridView.getChildAt(childIndexNeededToAnimate).startAnimation(animation);

这些子视图是独立的,因为它们已经被绘制,所以不再被回收。

于 2013-12-24T13:23:32.753 回答
-1

你的问题是notifyDataSetChanged();它中断了动画。尝试在动画完成时调用它。

于 2013-12-22T13:25:16.470 回答