Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在带有ViewHolder图案的适配器中使用动画_Android - Fatal编程技术网

Android 在带有ViewHolder图案的适配器中使用动画

Android 在带有ViewHolder图案的适配器中使用动画,android,Android,在适配器中使用动画时出现问题 @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(re

在适配器中使用动画时出现问题

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            convertView = inflater.inflate(resource, parent, false);
            holder = new ViewHolder();

            holder.newRoomView = (TextView) convertView.findViewById(R.id.newRoom);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Room item = items.get(position);

        // animate new rooms
        if (item.isNewRoom()) {
            AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
            alphaAnim.setDuration(1500);
            alphaAnim.setAnimationListener(new AnimationListener() {
                public void onAnimationEnd(Animation animation) {
                    holder.newRoomView.setVisibility(View.INVISIBLE);
                }

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}
            });
            holder.newRoomView.startAnimation(alphaAnim);
        }

        // ...

        return convertView;
    }
在适配器外部添加新房间并调用
notifyDataSetChanged
时,新房间将正确设置动画,但调用
onAnimationEnd
时,另一个房间(不是新房间)将隐藏


有没有办法隐藏正确的文件室?

这可能是由于ListView的循环机制。尝试标记动画视图,并使用
findViewByTag
在动画端检索它。例如

public View getView(final int position, final View convertView, ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(resource, parent, false);
        holder = new ViewHolder();

        holder.newRoomView = (TextView) convertView.findViewById(R.id.newRoom);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Room item = items.get(position);

    // animate new rooms
    if (item.isNewRoom()) {
        AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
        alphaAnim.setDuration(1500);
        alphaAnim.setAnimationListener(new AnimationListener() {
            public void onAnimationEnd(Animation animation) {
                View view = convertView.findViewWithTag(position);
                if (view != null) {
                     view.setVisibility(View.INVISIBLE);
                } 

            }

            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationRepeat(Animation animation) {}
        });
        holder.newRoomView.startAnimation(alphaAnim);
        holder.newRoomView.setTag(position);
    }

    // ...

    return convertView;
}

如果您愿意迁移到新的,您将能够使用这个伟大的动画库,请查看它:

由于您没有在
getView()
方法中声明
holder
变量,我只能假设您已经在类中将其声明为实例变量。这是你的问题。当动画完成时,变量
holder
正在保存对完全不同项目的引用

您需要在
getView()
方法中使用声明为
final
的局部变量。我不知道您是否需要
getView()
方法之外的
holder
变量,但如果需要,您可以这样做:

    // animate new rooms
    if (item.isNewRoom()) {
        final ViewHolder holderCopy = holder; // make a copy
        AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
        alphaAnim.setDuration(1500);
        alphaAnim.setAnimationListener(new AnimationListener() {
            public void onAnimationEnd(Animation animation) {
                holderCopy.newRoomView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationRepeat(Animation animation) {}
        });
        holder.newRoomView.startAnimation(alphaAnim);
    }

当然,如果动画花费的时间太长,以致于在此期间视图已被循环使用,则此操作将不起作用。

请记住,对于此类内容,您需要始终使用else语句。 否则,使用同一视图保持架的任何其他内容也将不可见

if (item.isNewRoom()) {
        AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f);
        alphaAnim.setDuration(1500);
        alphaAnim.setAnimationListener(new AnimationListener() {
            public void onAnimationEnd(Animation animation) {
                holder.newRoomView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationRepeat(Animation animation) {}
        });
        holder.newRoomView.startAnimation(alphaAnim);
    }else{
        holder.newRoomView.setVisibility(View.VISIBLE);
    }

嗯。我以前遇到过这个问题,这可能是Android的一个bug:

您正在使用内部对象设置动画侦听器:

 alphaAnim.setAnimationListener(new AnimationListener(){/*bla bla bla*/});
将上述代码更改为类似以下内容:

AnimationListener myListener = new AnimationListener(){/*bla bla bla*/};
alphaAnim.setAnimationListener(myListener);

我知道这是一个非常疯狂的解决方案,但它在几次类似的情况下救了我的命。

为什么不使用
RecyclerView
?发布你的物品布局,请注意这个答案没有用。您建议的代码与要替换的代码完全相同。您仍在创建一个匿名类,与以前一样。编译器将把两个代码段编译成完全相同的东西。@David Wasser:这在过去对我很有效。你100%确定Android上的代码完全相同吗?是的。完全一样。我不敢相信这解决了你过去可能遇到的任何问题。我的问题与OP完全相同。但由于你是一个经验丰富得多的程序员,我一到我的电脑就会删除我的答案。
AnimationListener myListener = new AnimationListener(){/*bla bla bla*/};
alphaAnim.setAnimationListener(myListener);