发现一个问题,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;
}
}
}