recyclerview AnimationDrawable 无法停止

本文探讨了在使用RecyclerView结合AnimationDrawable时遇到的动画控制问题,特别是在界面刷新时动画不停止的现象。通过深入分析和实验,提供了一种解决方案,即在绑定数据时将之前的AnimationDrawable置空并重新设置,确保动画正确停止。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发现一个问题,AnimationDrawable 配合recyclerview 使用时,在界面全部刷新的时候,调用stop方法,并不会使动画停止。但是手动调用 stop 方法,则可以进行停止,不知道是什么原因。

先附上最后的解决方案,就是在bind 数据的时候,将之前的AnimationDrawable置空,然后重新设置动画。

代码如下

 AnimationDrawable ad = (AnimationDrawable) ivVoice.getBackground();
            if (voiceClass.isPlayAudio()) {
                if (!ad.isRunning()) {
                    ad.start();
                }
            } else {
                if (ad.isRunning()) {
                    ad.stop();
                    ad.selectDrawable(0);
                }
                ivVoice.setBackground(null);
                ivVoice.setBackgroundResource( R.drawable.r_chat_voice_play);
            }

这两句是我额外加上的。

   ivVoice.setBackground(null);
                ivVoice.setBackgroundResource( R.drawable.r_chat_voice_play);

我在fragement里面如此触发单条刷新 是可以停止的。

 mVoiceAdapter.notifyItemChanged(index,VoiceAdapter.FLAG_UPDATE_PROGRESS);

@Override
        public void onBindViewHolder(@NonNull VoiceVH holder, int position, @NonNull List<Object> payloads) {
            if(payloads==null||payloads.size()==0)
                onBindViewHolder(holder,position);
            else
            {
                String flag=payloads.get(0).toString();
                switch (flag)
                {
                    case VoiceAdapter.FLAG_UPDATE_PROGRESS:
                        holder.updateVoiceStatus();
                        break;
                }
            }
        }

  public void updateVoiceStatus( ){
            //显示播放 的动画
            AnimationDrawable ad = (AnimationDrawable) ivVoice.getBackground();


            if (mVoiceClass.isPlayAudio()) {
                if (!ad.isRunning()) {
                    ad.start();
                }
            } else {
                if (ad.isRunning()) {
                    ad.stop();
                    ad.selectDrawable(0);

                }

感觉是跟viewholder复用有关但是,我重写onViewRecycled 还是无法停止。实在是找不出原因了。复用的ad.hashcode 也是相同的,但是调用的位置不同,stop()方法就是停止不了动画。。。。。

  @Override
        public void onViewRecycled(VoiceVH holder) {
            super.onViewRecycled(holder);
         //   holder.StopVoice();
         holder.updateVoiceStatus(false);
        }

完整的代码(加载30项,然后播放前几项和最后几项(前几项和后几项是不在一页的),然后刷新,发现屏幕外的帧动画并未停止)

 

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.speech.tts.Voice;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class VoiceFragment extends Fragment implements InputActionListener {

    RecyclerView mRecyclerView;
    VoiceAdapter mVoiceAdapter;
    List<VoiceClass> mVoiceClasses;
    Button mButton;
    Button mButtonRefresh;
    Button mButtonOne;
    Button mButtonExit;
    DrawerLayout mDrawerLayout;
     public static Fragment newInstance()
    {
        return new VoiceFragment();
    }


    @Override
    public void onCreate(  Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(  LayoutInflater inflater,   ViewGroup container,   Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.voicefragement,container,false);
        mRecyclerView=view.findViewById(R.id.voice_recyclerview);
        mVoiceClasses=new ArrayList<>();
        mButton=view.findViewById(R.id.voice_button);
        mButtonOne=view.findViewById(R.id.voice_add_one);
        mButtonExit=view.findViewById(R.id.btnExit);
        mButtonRefresh=view.findViewById(R.id.voice_refresh);
        mDrawerLayout=view.findViewById(R.id.id_drawerlayout);


        //增加一项
        mButtonOne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                VoiceClass voiceClass=new VoiceClass(mVoiceClasses.size());
                mVoiceClasses.add(voiceClass);
                mVoiceAdapter.notifyItemInserted(mVoiceClasses.size()-1);
            }
        });
        //全部停止
        mButtonRefresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for(VoiceClass voiceClass:mVoiceClasses){
                    voiceClass.setPlayAudio(false);
                }
                mVoiceAdapter.notifyDataSetChanged();
            }
        });
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int count=mVoiceClasses.size();
                mVoiceClasses.clear();
                for(int i=0;i<30 ;i++)
                {
                    VoiceClass voiceClass=new VoiceClass(i);
                    mVoiceClasses.add(voiceClass);
                }
                mVoiceAdapter.SetList(mVoiceClasses);
                mVoiceAdapter.notifyDataSetChanged();
                mVoiceAdapter.notifyItemChanged(0,VoiceAdapter.FLAG_UPDATE_PROGRESS);
            }
        });
        for(int i=0;i<1;i++)
        {
            VoiceClass voiceClass=new VoiceClass(i);
            mVoiceClasses.add(voiceClass);
        }
        mVoiceAdapter=new VoiceAdapter(mVoiceClasses);

        mVoiceAdapter.setHasStableIds(true);
        mVoiceAdapter.SetListener(this);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerView.setAdapter(mVoiceAdapter);
        mRecyclerView.addItemDecoration(new GridItemDecoration(getActivity(),GridItemDecoration.VERTICAL));
        return view;
    }

    @Override
    public void onInputListener(InputAction action, Object... args) {
        switch (action) {
            case ACTION_1:// 播放语音
                VoiceClass item = (VoiceClass) args[0];
                int pos = 0;

                playVoice(item, pos);
                break;
        }
    }

    private void playVoice(VoiceClass item, int pos) {
        int index = mVoiceClasses.indexOf(item);
        if (!item.isPlayAudio()) {
            item.setPlayAudio(true);


            mVoiceClasses.get(index).setPlayAudio(true);
        } else {
            item.setPlayAudio(false);

            mVoiceClasses.get(index).setPlayAudio(false);
        }
        mVoiceAdapter.notifyItemChanged(index,VoiceAdapter.FLAG_UPDATE_PROGRESS);
    }

    public class VoiceVH extends RecyclerView.ViewHolder{
        private ImageView ivVoice;
        List<VoiceClass> mVoiceClassList;
        public VoiceClass mVoiceClass;
        TextView mTextView;
        InputActionListener mInputActionListener;
        public void StopVoice()
        {
            mInputActionListener.onInputListener(InputAction.ACTION_1,mVoiceClass);
        }
        public VoiceVH(LayoutInflater inflater,ViewGroup viewGroup,List<VoiceClass> voiceClasses ,InputActionListener inputActionListener) {
            super(inflater.inflate(R.layout.voicelayout,viewGroup,false));
            ivVoice = itemView.findViewById(R.id.item_chat_voice_icon);
            mTextView=itemView.findViewById(R.id.item_voice_id);
            mInputActionListener=inputActionListener;
            mVoiceClassList=voiceClasses;
        }

        public void bind(final VoiceClass voiceClass) {
            mVoiceClass=voiceClass;
            mTextView.setText(voiceClass.getId()+"v");
            AnimationDrawable ad1 =(AnimationDrawable) itemView.getTag();
            if(ad1!=null){
                if (ad1.isRunning()) {
                    ad1.stop();
                    ad1.selectDrawable(0);
                }
            }
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   int position=getAdapterPosition();
                    mInputActionListener.onInputListener(InputAction.ACTION_1,voiceClass );
                }
            });

            AnimationDrawable ad = (AnimationDrawable) ivVoice.getBackground();
            itemView.setTag(ad);
            if (voiceClass.isPlayAudio()) {
                if (!ad.isRunning()) {
                    ad.start();
                }
            } else {
                if (ad.isRunning()) {
                    ad.stop();
                    ad.selectDrawable(0);
                }
//                ivVoice.setBackground(null);
//                ivVoice.setBackgroundResource( R.drawable.r_chat_voice_play);
            }
        }


        public void updateVoiceStatus( ){
            //显示播放语音的动画
            AnimationDrawable ad = (AnimationDrawable) ivVoice.getBackground();


            if (mVoiceClass.isPlayAudio()) {
                if (!ad.isRunning()) {
                    ad.start();
                }
            } else {
                if (ad.isRunning()) {
                    ad.stop();
                    ad.selectDrawable(0);
                    ad.unscheduleSelf(ad);

                }
            }
        }
    }


    public class  VoiceAdapter extends RecyclerView.Adapter<VoiceVH>{
        public static final String FLAG_UPDATE_PROGRESS = "progress";
        List<VoiceClass> mVoiceClassList;
        InputActionListener mInputActionListener;
        public VoiceAdapter(List<VoiceClass> voice)
        {
            mVoiceClassList=voice;
        }
        public void SetListener(InputActionListener inputActionListener)
        {
            mInputActionListener=inputActionListener;
        }
        public void SetList(List<VoiceClass> voiceClasses)
        {
            mVoiceClassList=voiceClasses;
        }
        @NonNull
        @Override
        public VoiceVH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
            VoiceVH voiceVH=new VoiceVH(layoutInflater,viewGroup,mVoiceClassList,mInputActionListener);
            return voiceVH;
        }

        @Override
        public long getItemId(int position) {
            return mVoiceClassList.get(position).getId();
        }

        @Override
        public void onBindViewHolder(@NonNull VoiceVH voiceVH, int i) {
            final VoiceClass voiceClass=mVoiceClassList.get(i);
            voiceVH.bind(voiceClass);
        }


        @Override
        public void onViewRecycled(VoiceVH holder) {
            super.onViewRecycled(holder);
         //   holder.StopVoice();
      //   holder.updateVoiceStatus( );
        }
        @Override
        public void onBindViewHolder(@NonNull VoiceVH holder, int position, @NonNull List<Object> payloads) {
            if(payloads==null||payloads.size()==0)
                onBindViewHolder(holder,position);
            else
            {
                String flag=payloads.get(0).toString();
                switch (flag)
                {
                    case VoiceAdapter.FLAG_UPDATE_PROGRESS:
                        holder.updateVoiceStatus();
                        break;
                }
            }
        }

        @Override
        public int getItemCount() {
            return mVoiceClassList.size();
        }
    }

    public class VoiceClass{
         public VoiceClass(int i)
         {
             id=i;
         }
         private  int id;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        private boolean isPlayAudio ;

        public boolean isPlayAudio() {
            return isPlayAudio;
        }

        public void setPlayAudio(boolean isPlayAudio) {
            this.isPlayAudio = isPlayAudio;
        }
    }


}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值